Skip to content

Commit d28d415

Browse files
authored
fix(DataStore): ReconcileAndLocalSave schedule on internal queue (#1415)
* fix(DataStore): ReconcileAndLocalSave schedule on internal queue * address PR comments
1 parent 9d2f475 commit d28d415

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginIntegrationTests/DataStoreEndToEndTests.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,73 @@ class DataStoreEndToEndTests: SyncEngineIntegrationTestBase {
330330
try validateSavePost()
331331
}
332332

333+
/// Perform concurrent saves and observe the data successfuly synced from cloud. Then delete the items afterwards
334+
/// and ensure they have successfully synced from cloud
335+
///
336+
/// - Given: DataStore is in ready state
337+
/// - When:
338+
/// - Concurrently perform Save's
339+
/// - Then:
340+
/// - Ensure the expected mutation event with version 1 (synced from cloud) is received
341+
/// - Clean up: Concurrently perform Delete's
342+
/// - Ensure the expected mutation event with version 2 (synced from cloud) is received
343+
///
344+
func testConcurrentSave() throws {
345+
try startAmplifyAndWaitForReady()
346+
347+
var posts = [Post]()
348+
let count = 5
349+
for _ in 0 ..< count {
350+
let post = Post(title: "title",
351+
content: "content",
352+
createdAt: .now())
353+
posts.append(post)
354+
}
355+
let postsSyncedToCloud = expectation(description: "All posts saved and synced to cloud")
356+
var postsSyncedToCloudCount = 0
357+
let postsDeletedFromCloud = expectation(description: "All posts deleted and synced to cloud")
358+
var postsDeletedFromCloudCount = 0
359+
let sink = Amplify.DataStore.publisher(for: Post.self).sink { completed in
360+
switch completed {
361+
case .finished:
362+
break
363+
case .failure(let error):
364+
XCTFail("\(error)")
365+
}
366+
} receiveValue: { mutationEvent in
367+
if mutationEvent.mutationType == MutationEvent.MutationType.create.rawValue,
368+
posts.contains(where: { $0.id == mutationEvent.modelId }),
369+
mutationEvent.version == 1 {
370+
postsSyncedToCloudCount += 1
371+
self.log.debug("Post saved and synced from cloud \(mutationEvent.modelId) \(postsSyncedToCloudCount)")
372+
if postsSyncedToCloudCount == count {
373+
postsSyncedToCloud.fulfill()
374+
}
375+
} else if mutationEvent.mutationType == MutationEvent.MutationType.delete.rawValue,
376+
posts.contains(where: { $0.id == mutationEvent.modelId }),
377+
mutationEvent.version == 2 {
378+
postsDeletedFromCloudCount += 1
379+
self.log.debug(
380+
"Post deleted and synced from cloud \(mutationEvent.modelId) \(postsDeletedFromCloudCount)")
381+
if postsDeletedFromCloudCount == count {
382+
postsDeletedFromCloud.fulfill()
383+
}
384+
}
385+
}
386+
387+
DispatchQueue.concurrentPerform(iterations: count) { index in
388+
_ = Amplify.DataStore.save(posts[index])
389+
}
390+
391+
wait(for: [postsSyncedToCloud], timeout: 100)
392+
393+
DispatchQueue.concurrentPerform(iterations: count) { index in
394+
_ = Amplify.DataStore.delete(posts[index])
395+
}
396+
wait(for: [postsDeletedFromCloud], timeout: 100)
397+
sink.cancel()
398+
}
399+
333400
// MARK: - Helpers
334401

335402
func validateSavePost() throws {
@@ -371,3 +438,8 @@ class DataStoreEndToEndTests: SyncEngineIntegrationTestBase {
371438
wait(for: [createReceived], timeout: networkTimeout)
372439
}
373440
}
441+
442+
@available(iOS 13.0, *)
443+
extension DataStoreEndToEndTests: DefaultLogger {
444+
445+
}

0 commit comments

Comments
 (0)