Skip to content

Commit ca7fafa

Browse files
committed
[tests] add a test for Property Executor Concurrency
* Add test `testPropertyExecutorConcurrency`
1 parent ec7d7e9 commit ca7fafa

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

iOS_SDK/OneSignalSDK/OneSignalUserTests/OneSignalUserTests.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,44 @@ final class OneSignalUserTests: XCTestCase {
175175
XCTAssertTrue(client.allRequestsHandled)
176176
}
177177

178+
/**
179+
This test aims to ensure concurrency safety in the Property Executor.
180+
It is possible for two threads to modify and cache queues concurrently.
181+
*/
182+
func testPropertyExecutorConcurrency() throws {
183+
/* Setup */
184+
let client = MockOneSignalClient()
185+
// Ensure all requests fire the executor's callback so it will modify queues and cache it
186+
client.fireSuccessForAllRequests = true
187+
OneSignalCoreImpl.setSharedClient(client)
188+
189+
let identityModel = OSIdentityModel(aliases: [OS_ONESIGNAL_ID: UUID().uuidString], changeNotifier: OSEventProducer())
190+
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(identityModel)
191+
192+
let executor = OSPropertyOperationExecutor()
193+
OSOperationRepo.sharedInstance.addExecutor(executor)
194+
195+
/* When */
196+
197+
DispatchQueue.concurrentPerform(iterations: 50) { _ in
198+
// 1. Enqueue Deltas to the Operation Repo
199+
OSOperationRepo.sharedInstance.enqueueDelta(OSDelta(name: OS_UPDATE_PROPERTIES_DELTA, identityModelId: identityModel.modelId, model: OSPropertiesModel(changeNotifier: OSEventProducer()), property: "language", value: UUID().uuidString))
200+
OSOperationRepo.sharedInstance.enqueueDelta(OSDelta(name: OS_UPDATE_PROPERTIES_DELTA, identityModelId: identityModel.modelId, model: OSPropertiesModel(changeNotifier: OSEventProducer()), property: "language", value: UUID().uuidString))
201+
202+
// 2. Flush Operation Repo
203+
OSOperationRepo.sharedInstance.addFlushDeltaQueueToDispatchQueue()
204+
205+
// 3. Simulate updating the executor's request queue from a network response
206+
executor.executeUpdatePropertiesRequest(OSRequestUpdateProperties(params: ["properties": ["language": UUID().uuidString], "refresh_device_metadata": false], identityModel: identityModel), inBackground: false)
207+
}
208+
209+
// 4. Run background threads
210+
OneSignalCoreMocks.waitForBackgroundThreads(seconds: 0.5)
211+
212+
/* Then */
213+
// No crash
214+
}
215+
178216
/**
179217
This test aims to ensure concurrency safety in the User Executor.
180218
It is possible for two threads to modify and cache queues concurrently.

0 commit comments

Comments
 (0)