// file: crates/ksp-onchain-transport-lib/tests/websocket_devnet_smoke.rs // version: 1 //! Opt-in live Devnet smoke for one stable standard Solana WebSocket subscription. fn devnet_websocket_endpoint() -> ksp_core_lib::Result { let url_result = ksp_onchain_transport_lib::WsEndpointUrl::parse("wss://api.devnet.solana.com"); let url = match url_result { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let session = ksp_onchain_transport_lib::WsSessionSettings::new( std::time::Duration::from_secs(10), std::time::Duration::from_secs(5), ksp_onchain_transport_lib::WsReconnectSettings::new(0, std::time::Duration::from_millis(250), std::time::Duration::from_secs(2)), ksp_onchain_transport_lib::WsResubscribePolicy::ActiveSubscriptions, 16, 16, 8, 8, 4 * 1024 * 1024, 4 * 1024 * 1024, 256 * 1024, ); return std::result::Result::Ok(ksp_onchain_transport_lib::WsEndpointSettings::new( "solana_devnet_public_ws", true, ksp_onchain_transport_lib::WsProviderName::new("solana-public"), ksp_onchain_transport_lib::WsClusterName::new("devnet"), ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard, url, session, )); } #[tokio::test(flavor = "current_thread")] #[ignore = "opt-in live Solana Devnet WebSocket smoke; performs an external network connection"] async fn programmatic_devnet_websocket_reaches_slot_notification_then_unsubscribes_and_closes() { let endpoint = devnet_websocket_endpoint().expect("programmatic Devnet WebSocket settings must construct an endpoint"); let session = ksp_onchain_transport_lib::WsSession::connect(endpoint).await.expect("Devnet WebSocket handshake must succeed"); assert_eq!(session.snapshot().state(), ksp_onchain_transport_lib::WsSessionState::Active); let mut subscription = session.slot_subscribe().await.expect("Devnet slotSubscribe must succeed"); assert_eq!(subscription.kind(), ksp_onchain_transport_lib::WsSubscriptionKind::Slot); assert_eq!(subscription.state(), ksp_onchain_transport_lib::WsSubscriptionState::Active); let notification_wait = tokio::time::timeout(std::time::Duration::from_secs(20), subscription.recv()).await; let notification = match notification_wait { std::result::Result::Ok(std::option::Option::Some(std::result::Result::Ok(value))) => value, std::result::Result::Ok(std::option::Option::Some(std::result::Result::Err(error))) => panic!("Devnet slot notification decoding failed: {error}"), std::result::Result::Ok(std::option::Option::None) => panic!("Devnet slot subscription closed before one notification arrived"), std::result::Result::Err(_) => panic!("Devnet slot notification did not arrive within the smoke timeout"), }; assert!(notification.slot() > 0); let unsubscribed = subscription.unsubscribe().await.expect("Devnet slotUnsubscribe must succeed"); assert!(unsubscribed); session.close().await.expect("Devnet WebSocket session must close cleanly"); assert_eq!(session.snapshot().state(), ksp_onchain_transport_lib::WsSessionState::Closed); }