v0.2.7-pre.002
This commit is contained in:
70
crates/ksp-onchain-transport-lib/unit_tests/ws_lifecycle.rs
Normal file
70
crates/ksp-onchain-transport-lib/unit_tests/ws_lifecycle.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_lifecycle.rs
|
||||
// version: 1
|
||||
|
||||
fn non_zero(value: u64) -> std::num::NonZeroU64 {
|
||||
return std::num::NonZeroU64::new(value).expect("test ID must be non-zero");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn websocket_local_ids_preserve_ordering_and_numeric_identity() {
|
||||
let first_session = crate::WsSessionId::new(non_zero(1));
|
||||
let second_session = crate::WsSessionId::new(non_zero(2));
|
||||
let subscription = crate::WsSubscriptionId::new(non_zero(7));
|
||||
assert!(first_session < second_session);
|
||||
assert_eq!(subscription.get(), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn websocket_state_models_expose_concurrent_lifecycle_states() {
|
||||
assert_eq!(crate::WsSessionState::Reconnecting { attempt: 3 }, crate::WsSessionState::Reconnecting { attempt: 3 });
|
||||
assert_eq!(crate::WsSubscriptionState::Resubscribing, crate::WsSubscriptionState::Resubscribing);
|
||||
assert_ne!(crate::WsSubscriptionState::Cancelling, crate::WsSubscriptionState::Closed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn websocket_subscription_kinds_cover_all_nine_standard_families() {
|
||||
let kinds = [
|
||||
crate::WsSubscriptionKind::Account,
|
||||
crate::WsSubscriptionKind::Block,
|
||||
crate::WsSubscriptionKind::Logs,
|
||||
crate::WsSubscriptionKind::Program,
|
||||
crate::WsSubscriptionKind::Root,
|
||||
crate::WsSubscriptionKind::Signature,
|
||||
crate::WsSubscriptionKind::Slot,
|
||||
crate::WsSubscriptionKind::SlotsUpdates,
|
||||
crate::WsSubscriptionKind::Vote,
|
||||
];
|
||||
assert_eq!(kinds.len(), 9);
|
||||
assert_eq!(kinds[7].as_str(), "slots_updates");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn websocket_snapshots_expose_safe_metadata_without_remote_ids_or_urls() {
|
||||
let subscription = crate::WsSubscriptionSnapshot::new(
|
||||
crate::WsSubscriptionId::new(non_zero(9)),
|
||||
crate::WsSubscriptionKind::Slot,
|
||||
crate::WsSubscriptionState::Active,
|
||||
true,
|
||||
);
|
||||
let snapshot = crate::WsSessionSnapshot::new(
|
||||
crate::WsSessionId::new(non_zero(3)),
|
||||
"devnet_public",
|
||||
crate::WsProviderName::new("solana-public"),
|
||||
crate::WsClusterName::new("devnet"),
|
||||
crate::WsProtocolKind::SolanaStandard,
|
||||
crate::WsSessionState::Active,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
std::vec![subscription],
|
||||
);
|
||||
assert_eq!(snapshot.id().get(), 3);
|
||||
assert_eq!(snapshot.endpoint_name(), "devnet_public");
|
||||
assert_eq!(snapshot.pending_request_count(), 2);
|
||||
assert_eq!(snapshot.continuity_gap_count(), 1);
|
||||
assert_eq!(snapshot.subscription_count(), 1);
|
||||
assert!(snapshot.subscriptions()[0].remote_bound());
|
||||
let rendered = format!("{snapshot:?}");
|
||||
assert!(!rendered.contains("wss://"));
|
||||
assert!(!rendered.contains("remote_subscription_id"));
|
||||
}
|
||||
148
crates/ksp-onchain-transport-lib/unit_tests/ws_settings.rs
Normal file
148
crates/ksp-onchain-transport-lib/unit_tests/ws_settings.rs
Normal file
@@ -0,0 +1,148 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_settings.rs
|
||||
// version: 1
|
||||
|
||||
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_is_extensible_but_only_standard_is_available_now() {
|
||||
assert_eq!(crate::WsProtocolKind::SolanaStandard.as_str(), "solana_standard");
|
||||
}
|
||||
|
||||
#[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"));
|
||||
}
|
||||
Reference in New Issue
Block a user