From d9fc3df27bf73c1223f1c2f9a05e6290f980695e Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Sat, 14 Mar 2020 11:38:03 +0100 Subject: [PATCH 1/4] Moved Foundation to FoundationCompat lib --- Package.swift | 12 +++++++--- Sources/AWSLambdaRuntime/Lambda.swift | 4 ++-- .../LambdaConfiguration.swift | 24 +++++++++---------- .../Context+Foundation.swift | 23 ++++++++++++++++++ .../Lambda+Codable.swift | 3 ++- Sources/AWSLambdaTesting/Lambda+Testing.swift | 1 + Sources/CodableSample/main.swift | 3 ++- .../Lambda+CodeableTest.swift | 1 + 8 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeFoundationCompat}/Lambda+Codable.swift (98%) diff --git a/Package.swift b/Package.swift index 624cf6b5..38e09dd4 100644 --- a/Package.swift +++ b/Package.swift @@ -10,6 +10,8 @@ let package = Package( products: [ // core library .library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]), + // foundaation utils for the core library + .library(name: "AWSLambdaRuntimeFoundationCompat", targets: ["AWSLambdaRuntimeFoundationCompat"]), // common AWS events .library(name: "AWSLambdaEvents", targets: ["AWSLambdaEvents"]), // for testing only @@ -25,9 +27,13 @@ let package = Package( .product(name: "Logging", package: "swift-log"), .product(name: "Backtrace", package: "swift-backtrace"), .product(name: "NIOHTTP1", package: "swift-nio"), + ]), + .target(name: "AWSLambdaRuntimeFoundationCompat", dependencies: [ + .byName(name: "AWSLambdaRuntime"), + .product(name: "NIO", package: "swift-nio"), .product(name: "NIOFoundationCompat", package: "swift-nio"), ]), - .testTarget(name: "AWSLambdaRuntimeTests", dependencies: ["AWSLambdaRuntime"]), + .testTarget(name: "AWSLambdaRuntimeTests", dependencies: ["AWSLambdaRuntime", "AWSLambdaRuntimeFoundationCompat"]), .target(name: "AWSLambdaEvents", dependencies: []), .testTarget(name: "AWSLambdaEventsTests", dependencies: ["AWSLambdaEvents"]), // testing helper @@ -35,10 +41,10 @@ let package = Package( "AWSLambdaRuntime", .product(name: "NIO", package: "swift-nio"), ]), - .testTarget(name: "AWSLambdaTestingTests", dependencies: ["AWSLambdaTesting"]), + .testTarget(name: "AWSLambdaTestingTests", dependencies: ["AWSLambdaTesting", "AWSLambdaRuntimeFoundationCompat"]), // samples .target(name: "StringSample", dependencies: ["AWSLambdaRuntime"]), - .target(name: "CodableSample", dependencies: ["AWSLambdaRuntime"]), + .target(name: "CodableSample", dependencies: ["AWSLambdaRuntime", "AWSLambdaRuntimeFoundationCompat"]), // perf tests .target(name: "MockServer", dependencies: [ .product(name: "NIOHTTP1", package: "swift-nio"), diff --git a/Sources/AWSLambdaRuntime/Lambda.swift b/Sources/AWSLambdaRuntime/Lambda.swift index 6e9fd9f0..0f2bb669 100644 --- a/Sources/AWSLambdaRuntime/Lambda.swift +++ b/Sources/AWSLambdaRuntime/Lambda.swift @@ -64,13 +64,13 @@ public enum Lambda { // for testing and internal use @discardableResult - internal static func run(configuration: Configuration = .init(), handler: Handler) -> Result { + public static func run(configuration: Configuration = .init(), handler: Handler) -> Result { self.run(configuration: configuration, factory: { $0.makeSucceededFuture(handler) }) } // for testing and internal use @discardableResult - internal static func run(configuration: Configuration = .init(), factory: @escaping (EventLoop) throws -> Handler) -> Result { + public static func run(configuration: Configuration = .init(), factory: @escaping (EventLoop) throws -> Handler) -> Result { self.run(configuration: configuration, factory: { eventloop -> EventLoopFuture in do { let handler = try factory(eventloop) diff --git a/Sources/AWSLambdaRuntime/LambdaConfiguration.swift b/Sources/AWSLambdaRuntime/LambdaConfiguration.swift index 44352d2f..0979f97c 100644 --- a/Sources/AWSLambdaRuntime/LambdaConfiguration.swift +++ b/Sources/AWSLambdaRuntime/LambdaConfiguration.swift @@ -17,12 +17,12 @@ import Logging import NIO extension Lambda { - internal struct Configuration: CustomStringConvertible { - let general: General - let lifecycle: Lifecycle - let runtimeEngine: RuntimeEngine + public struct Configuration: CustomStringConvertible { + public let general: General + public let lifecycle: Lifecycle + public let runtimeEngine: RuntimeEngine - init() { + public init() { self.init(general: .init(), lifecycle: .init(), runtimeEngine: .init()) } @@ -32,19 +32,19 @@ extension Lambda { self.runtimeEngine = runtimeEngine ?? RuntimeEngine() } - struct General: CustomStringConvertible { + public struct General: CustomStringConvertible { let logLevel: Logger.Level init(logLevel: Logger.Level? = nil) { self.logLevel = logLevel ?? env("LOG_LEVEL").flatMap(Logger.Level.init) ?? .info } - var description: String { + public var description: String { "\(General.self)(logLevel: \(self.logLevel))" } } - struct Lifecycle: CustomStringConvertible { + public struct Lifecycle: CustomStringConvertible { let id: String let maxTimes: Int let stopSignal: Signal @@ -56,12 +56,12 @@ extension Lambda { precondition(self.maxTimes >= 0, "maxTimes must be equal or larger than 0") } - var description: String { + public var description: String { "\(Lifecycle.self)(id: \(self.id), maxTimes: \(self.maxTimes), stopSignal: \(self.stopSignal))" } } - struct RuntimeEngine: CustomStringConvertible { + public struct RuntimeEngine: CustomStringConvertible { let ip: String let port: Int let keepAlive: Bool @@ -78,12 +78,12 @@ extension Lambda { self.requestTimeout = requestTimeout ?? env("REQUEST_TIMEOUT").flatMap(Int64.init).flatMap { .milliseconds($0) } } - var description: String { + public var description: String { "\(RuntimeEngine.self)(ip: \(self.ip), port: \(self.port), keepAlive: \(self.keepAlive), requestTimeout: \(String(describing: self.requestTimeout))" } } - var description: String { + public var description: String { "\(Configuration.self)\n \(self.general))\n \(self.lifecycle)\n \(self.runtimeEngine)" } } diff --git a/Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift b/Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift new file mode 100644 index 00000000..d22c3173 --- /dev/null +++ b/Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftAWSLambdaRuntime open source project +// +// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import AWSLambdaRuntime +import Foundation + +extension Lambda.Context { + var deadlineDate: Date { + let secondsSinceEpoch = Double(Int64(bitPattern: self.deadline.rawValue)) / -1_000_000_000 + return Date(timeIntervalSince1970: secondsSinceEpoch) + } +} diff --git a/Sources/AWSLambdaRuntime/Lambda+Codable.swift b/Sources/AWSLambdaRuntimeFoundationCompat/Lambda+Codable.swift similarity index 98% rename from Sources/AWSLambdaRuntime/Lambda+Codable.swift rename to Sources/AWSLambdaRuntimeFoundationCompat/Lambda+Codable.swift index e24e736d..c8c5bde9 100644 --- a/Sources/AWSLambdaRuntime/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntimeFoundationCompat/Lambda+Codable.swift @@ -2,7 +2,7 @@ // // This source file is part of the SwiftAWSLambdaRuntime open source project // -// Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import AWSLambdaRuntime import class Foundation.JSONDecoder import class Foundation.JSONEncoder import NIO diff --git a/Sources/AWSLambdaTesting/Lambda+Testing.swift b/Sources/AWSLambdaTesting/Lambda+Testing.swift index d8b2b125..f781afd6 100644 --- a/Sources/AWSLambdaTesting/Lambda+Testing.swift +++ b/Sources/AWSLambdaTesting/Lambda+Testing.swift @@ -17,6 +17,7 @@ // @testable is used to access of internal functions #if DEBUG @testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeFoundationCompat import Dispatch import Logging import NIO diff --git a/Sources/CodableSample/main.swift b/Sources/CodableSample/main.swift index eb985f41..a52e6d41 100644 --- a/Sources/CodableSample/main.swift +++ b/Sources/CodableSample/main.swift @@ -2,7 +2,7 @@ // // This source file is part of the SwiftAWSLambdaRuntime open source project // -// Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// import AWSLambdaRuntime +import AWSLambdaRuntimeFoundationCompat import NIO struct Request: Codable { diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift index 1d4b79dc..04f2f50b 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift +++ b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// @testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeFoundationCompat import NIO import XCTest From 7ca386322e7f4c625fbf33c6d9255853283c01bd Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Thu, 7 May 2020 10:10:43 +0200 Subject: [PATCH 2/4] The grand rename --- Package.swift | 32 ++++++++++++------- .../Context+Foundation.swift | 4 +-- .../Lambda+Codable.swift | 2 +- .../HTTPClient.swift | 0 .../Lambda+String.swift | 0 .../Lambda.swift | 0 .../LambdaConfiguration.swift | 0 .../LambdaContext.swift | 0 .../LambdaHandler.swift | 0 .../LambdaLifecycle.swift | 0 .../LambdaRunner.swift | 0 .../LambdaRuntimeClient.swift | 0 .../Utils.swift | 0 Sources/AWSLambdaTesting/Lambda+Testing.swift | 2 +- Sources/CodableSample/main.swift | 1 - Sources/StringSample/main.swift | 2 +- .../Lambda+CodeableTest.swift | 2 +- .../Lambda+StringTest.swift | 1 + .../LambdaRunnerTest.swift | 2 +- .../LambdaRuntimeClientTest.swift | 1 + Tests/AWSLambdaRuntimeTests/LambdaTest.swift | 1 + .../MockLambdaServer.swift | 2 +- Tests/AWSLambdaRuntimeTests/Utils.swift | 1 + 23 files changed, 33 insertions(+), 20 deletions(-) rename Sources/{AWSLambdaRuntimeFoundationCompat => AWSLambdaRuntime}/Context+Foundation.swift (92%) rename Sources/{AWSLambdaRuntimeFoundationCompat => AWSLambdaRuntime}/Lambda+Codable.swift (99%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/HTTPClient.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/Lambda+String.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/Lambda.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/LambdaConfiguration.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/LambdaContext.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/LambdaHandler.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/LambdaLifecycle.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/LambdaRunner.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/LambdaRuntimeClient.swift (100%) rename Sources/{AWSLambdaRuntime => AWSLambdaRuntimeCore}/Utils.swift (100%) diff --git a/Package.swift b/Package.swift index 38e09dd4..f0d13c6b 100644 --- a/Package.swift +++ b/Package.swift @@ -8,10 +8,10 @@ let package = Package( .macOS(.v10_13), ], products: [ - // core library + // this library exports `AWSLambdaRuntimeCore` and adds Foundation convenience methods .library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]), - // foundaation utils for the core library - .library(name: "AWSLambdaRuntimeFoundationCompat", targets: ["AWSLambdaRuntimeFoundationCompat"]), + // this has all the main functionality for lambda and it does not link Foundation + .library(name: "AWSLambdaRuntimeCore", targets: ["AWSLambdaRuntimeCore"]), // common AWS events .library(name: "AWSLambdaEvents", targets: ["AWSLambdaEvents"]), // for testing only @@ -24,27 +24,37 @@ let package = Package( ], targets: [ .target(name: "AWSLambdaRuntime", dependencies: [ + .byName(name: "AWSLambdaRuntimeCore"), + .product(name: "NIO", package: "swift-nio"), + .product(name: "NIOFoundationCompat", package: "swift-nio"), + ]), + .target(name: "AWSLambdaRuntimeCore", dependencies: [ .product(name: "Logging", package: "swift-log"), .product(name: "Backtrace", package: "swift-backtrace"), .product(name: "NIOHTTP1", package: "swift-nio"), ]), - .target(name: "AWSLambdaRuntimeFoundationCompat", dependencies: [ + .testTarget(name: "AWSLambdaRuntimeTests", dependencies: [ + .byName(name: "AWSLambdaRuntimeCore"), .byName(name: "AWSLambdaRuntime"), - .product(name: "NIO", package: "swift-nio"), - .product(name: "NIOFoundationCompat", package: "swift-nio"), ]), - .testTarget(name: "AWSLambdaRuntimeTests", dependencies: ["AWSLambdaRuntime", "AWSLambdaRuntimeFoundationCompat"]), .target(name: "AWSLambdaEvents", dependencies: []), .testTarget(name: "AWSLambdaEventsTests", dependencies: ["AWSLambdaEvents"]), // testing helper .target(name: "AWSLambdaTesting", dependencies: [ - "AWSLambdaRuntime", + .byName(name: "AWSLambdaRuntime"), .product(name: "NIO", package: "swift-nio"), ]), - .testTarget(name: "AWSLambdaTestingTests", dependencies: ["AWSLambdaTesting", "AWSLambdaRuntimeFoundationCompat"]), + .testTarget(name: "AWSLambdaTestingTests", dependencies: [ + .byName(name: "AWSLambdaTesting"), + .byName(name: "AWSLambdaRuntime"), + ]), // samples - .target(name: "StringSample", dependencies: ["AWSLambdaRuntime"]), - .target(name: "CodableSample", dependencies: ["AWSLambdaRuntime", "AWSLambdaRuntimeFoundationCompat"]), + .target(name: "StringSample", dependencies: [ + .byName(name: "AWSLambdaRuntime"), + ]), + .target(name: "CodableSample", dependencies: [ + .byName(name: "AWSLambdaRuntime"), + ]), // perf tests .target(name: "MockServer", dependencies: [ .product(name: "NIOHTTP1", package: "swift-nio"), diff --git a/Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift b/Sources/AWSLambdaRuntime/Context+Foundation.swift similarity index 92% rename from Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift rename to Sources/AWSLambdaRuntime/Context+Foundation.swift index d22c3173..0aa1c019 100644 --- a/Sources/AWSLambdaRuntimeFoundationCompat/Context+Foundation.swift +++ b/Sources/AWSLambdaRuntime/Context+Foundation.swift @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -import AWSLambdaRuntime -import Foundation +import AWSLambdaRuntimeCore +import struct Foundation.Date extension Lambda.Context { var deadlineDate: Date { diff --git a/Sources/AWSLambdaRuntimeFoundationCompat/Lambda+Codable.swift b/Sources/AWSLambdaRuntime/Lambda+Codable.swift similarity index 99% rename from Sources/AWSLambdaRuntimeFoundationCompat/Lambda+Codable.swift rename to Sources/AWSLambdaRuntime/Lambda+Codable.swift index c8c5bde9..70d64d92 100644 --- a/Sources/AWSLambdaRuntimeFoundationCompat/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntime/Lambda+Codable.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -import AWSLambdaRuntime +@_exported import AWSLambdaRuntimeCore import class Foundation.JSONDecoder import class Foundation.JSONEncoder import NIO diff --git a/Sources/AWSLambdaRuntime/HTTPClient.swift b/Sources/AWSLambdaRuntimeCore/HTTPClient.swift similarity index 100% rename from Sources/AWSLambdaRuntime/HTTPClient.swift rename to Sources/AWSLambdaRuntimeCore/HTTPClient.swift diff --git a/Sources/AWSLambdaRuntime/Lambda+String.swift b/Sources/AWSLambdaRuntimeCore/Lambda+String.swift similarity index 100% rename from Sources/AWSLambdaRuntime/Lambda+String.swift rename to Sources/AWSLambdaRuntimeCore/Lambda+String.swift diff --git a/Sources/AWSLambdaRuntime/Lambda.swift b/Sources/AWSLambdaRuntimeCore/Lambda.swift similarity index 100% rename from Sources/AWSLambdaRuntime/Lambda.swift rename to Sources/AWSLambdaRuntimeCore/Lambda.swift diff --git a/Sources/AWSLambdaRuntime/LambdaConfiguration.swift b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift similarity index 100% rename from Sources/AWSLambdaRuntime/LambdaConfiguration.swift rename to Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift diff --git a/Sources/AWSLambdaRuntime/LambdaContext.swift b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift similarity index 100% rename from Sources/AWSLambdaRuntime/LambdaContext.swift rename to Sources/AWSLambdaRuntimeCore/LambdaContext.swift diff --git a/Sources/AWSLambdaRuntime/LambdaHandler.swift b/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift similarity index 100% rename from Sources/AWSLambdaRuntime/LambdaHandler.swift rename to Sources/AWSLambdaRuntimeCore/LambdaHandler.swift diff --git a/Sources/AWSLambdaRuntime/LambdaLifecycle.swift b/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift similarity index 100% rename from Sources/AWSLambdaRuntime/LambdaLifecycle.swift rename to Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift diff --git a/Sources/AWSLambdaRuntime/LambdaRunner.swift b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift similarity index 100% rename from Sources/AWSLambdaRuntime/LambdaRunner.swift rename to Sources/AWSLambdaRuntimeCore/LambdaRunner.swift diff --git a/Sources/AWSLambdaRuntime/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift similarity index 100% rename from Sources/AWSLambdaRuntime/LambdaRuntimeClient.swift rename to Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift diff --git a/Sources/AWSLambdaRuntime/Utils.swift b/Sources/AWSLambdaRuntimeCore/Utils.swift similarity index 100% rename from Sources/AWSLambdaRuntime/Utils.swift rename to Sources/AWSLambdaRuntimeCore/Utils.swift diff --git a/Sources/AWSLambdaTesting/Lambda+Testing.swift b/Sources/AWSLambdaTesting/Lambda+Testing.swift index f781afd6..da14faa1 100644 --- a/Sources/AWSLambdaTesting/Lambda+Testing.swift +++ b/Sources/AWSLambdaTesting/Lambda+Testing.swift @@ -17,7 +17,7 @@ // @testable is used to access of internal functions #if DEBUG @testable import AWSLambdaRuntime -@testable import AWSLambdaRuntimeFoundationCompat +@testable import AWSLambdaRuntimeCore import Dispatch import Logging import NIO diff --git a/Sources/CodableSample/main.swift b/Sources/CodableSample/main.swift index a52e6d41..34e845b1 100644 --- a/Sources/CodableSample/main.swift +++ b/Sources/CodableSample/main.swift @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// import AWSLambdaRuntime -import AWSLambdaRuntimeFoundationCompat import NIO struct Request: Codable { diff --git a/Sources/StringSample/main.swift b/Sources/StringSample/main.swift index fddfa478..c7d0434a 100644 --- a/Sources/StringSample/main.swift +++ b/Sources/StringSample/main.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -import AWSLambdaRuntime +import AWSLambdaRuntimeCore import NIO // in this example we are receiving and responding with strings diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift index 04f2f50b..a444a4ee 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift +++ b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// @testable import AWSLambdaRuntime -@testable import AWSLambdaRuntimeFoundationCompat +@testable import AWSLambdaRuntimeCore import NIO import XCTest diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift b/Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift index 9eebf2d2..3b8c4efd 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift +++ b/Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// @testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeCore import NIO import XCTest diff --git a/Tests/AWSLambdaRuntimeTests/LambdaRunnerTest.swift b/Tests/AWSLambdaRuntimeTests/LambdaRunnerTest.swift index 71707681..f91bde4a 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaRunnerTest.swift +++ b/Tests/AWSLambdaRuntimeTests/LambdaRunnerTest.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -@testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeCore import XCTest class LambdaRunnerTest: XCTestCase { diff --git a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift b/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift index f0b7c17d..dc45d0b8 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift +++ b/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// @testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeCore import XCTest class LambdaRuntimeClientTest: XCTestCase { diff --git a/Tests/AWSLambdaRuntimeTests/LambdaTest.swift b/Tests/AWSLambdaRuntimeTests/LambdaTest.swift index 6ff75fc1..763e6a21 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaTest.swift +++ b/Tests/AWSLambdaRuntimeTests/LambdaTest.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// @testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeCore import Logging import NIO import XCTest diff --git a/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift b/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift index 595ee011..b2f671a6 100644 --- a/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift +++ b/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -@testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeCore import Foundation // for JSON import Logging import NIO diff --git a/Tests/AWSLambdaRuntimeTests/Utils.swift b/Tests/AWSLambdaRuntimeTests/Utils.swift index 8cf46b6b..03377f94 100644 --- a/Tests/AWSLambdaRuntimeTests/Utils.swift +++ b/Tests/AWSLambdaRuntimeTests/Utils.swift @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// @testable import AWSLambdaRuntime +@testable import AWSLambdaRuntimeCore import Logging import NIO import XCTest From 26ee7f96ab4fe076d9aeb8e6b6d7efb12abb00da Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Thu, 7 May 2020 10:29:40 +0200 Subject: [PATCH 3/4] Reduced public exposure. --- Package.swift | 3 +++ Sources/AWSLambdaRuntime/Lambda+Codable.swift | 26 +++++++++---------- Sources/AWSLambdaRuntimeCore/Lambda.swift | 4 +-- .../LambdaConfiguration.swift | 24 ++++++++--------- .../Lambda+StringTest.swift | 1 - .../LambdaRunnerTest.swift | 0 .../LambdaRuntimeClientTest.swift | 1 - .../LambdaTest.swift | 1 - .../MockLambdaServer.swift | 0 .../Utils.swift | 1 - .../Lambda+CodeableTest.swift | 2 ++ 11 files changed, 32 insertions(+), 31 deletions(-) rename Tests/{AWSLambdaRuntimeTests => AWSLambdaRuntimeCoreTests}/Lambda+StringTest.swift (99%) rename Tests/{AWSLambdaRuntimeTests => AWSLambdaRuntimeCoreTests}/LambdaRunnerTest.swift (100%) rename Tests/{AWSLambdaRuntimeTests => AWSLambdaRuntimeCoreTests}/LambdaRuntimeClientTest.swift (99%) rename Tests/{AWSLambdaRuntimeTests => AWSLambdaRuntimeCoreTests}/LambdaTest.swift (99%) rename Tests/{AWSLambdaRuntimeTests => AWSLambdaRuntimeCoreTests}/MockLambdaServer.swift (100%) rename Tests/{AWSLambdaRuntimeTests => AWSLambdaRuntimeCoreTests}/Utils.swift (99%) diff --git a/Package.swift b/Package.swift index f0d13c6b..94353929 100644 --- a/Package.swift +++ b/Package.swift @@ -33,6 +33,9 @@ let package = Package( .product(name: "Backtrace", package: "swift-backtrace"), .product(name: "NIOHTTP1", package: "swift-nio"), ]), + .testTarget(name: "AWSLambdaRuntimeCoreTests", dependencies: [ + .byName(name: "AWSLambdaRuntimeCore"), + ]), .testTarget(name: "AWSLambdaRuntimeTests", dependencies: [ .byName(name: "AWSLambdaRuntimeCore"), .byName(name: "AWSLambdaRuntime"), diff --git a/Sources/AWSLambdaRuntime/Lambda+Codable.swift b/Sources/AWSLambdaRuntime/Lambda+Codable.swift index 70d64d92..490553e7 100644 --- a/Sources/AWSLambdaRuntime/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntime/Lambda+Codable.swift @@ -30,7 +30,7 @@ extension Lambda { /// /// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine. public static func run(_ closure: @escaping CodableClosure) { - self.run(closure: closure) + self.run(CodableClosureWrapper(closure)) } /// An asynchronous Lambda Closure that takes a `In: Decodable` and returns a `Result` via a completion handler. @@ -43,20 +43,20 @@ extension Lambda { /// /// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine. public static func run(_ closure: @escaping CodableVoidClosure) { - self.run(closure: closure) + self.run(CodableVoidClosureWrapper(closure)) } - // for testing - @discardableResult - internal static func run(configuration: Configuration = .init(), closure: @escaping CodableClosure) -> Result { - self.run(configuration: configuration, handler: CodableClosureWrapper(closure)) - } - - // for testing - @discardableResult - internal static func run(configuration: Configuration = .init(), closure: @escaping CodableVoidClosure) -> Result { - self.run(configuration: configuration, handler: CodableVoidClosureWrapper(closure)) - } +// // for testing +// @discardableResult +// internal static func run(configuration: Configuration = .init(), closure: @escaping CodableClosure) -> Result { +// self.run(configuration: configuration, handler: ) +// } +// +// // for testing +// @discardableResult +// internal static func run(configuration: Configuration = .init(), closure: @escaping CodableVoidClosure) -> Result { +// self.run(configuration: configuration, handler: CodableVoidClosureWrapper(closure)) +// } } internal struct CodableClosureWrapper: LambdaHandler { diff --git a/Sources/AWSLambdaRuntimeCore/Lambda.swift b/Sources/AWSLambdaRuntimeCore/Lambda.swift index 0f2bb669..6e9fd9f0 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda.swift @@ -64,13 +64,13 @@ public enum Lambda { // for testing and internal use @discardableResult - public static func run(configuration: Configuration = .init(), handler: Handler) -> Result { + internal static func run(configuration: Configuration = .init(), handler: Handler) -> Result { self.run(configuration: configuration, factory: { $0.makeSucceededFuture(handler) }) } // for testing and internal use @discardableResult - public static func run(configuration: Configuration = .init(), factory: @escaping (EventLoop) throws -> Handler) -> Result { + internal static func run(configuration: Configuration = .init(), factory: @escaping (EventLoop) throws -> Handler) -> Result { self.run(configuration: configuration, factory: { eventloop -> EventLoopFuture in do { let handler = try factory(eventloop) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift index 0979f97c..44352d2f 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift @@ -17,12 +17,12 @@ import Logging import NIO extension Lambda { - public struct Configuration: CustomStringConvertible { - public let general: General - public let lifecycle: Lifecycle - public let runtimeEngine: RuntimeEngine + internal struct Configuration: CustomStringConvertible { + let general: General + let lifecycle: Lifecycle + let runtimeEngine: RuntimeEngine - public init() { + init() { self.init(general: .init(), lifecycle: .init(), runtimeEngine: .init()) } @@ -32,19 +32,19 @@ extension Lambda { self.runtimeEngine = runtimeEngine ?? RuntimeEngine() } - public struct General: CustomStringConvertible { + struct General: CustomStringConvertible { let logLevel: Logger.Level init(logLevel: Logger.Level? = nil) { self.logLevel = logLevel ?? env("LOG_LEVEL").flatMap(Logger.Level.init) ?? .info } - public var description: String { + var description: String { "\(General.self)(logLevel: \(self.logLevel))" } } - public struct Lifecycle: CustomStringConvertible { + struct Lifecycle: CustomStringConvertible { let id: String let maxTimes: Int let stopSignal: Signal @@ -56,12 +56,12 @@ extension Lambda { precondition(self.maxTimes >= 0, "maxTimes must be equal or larger than 0") } - public var description: String { + var description: String { "\(Lifecycle.self)(id: \(self.id), maxTimes: \(self.maxTimes), stopSignal: \(self.stopSignal))" } } - public struct RuntimeEngine: CustomStringConvertible { + struct RuntimeEngine: CustomStringConvertible { let ip: String let port: Int let keepAlive: Bool @@ -78,12 +78,12 @@ extension Lambda { self.requestTimeout = requestTimeout ?? env("REQUEST_TIMEOUT").flatMap(Int64.init).flatMap { .milliseconds($0) } } - public var description: String { + var description: String { "\(RuntimeEngine.self)(ip: \(self.ip), port: \(self.port), keepAlive: \(self.keepAlive), requestTimeout: \(String(describing: self.requestTimeout))" } } - public var description: String { + var description: String { "\(Configuration.self)\n \(self.general))\n \(self.lifecycle)\n \(self.runtimeEngine)" } } diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift b/Tests/AWSLambdaRuntimeCoreTests/Lambda+StringTest.swift similarity index 99% rename from Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift rename to Tests/AWSLambdaRuntimeCoreTests/Lambda+StringTest.swift index 3b8c4efd..a0be16d6 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+StringTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/Lambda+StringTest.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -@testable import AWSLambdaRuntime @testable import AWSLambdaRuntimeCore import NIO import XCTest diff --git a/Tests/AWSLambdaRuntimeTests/LambdaRunnerTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaRunnerTest.swift similarity index 100% rename from Tests/AWSLambdaRuntimeTests/LambdaRunnerTest.swift rename to Tests/AWSLambdaRuntimeCoreTests/LambdaRunnerTest.swift diff --git a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift similarity index 99% rename from Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift rename to Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift index dc45d0b8..ea3e279d 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -@testable import AWSLambdaRuntime @testable import AWSLambdaRuntimeCore import XCTest diff --git a/Tests/AWSLambdaRuntimeTests/LambdaTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift similarity index 99% rename from Tests/AWSLambdaRuntimeTests/LambdaTest.swift rename to Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift index 763e6a21..60cc2e9a 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -@testable import AWSLambdaRuntime @testable import AWSLambdaRuntimeCore import Logging import NIO diff --git a/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift b/Tests/AWSLambdaRuntimeCoreTests/MockLambdaServer.swift similarity index 100% rename from Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift rename to Tests/AWSLambdaRuntimeCoreTests/MockLambdaServer.swift diff --git a/Tests/AWSLambdaRuntimeTests/Utils.swift b/Tests/AWSLambdaRuntimeCoreTests/Utils.swift similarity index 99% rename from Tests/AWSLambdaRuntimeTests/Utils.swift rename to Tests/AWSLambdaRuntimeCoreTests/Utils.swift index 03377f94..11e6004e 100644 --- a/Tests/AWSLambdaRuntimeTests/Utils.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/Utils.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -@testable import AWSLambdaRuntime @testable import AWSLambdaRuntimeCore import Logging import NIO diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift index a444a4ee..c40367d0 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift +++ b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#if false @testable import AWSLambdaRuntime @testable import AWSLambdaRuntimeCore import NIO @@ -279,3 +280,4 @@ private struct Response: Codable { self.requestId = requestId } } +#endif From ede1bed684209b269d597f533db126fb97900821 Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Thu, 7 May 2020 10:50:50 +0200 Subject: [PATCH 4/4] Reduce tests to what is possible without broadening public API surface --- Sources/AWSLambdaRuntime/Lambda+Codable.swift | 12 - .../Lambda+CodeableTest.swift | 276 +++--------------- 2 files changed, 42 insertions(+), 246 deletions(-) diff --git a/Sources/AWSLambdaRuntime/Lambda+Codable.swift b/Sources/AWSLambdaRuntime/Lambda+Codable.swift index 490553e7..23743a98 100644 --- a/Sources/AWSLambdaRuntime/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntime/Lambda+Codable.swift @@ -45,18 +45,6 @@ extension Lambda { public static func run(_ closure: @escaping CodableVoidClosure) { self.run(CodableVoidClosureWrapper(closure)) } - -// // for testing -// @discardableResult -// internal static func run(configuration: Configuration = .init(), closure: @escaping CodableClosure) -> Result { -// self.run(configuration: configuration, handler: ) -// } -// -// // for testing -// @discardableResult -// internal static func run(configuration: Configuration = .init(), closure: @escaping CodableVoidClosure) -> Result { -// self.run(configuration: configuration, handler: CodableVoidClosureWrapper(closure)) -// } } internal struct CodableClosureWrapper: LambdaHandler { diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift index c40367d0..371783b5 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift +++ b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift @@ -12,272 +12,80 @@ // //===----------------------------------------------------------------------===// -#if false @testable import AWSLambdaRuntime @testable import AWSLambdaRuntimeCore +import Logging import NIO +import NIOFoundationCompat import XCTest class CodableLambdaTest: XCTestCase { - func testCallbackSuccess() { - let server = MockLambdaServer(behavior: Behavior()) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } + var eventLoopGroup: EventLoopGroup! + let allocator = ByteBufferAllocator() - struct Handler: LambdaHandler { - typealias In = Request - typealias Out = Response - - func handle(context: Lambda.Context, payload: Request, callback: (Result) -> Void) { - callback(.success(Response(requestId: payload.requestId))) - } - } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration, handler: Handler()) - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testVoidCallbackSuccess() { - let server = MockLambdaServer(behavior: Behavior(result: .success(nil))) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - struct Handler: LambdaHandler { - typealias In = Request - typealias Out = Void - - func handle(context: Lambda.Context, payload: Request, callback: (Result) -> Void) { - callback(.success(())) - } - } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration, handler: Handler()) - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testCallbackFailure() { - let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom")))) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - struct Handler: LambdaHandler { - typealias In = Request - typealias Out = Response - - func handle(context: Lambda.Context, payload: Request, callback: (Result) -> Void) { - callback(.failure(TestError("boom"))) - } - } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration, handler: Handler()) - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testEventLoopSuccess() { - let server = MockLambdaServer(behavior: Behavior()) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - struct Handler: EventLoopLambdaHandler { - typealias In = Request - typealias Out = Response - - func handle(context: Lambda.Context, payload: Request) -> EventLoopFuture { - context.eventLoop.makeSucceededFuture(Response(requestId: payload.requestId)) - } - } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration, handler: Handler()) - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testVoidEventLoopSuccess() { - let server = MockLambdaServer(behavior: Behavior(result: .success(nil))) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - struct Handler: EventLoopLambdaHandler { - typealias In = Request - typealias Out = Void - - func handle(context: Lambda.Context, payload: Request) -> EventLoopFuture { - context.eventLoop.makeSucceededFuture(()) - } - } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration, handler: Handler()) - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testEventLoopFailure() { - let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom")))) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - struct Handler: EventLoopLambdaHandler { - typealias In = Request - typealias Out = Response - - func handle(context: Lambda.Context, payload: Request) -> EventLoopFuture { - context.eventLoop.makeFailedFuture(TestError("boom")) - } - } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration, handler: Handler()) - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testClosureSuccess() { - let server = MockLambdaServer(behavior: Behavior()) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration) { (_, payload: Request, callback) in - callback(.success(Response(requestId: payload.requestId))) - } - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) + override func setUp() { + self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) } - func testVoidClosureSuccess() { - let server = MockLambdaServer(behavior: Behavior(result: .success(nil))) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result = Lambda.run(configuration: configuration) { (_, _: Request, callback: (Result) -> Void) in - callback(.success(())) - } - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) - } - - func testClosureFailure() { - let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom")))) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - let maxTimes = Int.random(in: 1 ... 10) - let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes)) - let result: Result = Lambda.run(configuration: configuration) { (_, _: Request, callback: (Result) -> Void) in - callback(.failure(TestError("boom"))) - } - assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes) + override func tearDown() { + try! self.eventLoopGroup.syncShutdownGracefully() } - func testBootstrapFailure() { - let server = MockLambdaServer(behavior: FailedBootstrapBehavior()) - XCTAssertNoThrow(try server.start().wait()) - defer { XCTAssertNoThrow(try server.stop().wait()) } - - struct Handler: LambdaHandler { - typealias In = Request - typealias Out = Response + func testCodableVoidClosureWrapper() { + let request = Request(requestId: UUID().uuidString) + var inputBuffer: ByteBuffer? + var outputBuffer: ByteBuffer? - init(eventLoop: EventLoop) throws { - throw TestError("kaboom") - } - - func handle(context: Lambda.Context, payload: Request, callback: (Result) -> Void) { - callback(.failure(TestError("should not be called"))) - } + let closureWrapper = CodableVoidClosureWrapper { (_, _: Request, completion) in + XCTAssertEqual(request, request) + completion(.success(())) } - let result = Lambda.run(factory: Handler.init) - assertLambdaLifecycleResult(result, shouldFailWithError: TestError("kaboom")) - } -} - -// TODO: taking advantage of the fact we know the serialization is json -private struct Behavior: LambdaServerBehavior { - let requestId: String - let payload: String - let result: Result - - init(requestId: String = UUID().uuidString, payload: String = "hello", result: Result = .success("hello")) { - self.requestId = requestId - self.payload = payload - self.result = result + XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator)) + XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), payload: XCTUnwrap(inputBuffer)).wait()) + XCTAssertNil(outputBuffer) } - func getInvocation() -> GetInvocationResult { - guard let payload = try? JSONEncoder().encode(Request(requestId: requestId)) else { - XCTFail("encoding error") - return .failure(.internalServerError) - } - guard let payloadAsString = String(data: payload, encoding: .utf8) else { - XCTFail("encoding error") - return .failure(.internalServerError) - } - return .success((requestId: self.requestId, payload: payloadAsString)) - } + func testCodableClosureWrapper() { + let request = Request(requestId: UUID().uuidString) + var inputBuffer: ByteBuffer? + var outputBuffer: ByteBuffer? + var response: Response? - func processResponse(requestId: String, response: String?) -> Result { - switch self.result { - case .success(let expected) where expected != nil: - guard let data = response?.data(using: .utf8) else { - XCTFail("decoding error") - return .failure(.internalServerError) - } - guard let response = try? JSONDecoder().decode(Response.self, from: data) else { - XCTFail("decoding error") - return .failure(.internalServerError) - } - XCTAssertEqual(self.requestId, response.requestId, "expecting requestId to match") - return .success(()) - case .success(let expected) where expected == nil: - XCTAssertNil(response) - return .success(()) - case .failure: - XCTFail("unexpected to fail, but succeeded with: \(response ?? "undefined")") - return .failure(.internalServerError) - default: - preconditionFailure("invalid state") + let closureWrapper = CodableClosureWrapper { (_, req: Request, completion: (Result) -> Void) in + XCTAssertEqual(request, request) + completion(.success(Response(requestId: req.requestId))) } - } - func processError(requestId: String, error: ErrorResponse) -> Result { - XCTAssertEqual(self.requestId, requestId, "expecting requestId to match") - switch self.result { - case .success: - XCTFail("unexpected to succeed, but failed with: \(error)") - return .failure(.internalServerError) - case .failure(let expected): - XCTAssertEqual(expected.description, error.errorMessage, "expecting error to match") - return .success(()) - } + XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator)) + XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), payload: XCTUnwrap(inputBuffer)).wait()) + XCTAssertNoThrow(response = try JSONDecoder().decode(Response.self, from: XCTUnwrap(outputBuffer))) + XCTAssertEqual(response?.requestId, request.requestId) } - func processInitError(error: ErrorResponse) -> Result { - XCTFail("should not report init error") - return .failure(.internalServerError) + // convencience method + func newContext() -> Lambda.Context { + Lambda.Context(requestId: UUID().uuidString, + traceId: "abc123", + invokedFunctionArn: "aws:arn:", + deadline: .now() + .seconds(3), + cognitoIdentity: nil, + clientContext: nil, + logger: Logger(label: "test"), + eventLoop: self.eventLoopGroup.next()) } } -private struct Request: Codable { +private struct Request: Codable, Equatable { let requestId: String init(requestId: String) { self.requestId = requestId } } -private struct Response: Codable { +private struct Response: Codable, Equatable { let requestId: String init(requestId: String) { self.requestId = requestId } } -#endif