Skip to content

Commit

Permalink
Increase test case timeout, fix deadlocks on older Xcode versions, an…
Browse files Browse the repository at this point in the history
…d fix incorrect member and watcher reset (#3213)
  • Loading branch information
laevandus authored May 20, 2024
1 parent a5f118b commit cc3a26c
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 72 deletions.
6 changes: 4 additions & 2 deletions Sources/StreamChat/Workers/ChannelUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -916,10 +916,12 @@ extension ChannelUpdater {
) async throws -> ChannelPayload {
// Just populate the closure since we select the endpoint based on it.
let useCreateEndpoint: ((ChannelId) -> Void)? = channelQuery.cid == nil ? { _ in } : nil
let parameter = channelQuery.pagination?.parameter
let reset = parameter == nil || parameter?.isJumpingToMessage == true
let actions = ChannelUpdateActions(
memberListSorting: memberSorting,
resetMembers: true,
resetWatchers: true
resetMembers: reset,
resetWatchers: reset
)
return try await withCheckedThrowingContinuation { continuation in
update(
Expand Down
46 changes: 29 additions & 17 deletions Tests/StreamChatTests/StateLayer/ChannelList_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,7 @@ final class ChannelList_Tests: XCTestCase {
try await env.client.mockDatabaseContainer.write { session in
session.saveChannelList(payload: incomingChannelListPayload, query: self.channelList.query)
}
#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)
cancellable.cancel()
}

Expand Down Expand Up @@ -222,11 +218,7 @@ final class ChannelList_Tests: XCTestCase {
let eventExpectation = XCTestExpectation(description: "Event processed")
env.client.eventNotificationCenter.process([event], completion: { eventExpectation.fulfill() })

#if swift(>=5.8)
await fulfillment(of: [eventExpectation, stateExpectation], timeout: defaultTimeout)
#else
wait(for: [eventExpectation, stateExpectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [eventExpectation, stateExpectation], timeout: defaultTimeout, enforceOrder: true)
cancellable.cancel()
}

Expand All @@ -242,6 +234,15 @@ final class ChannelList_Tests: XCTestCase {
// Ensure that the channel is in the state
XCTAssertEqual(existingChannelListPayload.channels.map(\.channel.cid.rawValue), await channelList.state.channels.map(\.cid.rawValue))

let stateExpectation = XCTestExpectation(description: "State changed")
let cancellable = await channelList.state.$channels
.dropFirst() // ignore initial
.sink { channels in
// Ensure the unlinking removed it from the state
XCTAssertEqual([], channels.map(\.cid))
stateExpectation.fulfill()
}

let event = ChannelUpdatedEvent(
channel: .mock(cid: existingCid, memberCount: 4),
user: .unique,
Expand All @@ -250,13 +251,8 @@ final class ChannelList_Tests: XCTestCase {
)
let eventExpectation = XCTestExpectation(description: "Event processed")
env.client.eventNotificationCenter.process([event], completion: { eventExpectation.fulfill() })
#if swift(>=5.8)
await fulfillment(of: [eventExpectation], timeout: defaultTimeout)
#else
wait(for: [eventExpectation], timeout: defaultTimeout)
#endif
// Ensure the unlinking removed it from the state
await XCTAssertEqual([], channelList.state.channels.map(\.cid))
await fulfillmentCompatibility(of: [eventExpectation], timeout: defaultTimeout, enforceOrder: true)
cancellable.cancel()
}

// MARK: - Test Data
Expand Down Expand Up @@ -332,3 +328,19 @@ extension ChannelList_Tests {
}
}
}

@available(iOS 13.0, *)
extension XCTestCase {
func fulfillmentCompatibility(of expectations: [XCTestExpectation], timeout seconds: TimeInterval, enforceOrder enforceOrderOfFulfillment: Bool = false) async {
#if swift(>=5.8)
await fulfillment(of: expectations, timeout: seconds, enforceOrder: enforceOrderOfFulfillment)
#else
await withCheckedContinuation { continuation in
Thread.detachNewThread { [self] in
wait(for: expectations, timeout: seconds, enforceOrder: enforceOrderOfFulfillment)
continuation.resume()
}
}
#endif
}
}
12 changes: 2 additions & 10 deletions Tests/StreamChatTests/StateLayer/Chat_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -560,11 +560,7 @@ final class Chat_Tests: XCTestCase {
messageId: apiResponse.message.id
)

#if swift(>=5.8)
await fulfillment(of: [notificationExpectation], timeout: defaultTimeout)
#else
wait(for: [notificationExpectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [notificationExpectation], timeout: defaultTimeout)

XCTAssertEqual(text, message.text)
await XCTAssertEqual(1, chat.state.messages.count)
Expand Down Expand Up @@ -1115,11 +1111,7 @@ final class Chat_Tests: XCTestCase {
)
XCTAssertEqual(apiResponse.message.id, replyMessage.id)

#if swift(>=5.8)
await fulfillment(of: [notificationExpectation], timeout: defaultTimeout)
#else
wait(for: [notificationExpectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [notificationExpectation], timeout: defaultTimeout)

let messageState = try await chat.messageState(for: lastMessageId)
await XCTAssertEqual(lastMessageId, messageState.message.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@ final class StateLayerDatabaseObserver_Tests: XCTestCase {

try await waitForDuplicateCallbacks()

#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)

XCTAssertEqual("first", observer.item?.name)
XCTAssertEqual(1, changeCount)
}
Expand All @@ -73,11 +70,8 @@ final class StateLayerDatabaseObserver_Tests: XCTestCase {

try await waitForDuplicateCallbacks()

#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)

XCTAssertEqual("second", observer.item?.name)
XCTAssertEqual(1, changeCount)
}
Expand All @@ -104,11 +98,8 @@ final class StateLayerDatabaseObserver_Tests: XCTestCase {

try await waitForDuplicateCallbacks()

#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)

XCTAssertEqual("second", observer.item?.name)
XCTAssertEqual("team2", observer.item?.team)
XCTAssertEqual(2, changeCount)
Expand Down Expand Up @@ -137,11 +128,8 @@ final class StateLayerDatabaseObserver_Tests: XCTestCase {

try await waitForDuplicateCallbacks()

#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)

XCTAssertEqual(8, observer.items.count)
let expectedIds = (firstPayload.messages + secondPayload.messages).map(\.id)
XCTAssertEqual(expectedIds, observer.items.map(\.id))
Expand Down Expand Up @@ -173,11 +161,8 @@ final class StateLayerDatabaseObserver_Tests: XCTestCase {

try await waitForDuplicateCallbacks()

#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)

XCTAssertEqual(3, observer.items.count)
XCTAssertEqual(secondPayload.messages.map(\.id), observer.items.map(\.id))
XCTAssertEqual(1, changeCount)
Expand Down Expand Up @@ -210,11 +195,8 @@ final class StateLayerDatabaseObserver_Tests: XCTestCase {

try await waitForDuplicateCallbacks()

#if swift(>=5.8)
await fulfillment(of: [expectation], timeout: defaultTimeout)
#else
wait(for: [expectation], timeout: defaultTimeout)
#endif
await fulfillmentCompatibility(of: [expectation], timeout: defaultTimeout)

XCTAssertEqual(11, observer.items.count)
let expectedIds = (firstPayload.messages + secondPayload.messages + thirdPayload.messages).map(\.id)
XCTAssertEqual(expectedIds, observer.items.map(\.id))
Expand Down
14 changes: 4 additions & 10 deletions Tests/StreamChatTests/StateLayer/UserSearch_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,17 @@ final class UserSearch_Tests: XCTestCase {
env.userListUpdaterMock.fetch_query_called = { _ in
expectation1.fulfill()
}
#if swift(>=5.8)
await fulfillment(of: [expectation1], timeout: defaultTimeout)
#else
wait(for: [expectation1], timeout: defaultTimeout)
#endif

await fulfillmentCompatibility(of: [expectation1], timeout: defaultTimeout)

// Search for "name"
async let result2 = try await userSearch.search(term: "name")
let expectation2 = XCTestExpectation()
env.userListUpdaterMock.fetch_query_called = { _ in
expectation2.fulfill()
}
#if swift(>=5.8)
await fulfillment(of: [expectation2], timeout: defaultTimeout)
#else
wait(for: [expectation2], timeout: defaultTimeout)
#endif

await fulfillmentCompatibility(of: [expectation2], timeout: defaultTimeout)

XCTAssertEqual(2, env.userListUpdaterMock.fetch_completions.count)

Expand Down
2 changes: 1 addition & 1 deletion Tests/StreamChatTests/StreamChatFlakyTests.xctestplan
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}
],
"defaultOptions" : {
"defaultTestExecutionTimeAllowance" : 180,
"defaultTestExecutionTimeAllowance" : 300,
"testTimeoutsEnabled" : true
},
"testTargets" : [
Expand Down
2 changes: 1 addition & 1 deletion Tests/StreamChatTests/StreamChatStressTestPlan.xctestplan
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"argument" : "-com.apple.CoreData.ConcurrencyDebug 1"
}
],
"defaultTestExecutionTimeAllowance" : 180,
"defaultTestExecutionTimeAllowance" : 300,
"environmentVariableEntries" : [
{
"key" : "TEST_INVOCATIONS",
Expand Down
2 changes: 1 addition & 1 deletion Tests/StreamChatTests/StreamChatTestPlan.xctestplan
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"argument" : "-com.apple.CoreData.ConcurrencyDebug 1"
}
],
"defaultTestExecutionTimeAllowance" : 180,
"defaultTestExecutionTimeAllowance" : 300,
"testTimeoutsEnabled" : true
},
"testTargets" : [
Expand Down

0 comments on commit cc3a26c

Please sign in to comment.