test(crawler): deflake sync serialization concurrency test
Some checks failed
deploy / test-backend (pull_request) Failing after 1m36s
deploy / build-and-push (pull_request) Has been cancelled
deploy / test-frontend (pull_request) Has been cancelled
deploy / deploy (pull_request) Has been cancelled

sync_chapters_serializes_concurrent_calls_for_same_manga asserted a single
ordering ([A,B,C]) that the per-manga advisory lock cannot guarantee: it
serializes the two concurrent syncs but not WHICH wins the lock last. Under
heavy CI load the order inverted — call X (list [A,B]) committed last and
correctly soft-dropped C (a key it never saw), yielding [A,B] → assertion
failed. Both [A,B,C] (Y last) and [A,B] (X last) are valid last-writer-wins
serializations; the lock only guarantees no TORN state. Accept either.

Pre-existing flake (test unchanged since 0.52.0, lock since 0.55.0); product
sync logic is correct and untouched. Unblocks the 0.84.0 deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 15:37:21 +02:00
parent d51ab2a049
commit bf2eea8c49

View File

@@ -583,10 +583,18 @@ async fn sync_chapters_serializes_concurrent_calls_for_same_manga(pool: PgPool)
.fetch_all(&pool)
.await
.unwrap();
assert_eq!(
alive,
vec!["A".to_string(), "B".to_string(), "C".to_string()],
"all chapters survive concurrent syncs that both contain them"
// The per-manga advisory lock serializes the two calls, but it cannot
// dictate WHICH commits last (spawn order is not guaranteed — under load
// it inverts), so two correct last-writer-wins outcomes are possible:
// - Y (list [A,B,C]) commits last → nothing dropped → [A,B,C].
// - X (list [A,B]) commits last → it soft-drops C, a key it never saw
// and which the next full sync re-adds → [A,B].
// The lock's job is to prevent a TORN result (a lost B, a half-applied
// drop), not to fix an order it cannot. Accept either serialization;
// anything else means the lock failed to serialize.
assert!(
alive == ["A", "B", "C"] || alive == ["A", "B"],
"concurrent syncs must leave a valid serialization, got {alive:?}"
);
}