// file: crates/apps/game-realtime-transport-fallback-smoke/unit_tests/fallback.rs // version: 1 #[test] fn fallback_policy_is_narrow_and_excludes_ambiguous_connect_failures() { assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::InvalidConfiguration)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Connect)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Bind)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Accept)); assert!(super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Timeout)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::MessageTooLarge)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Backpressure)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Closed)); assert!(super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Io)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Protocol)); assert!(!super::is_fallback_eligible(game_realtime_transport_lib::TransportErrorKind::Aborted)); } #[tokio::test(flavor = "current_thread")] async fn selector_prefers_webtransport_and_falls_back_only_for_classified_errors() { let preferred = super::select_preferred_transport( || async { return std::result::Result::::Ok(7); }, || async { return std::result::Result::::Err(test_error("fallback must not run")); }, ) .await; assert!(matches!(preferred, std::result::Result::Ok(super::SelectedConnection::WebTransport(7))), "WebTransport success must remain preferred"); let fallback = super::select_preferred_transport( || async { return std::result::Result::::Err(game_realtime_transport_lib::TransportError::new( game_realtime_transport_lib::TransportErrorKind::Timeout, "forced timeout", )); }, || async { return std::result::Result::::Ok(9); }, ) .await; assert!(matches!(fallback, std::result::Result::Ok(super::SelectedConnection::WebSocket(9))), "classified timeout must select WebSocket fallback"); let non_fallback = super::select_preferred_transport( || async { return std::result::Result::::Err(test_error("visible primary error")); }, || async { return std::result::Result::::Ok(11); }, ) .await; assert!( matches!( &non_fallback, std::result::Result::Err(error) if error.kind() == game_realtime_transport_lib::TransportErrorKind::InvalidConfiguration && error.detail() == "visible primary error" ), "non-fallback errors must remain visible" ); } fn test_error(detail: &str) -> game_realtime_transport_lib::TransportError { return game_realtime_transport_lib::TransportError::new(game_realtime_transport_lib::TransportErrorKind::InvalidConfiguration, detail); }