v0.2.9-pre.002
This commit is contained in:
40
crates/ksp-onchain-transport-lib/unit_tests/grpc_channel.rs
Normal file
40
crates/ksp-onchain-transport-lib/unit_tests/grpc_channel.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/grpc_channel.rs
|
||||
// version: 1
|
||||
|
||||
fn endpoint(enabled: bool, value: &str) -> crate::YellowstoneGrpcEndpointSettings {
|
||||
let parsed = crate::YellowstoneGrpcEndpointUrl::parse(value).expect("fixture Yellowstone gRPC URL must parse");
|
||||
return crate::YellowstoneGrpcEndpointSettings::new(
|
||||
"fixture",
|
||||
enabled,
|
||||
crate::YellowstoneGrpcProviderName::new("fixture-provider"),
|
||||
crate::YellowstoneGrpcClusterName::new("devnet"),
|
||||
parsed,
|
||||
crate::YellowstoneGrpcSessionSettings::default(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_channel_prepare_is_lazy_safe_and_keeps_tonic_private() {
|
||||
let endpoint = endpoint(true, "http://127.0.0.1:10000/GRPC-SECRET-CANARY");
|
||||
let channel = crate::YellowstoneGrpcChannel::prepare(&endpoint);
|
||||
assert!(channel.is_ok());
|
||||
let channel = match channel {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
assert_eq!(channel.endpoint_name(), "fixture");
|
||||
assert_eq!(channel.provider().as_str(), "fixture-provider");
|
||||
assert_eq!(channel.cluster().as_str(), "devnet");
|
||||
let rendered = format!("{channel:?}");
|
||||
assert!(!rendered.contains("GRPC-SECRET-CANARY"));
|
||||
assert!(!rendered.contains("127.0.0.1"));
|
||||
let _channel_type = std::any::type_name_of_val(&channel.channel);
|
||||
let _wire_type = std::any::type_name::<yellowstone_grpc_proto::geyser::SubscribeRequest>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_channel_prepare_rejects_disabled_endpoint_before_network_io() {
|
||||
let endpoint = endpoint(false, "http://127.0.0.1:10000");
|
||||
let result = crate::YellowstoneGrpcChannel::prepare(&endpoint);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
151
crates/ksp-onchain-transport-lib/unit_tests/grpc_settings.rs
Normal file
151
crates/ksp-onchain-transport-lib/unit_tests/grpc_settings.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/grpc_settings.rs
|
||||
// version: 1
|
||||
|
||||
fn endpoint(name: &str, enabled: bool, url: &str, session: crate::YellowstoneGrpcSessionSettings) -> crate::YellowstoneGrpcEndpointSettings {
|
||||
let parsed = crate::YellowstoneGrpcEndpointUrl::parse(url).expect("fixture Yellowstone gRPC URL must parse");
|
||||
return crate::YellowstoneGrpcEndpointSettings::new(
|
||||
name,
|
||||
enabled,
|
||||
crate::YellowstoneGrpcProviderName::new("fixture"),
|
||||
crate::YellowstoneGrpcClusterName::new("devnet"),
|
||||
parsed,
|
||||
session,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_endpoint_url_accepts_http_and_https_and_redacts_debug() {
|
||||
for value in ["http://127.0.0.1:10000", "https://yellowstone.example.invalid:443/path?token=GRPC-SECRET-CANARY"] {
|
||||
let parsed = crate::YellowstoneGrpcEndpointUrl::parse(value);
|
||||
assert!(parsed.is_ok());
|
||||
let parsed = match parsed {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => continue,
|
||||
};
|
||||
assert_eq!(parsed.as_str(), value);
|
||||
let rendered = format!("{parsed:?}");
|
||||
assert_eq!(rendered, "YellowstoneGrpcEndpointUrl(<redacted>)");
|
||||
assert!(!rendered.contains("GRPC-SECRET-CANARY"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_endpoint_url_rejects_non_http_schemes_without_echoing_secret() {
|
||||
let result = crate::YellowstoneGrpcEndpointUrl::parse("wss://GRPC-SECRET-CANARY@example.invalid/socket");
|
||||
assert!(result.is_err());
|
||||
let error = match result {
|
||||
std::result::Result::Ok(_) => return,
|
||||
std::result::Result::Err(error) => error,
|
||||
};
|
||||
let rendered = error.to_string();
|
||||
assert!(!rendered.contains("GRPC-SECRET-CANARY"));
|
||||
assert!(!format!("{error:?}").contains("GRPC-SECRET-CANARY"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_endpoint_url_rejects_excessive_length_without_echoing_payload() {
|
||||
let value = format!("https://example.invalid/{}", "S".repeat(super::MAX_GRPC_ENDPOINT_URL_LENGTH_BYTES + 1));
|
||||
let result = crate::YellowstoneGrpcEndpointUrl::parse(value);
|
||||
assert!(result.is_err());
|
||||
let error = match result {
|
||||
std::result::Result::Ok(_) => return,
|
||||
std::result::Result::Err(error) => error,
|
||||
};
|
||||
assert!(!format!("{error:?}").contains(&"S".repeat(64)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_session_defaults_are_bounded_and_validate() {
|
||||
let settings = crate::YellowstoneGrpcSessionSettings::default();
|
||||
assert!(settings.validate().is_ok());
|
||||
assert!(!settings.connect_timeout().is_zero());
|
||||
assert!(!settings.unary_timeout().is_zero());
|
||||
assert!(!settings.close_timeout().is_zero());
|
||||
assert!(settings.request_channel_capacity() > 0);
|
||||
assert!(settings.update_channel_capacity() > 0);
|
||||
assert!(settings.max_inbound_message_size_bytes() > 0);
|
||||
assert!(settings.max_outbound_message_size_bytes() > 0);
|
||||
assert!(settings.reconnect().max_retries() <= super::MAX_GRPC_RECONNECT_RETRIES);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_session_rejects_zero_excessive_and_reversed_runtime_bounds() {
|
||||
let zero = crate::YellowstoneGrpcSessionSettings::new(
|
||||
std::time::Duration::ZERO,
|
||||
std::time::Duration::from_secs(1),
|
||||
std::time::Duration::from_secs(1),
|
||||
crate::YellowstoneGrpcReconnectSettings::default(),
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
assert!(zero.validate().is_err());
|
||||
let excessive = crate::YellowstoneGrpcSessionSettings::new(
|
||||
super::MAX_GRPC_RUNTIME_DURATION + std::time::Duration::from_secs(1),
|
||||
std::time::Duration::from_secs(1),
|
||||
std::time::Duration::from_secs(1),
|
||||
crate::YellowstoneGrpcReconnectSettings::new(
|
||||
super::MAX_GRPC_RECONNECT_RETRIES + 1,
|
||||
std::time::Duration::from_millis(1),
|
||||
std::time::Duration::from_millis(2),
|
||||
),
|
||||
super::MAX_GRPC_CHANNEL_CAPACITY + 1,
|
||||
1,
|
||||
super::MAX_GRPC_MESSAGE_SIZE_BYTES + 1,
|
||||
1,
|
||||
);
|
||||
assert!(excessive.validate().is_err());
|
||||
let reversed = crate::YellowstoneGrpcSessionSettings::new(
|
||||
std::time::Duration::from_secs(1),
|
||||
std::time::Duration::from_secs(1),
|
||||
std::time::Duration::from_secs(1),
|
||||
crate::YellowstoneGrpcReconnectSettings::new(5, std::time::Duration::from_secs(2), std::time::Duration::from_secs(1)),
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
);
|
||||
assert!(reversed.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_transport_settings_validate_unique_enabled_endpoints_and_redact_urls() {
|
||||
let first = endpoint("first", true, "https://GRPC-SECRET-CANARY@example.invalid:443", crate::YellowstoneGrpcSessionSettings::default());
|
||||
let second = endpoint("second", false, "http://127.0.0.1:10000", crate::YellowstoneGrpcSessionSettings::default());
|
||||
let settings = crate::YellowstoneGrpcTransportSettings::new(std::vec![first.clone(), second]);
|
||||
assert!(settings.validate().is_ok());
|
||||
let rendered = format!("{settings:?}");
|
||||
assert!(!rendered.contains("GRPC-SECRET-CANARY"));
|
||||
assert!(!rendered.contains("example.invalid"));
|
||||
let duplicate = crate::YellowstoneGrpcTransportSettings::new(std::vec![first.clone(), first]);
|
||||
assert!(duplicate.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_transport_settings_reject_excessive_descriptor_and_endpoint_count() {
|
||||
let oversized_name = "n".repeat(super::MAX_GRPC_DESCRIPTOR_LENGTH_BYTES + 1);
|
||||
let oversized = endpoint(oversized_name.as_str(), true, "http://127.0.0.1:10000", crate::YellowstoneGrpcSessionSettings::default());
|
||||
assert!(crate::YellowstoneGrpcTransportSettings::new(std::vec![oversized]).validate().is_err());
|
||||
let parsed = crate::YellowstoneGrpcEndpointUrl::parse("http://127.0.0.1:10000").expect("fixture Yellowstone gRPC URL must parse");
|
||||
let endpoints = (0..=super::MAX_GRPC_ENDPOINT_COUNT)
|
||||
.map(|index| {
|
||||
crate::YellowstoneGrpcEndpointSettings::new(
|
||||
format!("endpoint-{index}"),
|
||||
true,
|
||||
crate::YellowstoneGrpcProviderName::new("fixture"),
|
||||
crate::YellowstoneGrpcClusterName::new("devnet"),
|
||||
parsed.clone(),
|
||||
crate::YellowstoneGrpcSessionSettings::default(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
assert!(crate::YellowstoneGrpcTransportSettings::new(endpoints).validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grpc_transport_settings_require_one_enabled_endpoint() {
|
||||
let disabled = endpoint("disabled", false, "http://127.0.0.1:10000", crate::YellowstoneGrpcSessionSettings::default());
|
||||
assert!(crate::YellowstoneGrpcTransportSettings::new(std::vec![disabled]).validate().is_err());
|
||||
assert!(crate::YellowstoneGrpcTransportSettings::new(std::vec![]).validate().is_err());
|
||||
}
|
||||
Reference in New Issue
Block a user