mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-08-22 07:16:03 +00:00
Deflake AppArchitectureTests: raise the local waitUntil to settleTimeout (#1653)
* Deflake AppArchitectureTests: raise the local waitUntil to settleTimeout The file-local waitUntil defaulted to 3s — below the documented minimumSettleTimeout floor — and the recent-chats geo-dedup wait missed it on a loaded runner right after merge (the Combine hop through receive(on: .main) was starved). Every caller waits for a condition to become true, so green runs return immediately and never pay the 30s deadline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix the real geo-dedup race: re-assert tracker state on each poll The 30s deadline didn't help — the recent-chats geo-dedup wait wasn't slow, it was permanently broken under parallel swift-test load: the view model's own channel binding delivers its initial .mesh selection asynchronously and resets the active participant geohash when it lands (GeohashSubscriptionManager → setActiveParticipantGeohash(nil)), wiping the test's setup so the dedup could never happen. Reproduced locally with `swift test --parallel`; standalone runs never hit it. The wait now re-asserts setActiveGeohash + recordParticipant on every poll (both idempotent) — the same self-healing pattern the geohash timeline test already uses for singleton interference. Interference heals on the next poll; a genuine dedup failure still times out. 6× full parallel runs green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5b592c8bae
commit
dba67c1466
@ -69,7 +69,11 @@ private func makeArchitectureMessage(
|
||||
|
||||
@MainActor
|
||||
private func waitUntil(
|
||||
timeoutNanoseconds: UInt64 = 3_000_000_000,
|
||||
// Settle deadline, not a latency budget (see TestConstants.settleTimeout):
|
||||
// the old 3s default flaked on CI the moment a Combine hop through
|
||||
// receive(on: .main) was starved. Every caller waits for a condition to
|
||||
// become true, so passing runs return immediately.
|
||||
timeoutNanoseconds: UInt64 = UInt64(TestConstants.settleTimeout * 1_000_000_000),
|
||||
pollNanoseconds: UInt64 = 20_000_000,
|
||||
_ condition: @escaping @MainActor () -> Bool
|
||||
) async {
|
||||
@ -580,11 +584,19 @@ struct AppArchitectureTests {
|
||||
|
||||
// While that person is visible in the geohash roster, the chat row
|
||||
// collapses — same absent-from-rosters contract as mesh.
|
||||
viewModel.participantTracker.setActiveGeohash("u4pruy")
|
||||
viewModel.participantTracker.recordParticipant(pubkeyHex: pubkeyHex, geohash: "u4pruy")
|
||||
|
||||
//
|
||||
// Re-assert the tracker state on every poll: the view model's own
|
||||
// channel binding delivers its initial .mesh selection asynchronously
|
||||
// and resets the active participant geohash when it lands
|
||||
// (GeohashSubscriptionManager.setActiveParticipantGeohash(nil)) — on
|
||||
// a loaded parallel runner that reset arrives AFTER this setup and
|
||||
// the dedup can never happen. Both calls are idempotent, so the
|
||||
// interference heals on the next poll while a genuine dedup failure
|
||||
// still times out.
|
||||
await waitUntil {
|
||||
!peerListModel.recentChatRows.contains { $0.peerID == geoDMPeer }
|
||||
viewModel.participantTracker.setActiveGeohash("u4pruy")
|
||||
viewModel.participantTracker.recordParticipant(pubkeyHex: pubkeyHex, geohash: "u4pruy")
|
||||
return !peerListModel.recentChatRows.contains { $0.peerID == geoDMPeer }
|
||||
}
|
||||
#expect(!peerListModel.recentChatRows.contains { $0.peerID == geoDMPeer })
|
||||
#expect(peerListModel.recentChatRows.map(\.peerID) == [offlinePeerID])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user