test(punktfunk1): serialize in-process-host tests (shared admission table)

The reconnect-preempt (b53710d, preempt_same_identity) reads the process-global admission table
and signals same-identity live sessions. The three in-process-host tests each bind a fixed loopback
port and share that ONE table, so running them concurrently let one test's connection preempt +
close another's live session — an intermittent `next_au: Closed` in c_abi_connection_roundtrip
(surfaced under full-workspace load; a lucky pass hid it at b53710d). Serialize them on a
poison-tolerant lock. Test-isolation only — in production a host is one process with unique client
certs, so same-identity preempt is correct. Full workspace `cargo test` now green (18 suites, 3× clean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-05 18:09:59 +00:00
parent fc1e8a8a32
commit 334f36ce25
+10
View File
@@ -3982,10 +3982,18 @@ mod tests {
/// End-to-end through the C ABI — the exact contract platform clients (Swift) link:
/// in-process punktfunk/1 host, `punktfunk_connect` (TOFU → pinned reconnect) →
/// `punktfunk_connection_next_au` pulls verified frames → `punktfunk_connection_send_input`
/// In-process-host tests each spin up a host on a fixed loopback port and share the process-global
/// admission table, so they must NOT run concurrently: a same-identity connection in one test would
/// fire the reconnect-preempt (`preempt_same_identity`) against another test's live session and
/// close it. Serialize them on this lock. Poison-tolerant (`into_inner`) so a failing test doesn't
/// cascade a poison error into the others.
static SESSION_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
/// enqueues → `punktfunk_connection_close`. Three sequential sessions against ONE host
/// process prove the persistent listener, and a wrong pin is rejected.
#[test]
fn c_abi_connection_roundtrip() {
let _serial = SESSION_TEST_LOCK.lock().unwrap_or_else(|p| p.into_inner());
use punktfunk_core::abi::{
punktfunk_connect, punktfunk_connection_close, punktfunk_connection_mode,
punktfunk_connection_send_input,
@@ -4174,6 +4182,7 @@ mod tests {
/// admitted to a session with no PIN and no reconnect.
#[test]
fn delegated_approval_admits_after_knock() {
let _serial = SESSION_TEST_LOCK.lock().unwrap_or_else(|p| p.into_inner());
use punktfunk_core::client::NativeClient;
use punktfunk_core::quic::endpoint;
@@ -4285,6 +4294,7 @@ mod tests {
/// identity gets a session on a pairing-required host; an anonymous client does not.
#[test]
fn pairing_ceremony_and_gate() {
let _serial = SESSION_TEST_LOCK.lock().unwrap_or_else(|p| p.into_inner());
use punktfunk_core::client::NativeClient;
use punktfunk_core::quic::endpoint;