fix(e2e): serialize all init_auth tests behind AUTH_LOCK to prevent race
Every test that calls init_auth() now holds AUTH_LOCK for its full duration, preventing the global AUTH_CONTEXT from being overwritten by concurrent tests. The e2e_auth_failure_wrong_token test additionally resets auth back to "devtoken" after its assertion. Tests now pass reliably with default parallelism (no --test-threads 1 required).
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user