228 lines
11 KiB
Rust
228 lines
11 KiB
Rust
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_settings.rs
|
|
// version: 3
|
|
|
|
fn valid_endpoint(name: &str, url_text: &str) -> crate::WsEndpointSettings {
|
|
return crate::WsEndpointSettings::new(
|
|
name,
|
|
true,
|
|
crate::WsProviderName::new("solana-public"),
|
|
crate::WsClusterName::new("devnet"),
|
|
crate::WsProtocolKind::SolanaStandard,
|
|
crate::WsEndpointUrl::parse(url_text).expect("test WebSocket URL must parse"),
|
|
crate::WsSessionSettings::default(),
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_endpoint_url_accepts_ws_and_wss() {
|
|
assert!(crate::WsEndpointUrl::parse("wss://api.devnet.solana.com").is_ok());
|
|
assert!(crate::WsEndpointUrl::parse("ws://127.0.0.1:8900").is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_endpoint_url_rejects_http_schemes() {
|
|
let result = crate::WsEndpointUrl::parse("https://api.devnet.solana.com");
|
|
let error = result.expect_err("HTTP URL must not be accepted by WebSocket settings");
|
|
assert_eq!(error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_endpoint_url_debug_redacts_secret_material() {
|
|
let url = crate::WsEndpointUrl::parse("wss://user:password@provider.invalid/path?api-key=SECRET-CANARY").expect("test URL must parse");
|
|
let rendered = format!("{url:?}");
|
|
assert_eq!(rendered, "WsEndpointUrl(<redacted>)");
|
|
assert!(!rendered.contains("SECRET-CANARY"));
|
|
assert!(!rendered.contains("provider.invalid"));
|
|
assert!(!rendered.contains("password"));
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_endpoint_url_errors_do_not_echo_sensitive_url() {
|
|
let result = crate::WsEndpointUrl::parse("http://user:password@provider.invalid/path?api-key=SECRET-CANARY");
|
|
let error = result.expect_err("unsupported scheme must fail");
|
|
let rendered = format!("{error:?}");
|
|
assert!(!rendered.contains("SECRET-CANARY"));
|
|
assert!(!rendered.contains("provider.invalid"));
|
|
assert!(!rendered.contains("password"));
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_protocol_kind_distinguishes_standard_and_helius_laserstream_websocket() {
|
|
assert_eq!(crate::WsProtocolKind::SolanaStandard.as_str(), "solana_standard");
|
|
assert_eq!(crate::WsProtocolKind::HeliusLaserStream.as_str(), "helius_laserstream");
|
|
assert_ne!(crate::WsProtocolKind::SolanaStandard, crate::WsProtocolKind::HeliusLaserStream);
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_session_defaults_are_bounded_and_validate() {
|
|
let settings = crate::WsSessionSettings::default();
|
|
assert!(settings.validate().is_ok());
|
|
assert!(settings.command_queue_capacity() > 0);
|
|
assert!(settings.notification_queue_capacity() > 0);
|
|
assert!(settings.max_active_subscriptions() > 0);
|
|
assert!(settings.max_pending_requests() > 0);
|
|
assert!(settings.max_message_size_bytes() > 0);
|
|
assert!(settings.max_frame_size_bytes() > 0);
|
|
assert!(settings.max_write_buffer_size_bytes() > 0);
|
|
assert_eq!(settings.resubscribe(), crate::WsResubscribePolicy::ActiveSubscriptions);
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_session_settings_reject_zero_runtime_bounds() {
|
|
let defaults = crate::WsSessionSettings::default();
|
|
let settings = crate::WsSessionSettings::new(
|
|
defaults.command_timeout(),
|
|
defaults.close_timeout(),
|
|
defaults.reconnect().clone(),
|
|
defaults.resubscribe(),
|
|
0,
|
|
defaults.notification_queue_capacity(),
|
|
defaults.max_active_subscriptions(),
|
|
defaults.max_pending_requests(),
|
|
defaults.max_message_size_bytes(),
|
|
defaults.max_frame_size_bytes(),
|
|
defaults.max_write_buffer_size_bytes(),
|
|
);
|
|
let error = settings.validate().expect_err("zero command queue capacity must fail");
|
|
assert_eq!(error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_session_settings_reject_reversed_reconnect_backoff() {
|
|
let defaults = crate::WsSessionSettings::default();
|
|
let settings = crate::WsSessionSettings::new(
|
|
defaults.command_timeout(),
|
|
defaults.close_timeout(),
|
|
crate::WsReconnectSettings::new(2, std::time::Duration::from_secs(2), std::time::Duration::from_secs(1)),
|
|
defaults.resubscribe(),
|
|
defaults.command_queue_capacity(),
|
|
defaults.notification_queue_capacity(),
|
|
defaults.max_active_subscriptions(),
|
|
defaults.max_pending_requests(),
|
|
defaults.max_message_size_bytes(),
|
|
defaults.max_frame_size_bytes(),
|
|
defaults.max_write_buffer_size_bytes(),
|
|
);
|
|
assert!(settings.validate().is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_transport_settings_validate_unique_enabled_endpoints() {
|
|
let settings = crate::WsTransportSettings::new(std::vec![
|
|
valid_endpoint("devnet_primary", "wss://api.devnet.solana.com"),
|
|
valid_endpoint("devnet_secondary", "wss://example.invalid/ws"),
|
|
]);
|
|
assert!(settings.validate().is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_transport_settings_reject_duplicate_endpoint_names() {
|
|
let settings =
|
|
crate::WsTransportSettings::new(std::vec![valid_endpoint("duplicate", "wss://one.invalid/ws"), valid_endpoint("duplicate", "wss://two.invalid/ws"),]);
|
|
let error = settings.validate().expect_err("duplicate endpoint names must fail");
|
|
assert_eq!(error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_transport_settings_require_one_enabled_endpoint() {
|
|
let endpoint = crate::WsEndpointSettings::new(
|
|
"disabled",
|
|
false,
|
|
crate::WsProviderName::new("provider"),
|
|
crate::WsClusterName::new("devnet"),
|
|
crate::WsProtocolKind::SolanaStandard,
|
|
crate::WsEndpointUrl::parse("wss://provider.invalid/ws").expect("test URL must parse"),
|
|
crate::WsSessionSettings::default(),
|
|
);
|
|
let settings = crate::WsTransportSettings::new(std::vec![endpoint]);
|
|
assert!(settings.validate().is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn websocket_transport_settings_debug_never_exposes_endpoint_url() {
|
|
let settings =
|
|
crate::WsTransportSettings::new(std::vec![valid_endpoint("secret_endpoint", "wss://user:password@provider.invalid/path?api-key=SECRET-CANARY",)]);
|
|
let rendered = format!("{settings:?}");
|
|
assert!(rendered.contains("WsEndpointUrl(<redacted>)"));
|
|
assert!(!rendered.contains("SECRET-CANARY"));
|
|
assert!(!rendered.contains("provider.invalid"));
|
|
assert!(!rendered.contains("password"));
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_15_pre_002_undeclared_websocket_capabilities_fail_closed_without_breaking_legacy_settings() {
|
|
let endpoint = valid_endpoint("legacy", "wss://legacy.invalid/ws");
|
|
assert_eq!(endpoint.subscription_capabilities(), std::option::Option::None);
|
|
assert!(!endpoint.supports_subscription(crate::WsSubscriptionKind::Logs));
|
|
assert!(!endpoint.supports_subscription(crate::WsSubscriptionKind::Block));
|
|
let settings = crate::WsTransportSettings::new(std::vec![endpoint]);
|
|
assert!(settings.validate().is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_15_pre_002_standard_endpoint_declares_exact_typed_subscription_capabilities() {
|
|
let endpoint = valid_endpoint("typed", "wss://typed.invalid/ws")
|
|
.with_subscription_capabilities(std::vec![crate::WsSubscriptionKind::Logs, crate::WsSubscriptionKind::Block,]);
|
|
assert_eq!(
|
|
endpoint.subscription_capabilities(),
|
|
std::option::Option::Some([crate::WsSubscriptionKind::Logs, crate::WsSubscriptionKind::Block].as_slice())
|
|
);
|
|
assert!(endpoint.supports_subscription(crate::WsSubscriptionKind::Logs));
|
|
assert!(endpoint.supports_subscription(crate::WsSubscriptionKind::Block));
|
|
assert!(!endpoint.supports_subscription(crate::WsSubscriptionKind::Vote));
|
|
assert!(!endpoint.supports_subscription(crate::WsSubscriptionKind::HeliusTransaction));
|
|
let settings = crate::WsTransportSettings::new(std::vec![endpoint]);
|
|
assert!(settings.validate().is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_15_pre_002_explicit_capability_set_rejects_empty_and_duplicate_entries() {
|
|
let empty = valid_endpoint("empty", "wss://empty.invalid/ws").with_subscription_capabilities(std::vec![]);
|
|
let empty_error = crate::WsTransportSettings::new(std::vec![empty]).validate().expect_err("explicit empty capabilities must fail");
|
|
assert_eq!(empty_error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
let duplicate = valid_endpoint("duplicate_caps", "wss://duplicate.invalid/ws")
|
|
.with_subscription_capabilities(std::vec![crate::WsSubscriptionKind::Logs, crate::WsSubscriptionKind::Logs,]);
|
|
let duplicate_error = crate::WsTransportSettings::new(std::vec![duplicate]).validate().expect_err("duplicate capabilities must fail");
|
|
assert_eq!(duplicate_error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_15_pre_002_capabilities_must_belong_to_selected_protocol_surface() {
|
|
let standard =
|
|
valid_endpoint("standard_bad", "wss://standard.invalid/ws").with_subscription_capabilities(std::vec![crate::WsSubscriptionKind::HeliusTransaction]);
|
|
assert!(!standard.supports_subscription(crate::WsSubscriptionKind::HeliusTransaction));
|
|
let standard_error =
|
|
crate::WsTransportSettings::new(std::vec![standard]).validate().expect_err("standard protocol must reject Helius transaction capability");
|
|
assert_eq!(standard_error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
let helius_block = crate::WsEndpointSettings::new(
|
|
"helius_block",
|
|
true,
|
|
crate::WsProviderName::new("helius"),
|
|
crate::WsClusterName::new("mainnet"),
|
|
crate::WsProtocolKind::HeliusLaserStream,
|
|
crate::WsEndpointUrl::parse("wss://helius.invalid/ws").expect("test URL must parse"),
|
|
crate::WsSessionSettings::default(),
|
|
)
|
|
.with_subscription_capabilities(std::vec![crate::WsSubscriptionKind::Block]);
|
|
assert!(!helius_block.supports_subscription(crate::WsSubscriptionKind::Block));
|
|
let helius_block_error =
|
|
crate::WsTransportSettings::new(std::vec![helius_block]).validate().expect_err("Helius protocol must reject unsupported block capability");
|
|
assert_eq!(helius_block_error.code(), crate::ERROR_CODE_INVALID_SETTINGS);
|
|
let helius_supported = crate::WsEndpointSettings::new(
|
|
"helius_supported",
|
|
true,
|
|
crate::WsProviderName::new("helius"),
|
|
crate::WsClusterName::new("mainnet"),
|
|
crate::WsProtocolKind::HeliusLaserStream,
|
|
crate::WsEndpointUrl::parse("wss://helius-supported.invalid/ws").expect("test URL must parse"),
|
|
crate::WsSessionSettings::default(),
|
|
)
|
|
.with_subscription_capabilities(std::vec![crate::WsSubscriptionKind::Logs, crate::WsSubscriptionKind::HeliusTransaction]);
|
|
assert!(helius_supported.supports_subscription(crate::WsSubscriptionKind::Logs));
|
|
assert!(helius_supported.supports_subscription(crate::WsSubscriptionKind::HeliusTransaction));
|
|
assert!(!helius_supported.supports_subscription(crate::WsSubscriptionKind::Block));
|
|
assert!(!helius_supported.supports_subscription(crate::WsSubscriptionKind::Vote));
|
|
let helius_settings = crate::WsTransportSettings::new(std::vec![helius_supported]);
|
|
assert!(helius_settings.validate().is_ok());
|
|
}
|