diff --git a/crates/quicproquo-client/tests/e2e.rs b/crates/quicproquo-client/tests/e2e.rs index d64eacd..3beec2d 100644 --- a/crates/quicproquo-client/tests/e2e.rs +++ b/crates/quicproquo-client/tests/e2e.rs @@ -25,8 +25,9 @@ use quicproquo_client::{ }; use quicproquo_core::{GroupMember, HybridKeypair, IdentityKeypair, ReceivedMessage}; -/// Serialises all tests that call `init_auth` with a non-devtoken session to prevent -/// the global `AUTH_CONTEXT` from being overwritten by concurrent tests. +/// Serialises ALL tests that call `init_auth` to prevent the global `AUTH_CONTEXT` +/// from being overwritten by concurrent tests. Every test that mutates auth state +/// must hold this lock for its entire duration. static AUTH_LOCK: Mutex<()> = Mutex::new(()); fn hex_encode(bytes: &[u8]) -> String { @@ -97,6 +98,7 @@ fn spawn_server(base: &std::path::Path, extra_args: &[&str]) -> (String, PathBuf #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_happy_path_register_invite_join_send_recv() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -186,6 +188,7 @@ async fn e2e_happy_path_register_invite_join_send_recv() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_three_party_group_invite_join_send_recv() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -449,6 +452,7 @@ async fn e2e_login_rejects_mismatched_identity() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_sealed_sender_enqueue_then_fetch() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1171,6 +1175,7 @@ async fn e2e_key_rotation_update_path() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_hook_rejects_oversized_payload() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1216,6 +1221,7 @@ async fn e2e_hook_rejects_oversized_payload() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_multi_party_group() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1353,6 +1359,7 @@ async fn e2e_multi_party_group() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_file_upload_download() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1484,6 +1491,7 @@ async fn e2e_file_upload_download() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_blob_hash_mismatch() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1573,6 +1581,7 @@ fn spawn_server_custom(base: &std::path::Path, args: &[&str]) -> (String, PathBu #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_auth_failure_wrong_token() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1615,6 +1624,9 @@ async fn e2e_auth_failure_wrong_token() -> anyhow::Result<()> { } } + // Reset auth back to devtoken so other tests aren't poisoned. + init_auth(ClientAuth::from_parts("devtoken".to_string(), None)); + Ok(()) } @@ -1622,6 +1634,7 @@ async fn e2e_auth_failure_wrong_token() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_message_ordering_preserved() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1837,6 +1850,7 @@ async fn e2e_opaque_login_wrong_password() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_keypackage_exhaustion_graceful() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path(); @@ -1891,6 +1905,7 @@ async fn e2e_keypackage_exhaustion_graceful() -> anyhow::Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn e2e_rate_limiting_rejects_excess() -> anyhow::Result<()> { ensure_rustls_provider(); + let _auth = AUTH_LOCK.lock().unwrap(); let temp = TempDir::new()?; let base = temp.path();