From 9f5491f6216314c136f609dda783db0c8a9e5fcb Mon Sep 17 00:00:00 2001 From: Liu Liu Date: Tue, 5 Oct 2021 02:17:24 -0400 Subject: [PATCH] Fix flaky tests The test is flaky because on subscription, it is done on main thread but asynchronously. Thus, if we don't drain the main queue, we could miss the first update (while always get the final deleted update). This will cause our fulfill logic fail. This PR does the wait for main queue to drain. Now, running `bazel test src/tests:Tests --runs_per_test=5000` will pass without any failures (about half-an-hour to run on Mac Mini 2020). --- src/tests/SubscribeTests.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tests/SubscribeTests.swift b/src/tests/SubscribeTests.swift index 59ec8a9f7..9199f4d35 100644 --- a/src/tests/SubscribeTests.swift +++ b/src/tests/SubscribeTests.swift @@ -398,6 +398,16 @@ class SubscribeTests: XCTestCase { ] #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) + func drainMainQueue() { + // Double dispatch to avoid nested main queue dispatch in previous blocks. + let mainQueueDrain = XCTestExpectation(description: "main") + DispatchQueue.main.async { + DispatchQueue.main.async { + mainQueueDrain.fulfill() + } + } + wait(for: [mainQueueDrain], timeout: 10.0) + } @available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) func testObjectPublisher() { guard let dflat = dflat else { return } @@ -432,6 +442,9 @@ class SubscribeTests: XCTestCase { pubExpectation.fulfill() } } + // The subscription happens on main queue asynchronously. Drain it to avoid we skip + // directly to deletion. + drainMainQueue() let firstExpectation = XCTestExpectation(description: "transcation done") dflat.performChanges( [MyGame.Sample.Monster.self], @@ -494,6 +507,9 @@ class SubscribeTests: XCTestCase { subExpectation.fulfill() } } + // The subscription happens on main queue asynchronously. Drain it to avoid we skip + // directly to deletion. + drainMainQueue() // Add one. let firstExpectation = XCTestExpectation(description: "transcation done") dflat.performChanges(