Skip to content

Commit

Permalink
feat: Add default reset implementation for Plugins (#3080)
Browse files Browse the repository at this point in the history
Adds default reset implementation for Plugins. Changes all Resettable conformances to async functions. Removes redundant no-op reset method from AWSCognitoAuthPlugin.
  • Loading branch information
palpatim authored Jul 12, 2023
1 parent ae44d86 commit 27278f7
Show file tree
Hide file tree
Showing 38 changed files with 124 additions and 68 deletions.
42 changes: 42 additions & 0 deletions Amplify/Core/Plugin/Internal/Plugin+Resettable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

public extension Resettable where Self: Plugin {
/// A default conformance if the plugin has no reset logic
///
/// **Warning**
///
/// This conformance will take precedence over a non-async `reset` method in an async context. Thus, given a plugin like:
/// ```swift
/// class MyPlugin: Plugin {
/// // Not invoked during `await Amplify.reset()`
/// func reset() { ... }
/// }
/// ```
///
/// The `MyPlugin.reset()` method will never be called during an invocation of `await Amplify.reset()`. Ensure
/// plugin `reset()` methods are always declared `async`:
/// ```swift
/// class MyPlugin: Plugin {
/// // Invoked during `await Amplify.reset()`
/// func reset() async { ... }
/// }
/// ```
///
/// As a best practice, always invoke `reset` through the Resettable protocol existential, rather than the concrete conforming
/// type, especially in tests:
/// ```swift
/// func testReset() async {
/// let resettable = plugin as Resettable
/// await resettable.reset()
/// // ... assert that the plugin state has been cleared
/// }
/// ```
func reset() async {
// Do nothing
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final public class AWSUnifiedLoggingPlugin: LoggingCategoryPlugin {
}

/// Removes listeners and empties the message queue
public func reset() {
public func reset() async {
concurrencyQueue.sync {
registeredLogs = [:]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extension AWSAPIPlugin: Resettable {
authService = nil

reachabilityMapLock.execute {
reachabilityMap.removeAll()
reachabilityMap.removeAll()
}

subscriptionConnectionFactory = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
import XCTest
@testable import AWSAPIPlugin

class AWSAPICategoryPluginResetTests: AWSAPICategoryPluginTestBase {

func testReset() async {
await apiPlugin.reset()
let resettable = apiPlugin as Resettable
await resettable.reset()

XCTAssertNotNil(apiPlugin.mapper)
XCTAssertEqual(apiPlugin.mapper.operations.count, 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation

extension AWSPinpointAnalyticsPlugin {
/// Resets the state of the plugin
public func reset() {
public func reset() async {
if pinpoint != nil {
pinpoint = nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
@_spi(InternalAWSPinpoint) import InternalAWSPinpoint
@testable import AWSPinpointAnalyticsPlugin
import XCTest

class AWSPinpointAnalyticsPluginResetTests: AWSPinpointAnalyticsPluginTestBase {
func testReset() {
analyticsPlugin.reset()
func testReset() async {
let resettable = analyticsPlugin as Resettable
await resettable.reset()

XCTAssertNil(analyticsPlugin.pinpoint)
XCTAssertNil(analyticsPlugin.globalProperties)
XCTAssertNil(analyticsPlugin.isEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class AWSPinpointAnalyticsPluginTestBase: XCTestCase {

override func tearDown() async throws {
await Amplify.reset()
analyticsPlugin.reset()
let resettable = analyticsPlugin as Resettable
await resettable.reset()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ final class AWSInitialSyncOrchestrator: InitialSyncOrchestrator {
extension AWSInitialSyncOrchestrator: DefaultLogger { }

extension AWSInitialSyncOrchestrator: Resettable {
func reset() {
func reset() async {
syncOperationQueue.cancelAllOperations()
syncOperationQueue.waitUntilAllOperationsAreFinished()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extension AWSMutationDatabaseAdapter: DefaultLogger { }

extension AWSMutationDatabaseAdapter: Resettable {

func reset() {
func reset() async {
log.verbose("Resetting AWSMutationDatabaseAdapter")
storageAdapter = nil
nextEventPromise.set(nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ extension AWSMutationEventPublisher: MutationEventPublisher {
extension AWSMutationEventPublisher: DefaultLogger { }

extension AWSMutationEventPublisher: Resettable {
func reset() {
func reset() async {
eventSource = nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ extension OutgoingMutationQueue: Subscriber {
}

extension OutgoingMutationQueue: Resettable {
func reset() {
func reset() async {
doStopWithoutNotifyingStateMachine()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ final class AWSIncomingSubscriptionEventPublisher: IncomingSubscriptionEventPubl
// MARK: Resettable
extension AWSIncomingSubscriptionEventPublisher: Resettable {

func reset() {
func reset() async {
Amplify.log.verbose("Resetting asyncEvents")
asyncEvents.reset()
Amplify.log.verbose("Resetting asyncEvents: finished")

Amplify.log.verbose("Resetting mapper")
mapper.reset()
await mapper.reset()
Amplify.log.verbose("Resetting mapper: finished")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ final class IncomingAsyncSubscriptionEventToAnyModelMapper: Subscriber, AmplifyC
}

extension IncomingAsyncSubscriptionEventToAnyModelMapper: Resettable {
func reset() {
func reset() async {
log.verbose("Resetting modelsFromSubscription and subscription")
modelsFromSubscription.send(completion: .finished)
subscription?.cancel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension AWSLocationGeoPlugin {
///
/// Sets stored objects to nil to allow deallocation, then calls onComplete closure
/// to signal the reset has completed.
public func reset() {
public func reset() async {
locationService = nil
authService = nil
pluginConfig = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ class AWSLocationGeoPluginConfigureTests: AWSLocationGeoPluginTestBase {

// MARK: - Configuration tests

func testConfigureSuccess() {
geoPlugin.reset()
func testConfigureSuccess() async {
let resettable = geoPlugin as Resettable
await resettable.reset()

do {
try geoPlugin.configure(using: GeoPluginTestConfig.geoPluginConfigJSON)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
@testable import AWSLocationGeoPlugin
import XCTest

class AWSLocationGeoPluginResetTests: AWSLocationGeoPluginTestBase {
func testReset() async {
geoPlugin.reset()
let resettable = geoPlugin as Resettable
await resettable.reset()
XCTAssertNil(geoPlugin.locationService)
XCTAssertNil(geoPlugin.authService)
XCTAssertNil(geoPlugin.pluginConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class AWSLocationGeoPluginTestBase: XCTestCase {

override func tearDown() async throws {
await Amplify.reset()
geoPlugin.reset()
let resettable = geoPlugin as Resettable
await resettable.reset()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

extension AWSPinpointPushNotificationsPlugin {
public func reset() {
public func reset() async {
if pinpoint != nil {
pinpoint = nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
@testable import AWSPinpointPushNotificationsPlugin
import XCTest

class AWSPinpointPushNotificationsPluginResetTests: AWSPinpointPushNotificationsPluginTestBase {
func testReset_shouldResetValues() {
plugin.reset()
func testReset_shouldResetValues() async {
let resettable = plugin as Resettable
await resettable.reset()

XCTAssertNil(plugin.pinpoint)
XCTAssertTrue(plugin.options.isEmpty)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AWSPinpointPushNotificationsPluginTestBase: XCTestCase {
}

override func tearDown() async throws {
plugin.reset()
let resettable = plugin as Resettable
await resettable.reset()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ import Amplify
extension AWSPredictionsPlugin {
public func reset() async {
if predictionsService != nil {
predictionsService.reset()
let resettable = predictionsService as Resettable
await resettable.reset()
predictionsService = nil
}

if authService != nil {
if let resettable = authService as? Resettable {
await resettable.reset()
}
authService = nil
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Amplify

extension AWSPredictionsService: Resettable {
func reset() async {
awsTranslate = nil
awsRekognition = nil
awsTextract = nil
awsComprehend = nil
awsPolly = nil
awsTranscribeStreaming = nil
identifier = nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,6 @@ class AWSPredictionsService {
self.predictionsConfig = configuration
}

func reset() {
awsTranslate = nil
awsRekognition = nil
awsTextract = nil
awsComprehend = nil
awsPolly = nil
awsTranscribeStreaming = nil
identifier = nil
}

func getEscapeHatch<T>(client: PredictionsAWSService<T>) -> T {
client.fetch(self)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extension AWSS3StoragePlugin {
/// storage service, authentication service, and queue to nil to allow deallocation.
///
/// - Tag: AWSS3StoragePlugin.reset
public func reset() {
public func reset() async {
if storageService != nil {
storageService.reset()
storageService = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
import XCTest
@testable import AWSS3StoragePlugin

class AWSS3StoragePluginResetTests: AWSS3StoragePluginTests {

func testReset() {
storagePlugin.reset()
func testReset() async {
let resettable = storagePlugin as Resettable
await resettable.reset()

XCTAssertNil(storagePlugin.authService)
XCTAssertNil(storagePlugin.storageService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class AWSS3StorageServiceTestBase: XCTestCase {
}
func testReset() {
func testReset() async {
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class APICategoryConfigurationTests: XCTestCase {

try Amplify.configure(amplifyConfig)
await Amplify.reset()
await waitForExpectations(timeout: 1.0)
await fulfillment(of: [resetWasInvoked], timeout: 1.0)
}

func testResetRemovesAddedPlugin() async throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class AnalyticsCategoryConfigurationTests: XCTestCase {

try Amplify.configure(amplifyConfig)
await Amplify.reset()
await waitForExpectations(timeout: 1.0)
await fulfillment(of: [resetWasInvoked], timeout: 1.0)
}

func testResetRemovesAddedPlugin() async throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class AuthCategoryConfigurationTests: XCTestCase {

try Amplify.configure(amplifyConfig)
await Amplify.reset()
await waitForExpectations(timeout: 1.0)
await fulfillment(of: [resetWasInvoked], timeout: 1.0)
}

/// Test whether calling reset removes the plugin added
Expand Down
Loading

0 comments on commit 27278f7

Please sign in to comment.