diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/MutationSync/MutationEvent/MutationEventClearState.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/MutationSync/MutationEvent/MutationEventClearState.swift new file mode 100644 index 0000000000..b8f8b0fa83 --- /dev/null +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/MutationSync/MutationEvent/MutationEventClearState.swift @@ -0,0 +1,65 @@ +// +// Copyright 2018-2020 Amazon.com, +// Inc. or its affiliates. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Amplify +import Foundation + +final class MutationEventClearState { + + let storageAdapter: StorageEngineAdapter + init(storageAdapter: StorageEngineAdapter) { + self.storageAdapter = storageAdapter + } + + func clearStateOutgoingMutations(completion: @escaping BasicClosure) { + let fields = MutationEvent.keys + let predicate = fields.inProcess == true + let orderClause = """ + ORDER BY \(MutationEvent.keys.createdAt.stringValue) ASC + """ + + storageAdapter.query(MutationEvent.self, + predicate: predicate, + paginationInput: nil, + additionalStatements: orderClause) { result in + switch result { + case .failure(let dataStoreError): + log.error("Failed on clearStateOutgoingMutations: \(dataStoreError)") + case .success(let mutationEvents): + if !mutationEvents.isEmpty { + updateMutationsState(mutationEvents: mutationEvents, + completion: completion) + } else { + completion() + } + } + } + } + + private func updateMutationsState(mutationEvents: [MutationEvent], completion: @escaping BasicClosure) { + var numMutationEventsUpdated = 0 + for mutationEvent in mutationEvents { + var inProcessEvent = mutationEvent + inProcessEvent.inProcess = false + storageAdapter.save(inProcessEvent, condition: nil, completion: { result in + switch result { + case .success: + numMutationEventsUpdated += 1 + if numMutationEventsUpdated >= mutationEvents.count { + completion() + } + case .failure(let error): + self.log.error("Failed to update mutationEvent:\(error)") + } + }) + } + } + +} + +@available(iOS 13.0, *) +extension MutationEventClearState: DefaultLogger { } diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Action.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Action.swift index 02cb224ae7..20b3451724 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Action.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Action.swift @@ -17,7 +17,8 @@ extension RemoteSyncEngine { case receivedStart case pausedSubscriptions - case pausedMutationQueue(APICategoryGraphQLBehavior, StorageEngineAdapter) + case pausedMutationQueue(StorageEngineAdapter) + case clearedStateOutgoingMutations(APICategoryGraphQLBehavior, StorageEngineAdapter) case initializedSubscriptions case performedInitialSync case activatedCloudSubscriptions(APICategoryGraphQLBehavior, MutationEventPublisher) @@ -41,6 +42,8 @@ extension RemoteSyncEngine { return "pausedSubscriptions" case .pausedMutationQueue: return "pausedMutationQueue" + case .clearedStateOutgoingMutations: + return "resetStateOutgoingMutations" case .initializedSubscriptions: return "initializedSubscriptions" case .performedInitialSync: diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Resolver.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Resolver.swift index baf0e6af96..734e7256d9 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Resolver.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+Resolver.swift @@ -20,7 +20,10 @@ extension RemoteSyncEngine { case (.pausingSubscriptions, .pausedSubscriptions): return .pausingMutationQueue - case (.pausingMutationQueue, .pausedMutationQueue(let api, let storageEngineAdapter)): + case (.pausingMutationQueue, .pausedMutationQueue(let storageEngineAdapter)): + return .clearingStateOutgoingMutations(storageEngineAdapter) + + case (.clearingStateOutgoingMutations, .clearedStateOutgoingMutations(let api, let storageEngineAdapter)): return .initializingSubscriptions(api, storageEngineAdapter) case (.initializingSubscriptions, .initializedSubscriptions): diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+State.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+State.swift index c7b3e1d8f3..46217209d7 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+State.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine+State.swift @@ -16,6 +16,7 @@ extension RemoteSyncEngine { case pausingSubscriptions case pausingMutationQueue + case clearingStateOutgoingMutations(StorageEngineAdapter) case initializingSubscriptions(APICategoryGraphQLBehavior, StorageEngineAdapter) case performingInitialSync case activatingCloudSubscriptions @@ -38,6 +39,8 @@ extension RemoteSyncEngine { return "pausingSubscriptions" case .pausingMutationQueue: return "pausingMutationQueue" + case .clearingStateOutgoingMutations: + return "clearingStateOutgoingMutations" case .initializingSubscriptions: return "initializingSubscriptions" case .performingInitialSync: diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine.swift index effb917e5b..aaa61e02ac 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine.swift @@ -135,6 +135,8 @@ class RemoteSyncEngine: RemoteSyncEngineBehavior { pauseSubscriptions() case .pausingMutationQueue: pauseMutations() + case .clearingStateOutgoingMutations(let storageAdapter): + clearStateOutgoingMutations(storageAdapter: storageAdapter) case .initializingSubscriptions(let api, let storageAdapter): initializeSubscriptions(api: api, storageAdapter: storageAdapter) case .performingInitialSync: @@ -209,8 +211,19 @@ class RemoteSyncEngine: RemoteSyncEngineBehavior { outgoingMutationQueue.pauseSyncingToCloud() remoteSyncTopicPublisher.send(.mutationsPaused) - if let api = self.api, let storageAdapter = self.storageAdapter { - stateMachine.notify(action: .pausedMutationQueue(api, storageAdapter)) + if let storageAdapter = self.storageAdapter { + stateMachine.notify(action: .pausedMutationQueue(storageAdapter)) + } + } + + private func clearStateOutgoingMutations(storageAdapter: StorageEngineAdapter) { + log.debug(#function) + let mutationEventClearState = MutationEventClearState(storageAdapter: storageAdapter) + mutationEventClearState.clearStateOutgoingMutations { + if let api = self.api { + self.remoteSyncTopicPublisher.send(.clearedStateOutgoingMutations) + self.stateMachine.notify(action: .clearedStateOutgoingMutations(api, storageAdapter)) + } } } diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngineBehavior.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngineBehavior.swift index 84dc8a65cb..b66382c896 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngineBehavior.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngineBehavior.swift @@ -12,6 +12,7 @@ enum RemoteSyncEngineEvent { case storageAdapterAvailable case subscriptionsPaused case mutationsPaused + case clearedStateOutgoingMutations case subscriptionsInitialized case performedInitialSync case subscriptionsActivated diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationEventClearStateTests.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationEventClearStateTests.swift new file mode 100644 index 0000000000..e766a694cb --- /dev/null +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationEventClearStateTests.swift @@ -0,0 +1,56 @@ +// +// Copyright 2018-2020 Amazon.com, +// Inc. or its affiliates. All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation +import XCTest + +@testable import Amplify +@testable import AmplifyTestCommon +@testable import AWSPluginsCore +@testable import AWSDataStoreCategoryPlugin + +class MutationEventClearStateTests: XCTestCase { + var mockStorageAdapter: MockSQLiteStorageEngineAdapter! + var mutationEventClearState: MutationEventClearState! + + override func setUp() { + mockStorageAdapter = MockSQLiteStorageEngineAdapter() + mutationEventClearState = MutationEventClearState(storageAdapter: mockStorageAdapter) + } + + func testInProcessIsSetFromTrueToFalse() { + let queryExpectation = expectation(description: "query is called") + let saveExpectation = expectation(description: "save is Called") + let completionExpectation = expectation(description: "completion handler is called") + + let queryResponder = QueryModelTypePredicateAdditionalStatementsResponder { _, _, _ in + queryExpectation.fulfill() + var mutationEvent = MutationEvent(modelId: "1111-22", + modelName: "Post", + json: "{}", + mutationType: .create) + mutationEvent.inProcess = true + return .success([mutationEvent]) + } + mockStorageAdapter.responders[.queryModelTypePredicateAdditionalStatements] = queryResponder + + let saveResponder = SaveModelCompletionResponder { model, completion in + XCTAssertEqual("1111-22", model.modelId) + XCTAssertFalse(model.inProcess) + saveExpectation.fulfill() + completion(.success(model)) + } + mockStorageAdapter.responders[.saveModelCompletion] = saveResponder + + mutationEventClearState.clearStateOutgoingMutations { + completionExpectation.fulfill() + } + wait(for: [queryExpectation, + saveExpectation, + completionExpectation], timeout: 1.0) + } +} diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationIngesterConflictResolutionTests.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationIngesterConflictResolutionTests.swift index cfc824b938..e5a5e3bae6 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationIngesterConflictResolutionTests.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/MutationQueue/MutationIngesterConflictResolutionTests.swift @@ -622,9 +622,9 @@ class MutationIngesterConflictResolutionTests: SyncEngineTestBase { tryOrFail { try setUpStorageAdapter(preCreating: [Post.self, Comment.self]) - try saveMutationEvent(of: .create, for: post, inProcess: true) try setUpDataStore() try startAmplifyAndWaitForSync() + try saveMutationEvent(of: .create, for: post, inProcess: true) } let saveResultReceived = expectation(description: "Save result received") @@ -671,10 +671,10 @@ class MutationIngesterConflictResolutionTests: SyncEngineTestBase { tryOrFail { try setUpStorageAdapter(preCreating: [Post.self, Comment.self]) - try saveMutationEvent(of: .create, for: post, inProcess: true) - try savePost(post) try setUpDataStore() try startAmplifyAndWaitForSync() + try savePost(post) + try saveMutationEvent(of: .create, for: post, inProcess: true) } var mutatedPost = post @@ -725,9 +725,9 @@ class MutationIngesterConflictResolutionTests: SyncEngineTestBase { tryOrFail { try setUpStorageAdapter(preCreating: [Post.self, Comment.self]) - try saveMutationEvent(of: .create, for: post, inProcess: true) try setUpDataStore() try startAmplifyAndWaitForSync() + try saveMutationEvent(of: .create, for: post, inProcess: true) } let deleteResultReceived = expectation(description: "Delete result received") diff --git a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/RemoteSyncEngineTests.swift b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/RemoteSyncEngineTests.swift index 3de5108643..e5a4ea1942 100644 --- a/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/RemoteSyncEngineTests.swift +++ b/AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/RemoteSyncEngineTests.swift @@ -63,6 +63,7 @@ class RemoteSyncEngineTests: XCTestCase { let storageAdapterAvailable = expectation(description: "storageAdapterAvailable") let subscriptionsPaused = expectation(description: "subscriptionsPaused") let mutationsPaused = expectation(description: "mutationsPaused") + let stateMutationsCleared = expectation(description: "stateMutationsCleared") let subscriptionsInitialized = expectation(description: "subscriptionsInitialized") let cleanedup = expectation(description: "cleanedup") let failureOnInitialSync = expectation(description: "failureOnInitialSync") @@ -75,7 +76,7 @@ class RemoteSyncEngineTests: XCTestCase { let remoteSyncEngineSink = remoteSyncEngine .publisher .sink(receiveCompletion: { _ in - currCount = self.checkAndFulfill(currCount, 6, expectation: failureOnInitialSync) + currCount = self.checkAndFulfill(currCount, 7, expectation: failureOnInitialSync) }, receiveValue: { event in switch event { case .storageAdapterAvailable: @@ -87,12 +88,14 @@ class RemoteSyncEngineTests: XCTestCase { DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500)) { MockAWSIncomingEventReconciliationQueue.mockSend(event: .initialized) } + case .clearedStateOutgoingMutations: + currCount = self.checkAndFulfill(currCount, 4, expectation: stateMutationsCleared) case .subscriptionsInitialized: - currCount = self.checkAndFulfill(currCount, 4, expectation: subscriptionsInitialized) + currCount = self.checkAndFulfill(currCount, 5, expectation: subscriptionsInitialized) case .performedInitialSync: XCTFail("performedInitialQueries should not be successful") case .cleanedUp: - currCount = self.checkAndFulfill(currCount, 5, expectation: cleanedup) + currCount = self.checkAndFulfill(currCount, 6, expectation: cleanedup) default: XCTFail("Unexpected case gets hit") } @@ -105,6 +108,7 @@ class RemoteSyncEngineTests: XCTestCase { wait(for: [storageAdapterAvailable, subscriptionsPaused, mutationsPaused, + stateMutationsCleared, subscriptionsInitialized, cleanedup, failureOnInitialSync], timeout: defaultAsyncWaitTimeout) @@ -114,6 +118,7 @@ class RemoteSyncEngineTests: XCTestCase { let storageAdapterAvailable = expectation(description: "storageAdapterAvailable") let subscriptionsPaused = expectation(description: "subscriptionsPaused") let mutationsPaused = expectation(description: "mutationsPaused") + let stateMutationsCleared = expectation(description: "stateMutationsCleared") let subscriptionsInitialized = expectation(description: "subscriptionsInitialized") let performedInitialSync = expectation(description: "performedInitialSync") let subscriptionActivation = expectation(description: "failureOnSubscriptionActivation") @@ -137,16 +142,18 @@ class RemoteSyncEngineTests: XCTestCase { DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500)) { MockAWSIncomingEventReconciliationQueue.mockSend(event: .initialized) } + case .clearedStateOutgoingMutations: + currCount = self.checkAndFulfill(currCount, 4, expectation: stateMutationsCleared) case .subscriptionsInitialized: - currCount = self.checkAndFulfill(currCount, 4, expectation: subscriptionsInitialized) + currCount = self.checkAndFulfill(currCount, 5, expectation: subscriptionsInitialized) case .performedInitialSync: - currCount = self.checkAndFulfill(currCount, 5, expectation: performedInitialSync) + currCount = self.checkAndFulfill(currCount, 6, expectation: performedInitialSync) case .subscriptionsActivated: - currCount = self.checkAndFulfill(currCount, 6, expectation: subscriptionActivation) + currCount = self.checkAndFulfill(currCount, 7, expectation: subscriptionActivation) case .mutationQueueStarted: - currCount = self.checkAndFulfill(currCount, 7, expectation: mutationQueueStarted) + currCount = self.checkAndFulfill(currCount, 8, expectation: mutationQueueStarted) case .syncStarted: - currCount = self.checkAndFulfill(currCount, 8, expectation: syncStarted) + currCount = self.checkAndFulfill(currCount, 9, expectation: syncStarted) default: XCTFail("unexpected call") } @@ -157,6 +164,7 @@ class RemoteSyncEngineTests: XCTestCase { wait(for: [storageAdapterAvailable, subscriptionsPaused, mutationsPaused, + stateMutationsCleared, subscriptionsInitialized, performedInitialSync, subscriptionActivation, @@ -168,6 +176,7 @@ class RemoteSyncEngineTests: XCTestCase { let storageAdapterAvailable = expectation(description: "storageAdapterAvailable") let subscriptionsPaused = expectation(description: "subscriptionsPaused") let mutationsPaused = expectation(description: "mutationsPaused") + let stateMutationsCleared = expectation(description: "stateMutationsCleared") let subscriptionsInitialized = expectation(description: "subscriptionsInitialized") let performedInitialSync = expectation(description: "performedInitialSync") let subscriptionActivation = expectation(description: "failureOnSubscriptionActivation") @@ -184,7 +193,7 @@ class RemoteSyncEngineTests: XCTestCase { let remoteSyncEngineSink = remoteSyncEngine .publisher .sink(receiveCompletion: { _ in - currCount = self.checkAndFulfill(currCount, 10, expectation: forceFailToNotRestartSyncEngine) + currCount = self.checkAndFulfill(currCount, 11, expectation: forceFailToNotRestartSyncEngine) }, receiveValue: { event in switch event { case .storageAdapterAvailable: @@ -196,21 +205,23 @@ class RemoteSyncEngineTests: XCTestCase { DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500)) { MockAWSIncomingEventReconciliationQueue.mockSend(event: .initialized) } + case .clearedStateOutgoingMutations: + currCount = self.checkAndFulfill(currCount, 4, expectation: stateMutationsCleared) case .subscriptionsInitialized: - currCount = self.checkAndFulfill(currCount, 4, expectation: subscriptionsInitialized) + currCount = self.checkAndFulfill(currCount, 5, expectation: subscriptionsInitialized) case .performedInitialSync: - currCount = self.checkAndFulfill(currCount, 5, expectation: performedInitialSync) + currCount = self.checkAndFulfill(currCount, 6, expectation: performedInitialSync) case .subscriptionsActivated: - currCount = self.checkAndFulfill(currCount, 6, expectation: subscriptionActivation) + currCount = self.checkAndFulfill(currCount, 7, expectation: subscriptionActivation) case .mutationQueueStarted: - currCount = self.checkAndFulfill(currCount, 7, expectation: mutationQueueStarted) + currCount = self.checkAndFulfill(currCount, 8, expectation: mutationQueueStarted) case .syncStarted: - currCount = self.checkAndFulfill(currCount, 8, expectation: syncStarted) + currCount = self.checkAndFulfill(currCount, 9, expectation: syncStarted) DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500)) { MockAWSIncomingEventReconciliationQueue.mockSendCompletion(completion: .failure(DataStoreError.unknown("", "", nil))) } case .cleanedUp: - currCount = self.checkAndFulfill(currCount, 9, expectation: cleanedUp) + currCount = self.checkAndFulfill(currCount, 10, expectation: cleanedUp) default: XCTFail("unexpected call") } @@ -221,6 +232,7 @@ class RemoteSyncEngineTests: XCTestCase { wait(for: [storageAdapterAvailable, subscriptionsPaused, mutationsPaused, + stateMutationsCleared, subscriptionsInitialized, performedInitialSync, subscriptionActivation, @@ -234,6 +246,7 @@ class RemoteSyncEngineTests: XCTestCase { let storageAdapterAvailable = expectation(description: "storageAdapterAvailable") let subscriptionsPaused = expectation(description: "subscriptionsPaused") let mutationsPaused = expectation(description: "mutationsPaused") + let stateMutationsCleared = expectation(description: "stateMutationsCleared") let subscriptionsInitialized = expectation(description: "subscriptionsInitialized") let performedInitialSync = expectation(description: "performedInitialSync") let subscriptionActivation = expectation(description: "failureOnSubscriptionActivation") @@ -251,7 +264,7 @@ class RemoteSyncEngineTests: XCTestCase { let remoteSyncEngineSink = remoteSyncEngine .publisher .sink(receiveCompletion: { _ in - currCount = self.checkAndFulfill(currCount, 10, expectation: forceFailToNotRestartSyncEngine) + currCount = self.checkAndFulfill(currCount, 11, expectation: forceFailToNotRestartSyncEngine) }, receiveValue: { event in switch event { case .storageAdapterAvailable: @@ -263,25 +276,27 @@ class RemoteSyncEngineTests: XCTestCase { DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500)) { MockAWSIncomingEventReconciliationQueue.mockSend(event: .initialized) } + case .clearedStateOutgoingMutations: + currCount = self.checkAndFulfill(currCount, 4, expectation: stateMutationsCleared) case .subscriptionsInitialized: - currCount = self.checkAndFulfill(currCount, 4, expectation: subscriptionsInitialized) + currCount = self.checkAndFulfill(currCount, 5, expectation: subscriptionsInitialized) case .performedInitialSync: - currCount = self.checkAndFulfill(currCount, 5, expectation: performedInitialSync) + currCount = self.checkAndFulfill(currCount, 6, expectation: performedInitialSync) case .subscriptionsActivated: - currCount = self.checkAndFulfill(currCount, 6, expectation: subscriptionActivation) + currCount = self.checkAndFulfill(currCount, 7, expectation: subscriptionActivation) case .mutationQueueStarted: - currCount = self.checkAndFulfill(currCount, 7, expectation: mutationQueueStarted) + currCount = self.checkAndFulfill(currCount, 8, expectation: mutationQueueStarted) case .syncStarted: - currCount = self.checkAndFulfill(currCount, 8, expectation: syncStarted) + currCount = self.checkAndFulfill(currCount, 9, expectation: syncStarted) DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500)) { self.remoteSyncEngine.stop(completion: { result in if case .success = result { - currCount = self.checkAndFulfill(currCount, 11, expectation: completionBlockCalled) + currCount = self.checkAndFulfill(currCount, 12, expectation: completionBlockCalled) } }) } case .cleanedUpForTermination: - currCount = self.checkAndFulfill(currCount, 9, expectation: cleanedUpForTermination) + currCount = self.checkAndFulfill(currCount, 10, expectation: cleanedUpForTermination) default: XCTFail("unexpected call") } @@ -292,6 +307,7 @@ class RemoteSyncEngineTests: XCTestCase { wait(for: [storageAdapterAvailable, subscriptionsPaused, mutationsPaused, + stateMutationsCleared, subscriptionsInitialized, performedInitialSync, subscriptionActivation, diff --git a/AmplifyPlugins/DataStore/DataStoreCategoryPlugin.xcodeproj/project.pbxproj b/AmplifyPlugins/DataStore/DataStoreCategoryPlugin.xcodeproj/project.pbxproj index 6210d72229..3d82a550db 100644 --- a/AmplifyPlugins/DataStore/DataStoreCategoryPlugin.xcodeproj/project.pbxproj +++ b/AmplifyPlugins/DataStore/DataStoreCategoryPlugin.xcodeproj/project.pbxproj @@ -67,6 +67,8 @@ 6B64027923E3584300001FD7 /* MockAWSIncomingEventReconciliationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B64027823E3584300001FD7 /* MockAWSIncomingEventReconciliationQueue.swift */; }; 6B64027B23E38B9900001FD7 /* MockOutgoingMutationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B64027A23E38B9900001FD7 /* MockOutgoingMutationQueue.swift */; }; 6B91DEBF238B9CE0004D6BEE /* ReconcileAndLocalSaveOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B91DEBE238B9CE0004D6BEE /* ReconcileAndLocalSaveOperationTests.swift */; }; + 6BB93F07244BA44B00ED1FC3 /* MutationEventClearState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93F06244BA44B00ED1FC3 /* MutationEventClearState.swift */; }; + 6BB93F09244BA8ED00ED1FC3 /* MutationEventClearStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93F08244BA8ED00ED1FC3 /* MutationEventClearStateTests.swift */; }; 6BC4FDA823A899180027D20C /* RequestRetryablePolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC4FDA723A899180027D20C /* RequestRetryablePolicyTests.swift */; }; 6BC4FDAA23A899680027D20C /* MockRequestRetryablePolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC4FDA923A899680027D20C /* MockRequestRetryablePolicy.swift */; }; 6BDC224023E21A4E007C8410 /* RemoteSyncEngineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BDC223F23E21A4E007C8410 /* RemoteSyncEngineTests.swift */; }; @@ -242,6 +244,8 @@ 6B64027823E3584300001FD7 /* MockAWSIncomingEventReconciliationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAWSIncomingEventReconciliationQueue.swift; sourceTree = ""; }; 6B64027A23E38B9900001FD7 /* MockOutgoingMutationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockOutgoingMutationQueue.swift; sourceTree = ""; }; 6B91DEBE238B9CE0004D6BEE /* ReconcileAndLocalSaveOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReconcileAndLocalSaveOperationTests.swift; sourceTree = ""; }; + 6BB93F06244BA44B00ED1FC3 /* MutationEventClearState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutationEventClearState.swift; sourceTree = ""; }; + 6BB93F08244BA8ED00ED1FC3 /* MutationEventClearStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutationEventClearStateTests.swift; sourceTree = ""; }; 6BC4FDA723A899180027D20C /* RequestRetryablePolicyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestRetryablePolicyTests.swift; sourceTree = ""; }; 6BC4FDA923A899680027D20C /* MockRequestRetryablePolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRequestRetryablePolicy.swift; sourceTree = ""; }; 6BDC223F23E21A4E007C8410 /* RemoteSyncEngineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteSyncEngineTests.swift; sourceTree = ""; }; @@ -600,6 +604,7 @@ FACBA78A2394950C006349C8 /* MutationEventSource.swift */, FA55A54A2391EAB5002AFF2D /* MutationEventSubscriber.swift */, FA55A5482391EA89002AFF2D /* MutationEventSubscription.swift */, + 6BB93F06244BA44B00ED1FC3 /* MutationEventClearState.swift */, ); path = MutationEvent; sourceTree = ""; @@ -697,6 +702,7 @@ 6B3381BB239778E90036F046 /* AWSMutationDatabaseAdapterTests.swift */, FA3B3F08238F39DE002EFDB3 /* AWSMutationEventIngesterTests.swift */, FA4B8E932391C2CD009FC10F /* MutationIngesterConflictResolutionTests.swift */, + 6BB93F08244BA8ED00ED1FC3 /* MutationEventClearStateTests.swift */, 2149E5F4238869CF00873955 /* OutgoingMutationQueueTests.swift */, 6B4E3DF32397269C00AD962B /* OutgoingMutationQueueTestsWithMockStateMachine.swift */, 21B3AD26242BB58000C7E1DA /* ProcessMutationErrorFromCloudOperationTests.swift */, @@ -1286,6 +1292,7 @@ FA3B3F03238F22CF002EFDB3 /* OutgoingMutationQueue+State.swift in Sources */, FA5D4CEF238AFCBC00D2F54A /* AWSDataStorePlugin+DataStoreSubscribeBehavior.swift in Sources */, FAAFAF3923905F35002CF932 /* MutationEventPublisher.swift in Sources */, + 6BB93F07244BA44B00ED1FC3 /* MutationEventClearState.swift in Sources */, 2149E5C82388684F00873955 /* SQLStatement.swift in Sources */, FAED5742238B52CE008EBED8 /* ModelStorageBehavior.swift in Sources */, 2149E5C62388684F00873955 /* StorageEngineAdapter.swift in Sources */, @@ -1310,6 +1317,7 @@ buildActionMask = 2147483647; files = ( 6BC4FDAA23A899680027D20C /* MockRequestRetryablePolicy.swift in Sources */, + 6BB93F09244BA8ED00ED1FC3 /* MutationEventClearStateTests.swift in Sources */, 2149E5FD238869CF00873955 /* OutgoingMutationQueueTests.swift in Sources */, 6B91DEBF238B9CE0004D6BEE /* ReconcileAndLocalSaveOperationTests.swift in Sources */, 6BDC224223E27324007C8410 /* MockAWSInitialSyncOrchestrator.swift in Sources */,