Skip to content

Commit b96da08

Browse files
committed
Reduce tests to what is possible without broadening public API surface
1 parent e6b8fc4 commit b96da08

File tree

2 files changed

+42
-246
lines changed

2 files changed

+42
-246
lines changed

Sources/AWSLambdaRuntime/Lambda+Codable.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,6 @@ extension Lambda {
4545
public static func run<In: Decodable>(_ closure: @escaping CodableVoidClosure<In>) {
4646
self.run(CodableVoidClosureWrapper(closure))
4747
}
48-
49-
// // for testing
50-
// @discardableResult
51-
// internal static func run<In: Decodable, Out: Encodable>(configuration: Configuration = .init(), closure: @escaping CodableClosure<In, Out>) -> Result<Int, Error> {
52-
// self.run(configuration: configuration, handler: )
53-
// }
54-
//
55-
// // for testing
56-
// @discardableResult
57-
// internal static func run<In: Decodable>(configuration: Configuration = .init(), closure: @escaping CodableVoidClosure<In>) -> Result<Int, Error> {
58-
// self.run(configuration: configuration, handler: CodableVoidClosureWrapper(closure))
59-
// }
6048
}
6149

6250
internal struct CodableClosureWrapper<In: Decodable, Out: Encodable>: LambdaHandler {

Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift

Lines changed: 42 additions & 234 deletions
Original file line numberDiff line numberDiff line change
@@ -12,272 +12,80 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
#if false
1615
@testable import AWSLambdaRuntime
1716
@testable import AWSLambdaRuntimeCore
17+
import Logging
1818
import NIO
19+
import NIOFoundationCompat
1920
import XCTest
2021

2122
class CodableLambdaTest: XCTestCase {
22-
func testCallbackSuccess() {
23-
let server = MockLambdaServer(behavior: Behavior())
24-
XCTAssertNoThrow(try server.start().wait())
25-
defer { XCTAssertNoThrow(try server.stop().wait()) }
23+
var eventLoopGroup: EventLoopGroup!
24+
let allocator = ByteBufferAllocator()
2625

27-
struct Handler: LambdaHandler {
28-
typealias In = Request
29-
typealias Out = Response
30-
31-
func handle(context: Lambda.Context, payload: Request, callback: (Result<Response, Error>) -> Void) {
32-
callback(.success(Response(requestId: payload.requestId)))
33-
}
34-
}
35-
36-
let maxTimes = Int.random(in: 1 ... 10)
37-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
38-
let result = Lambda.run(configuration: configuration, handler: Handler())
39-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
40-
}
41-
42-
func testVoidCallbackSuccess() {
43-
let server = MockLambdaServer(behavior: Behavior(result: .success(nil)))
44-
XCTAssertNoThrow(try server.start().wait())
45-
defer { XCTAssertNoThrow(try server.stop().wait()) }
46-
47-
struct Handler: LambdaHandler {
48-
typealias In = Request
49-
typealias Out = Void
50-
51-
func handle(context: Lambda.Context, payload: Request, callback: (Result<Void, Error>) -> Void) {
52-
callback(.success(()))
53-
}
54-
}
55-
56-
let maxTimes = Int.random(in: 1 ... 10)
57-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
58-
let result = Lambda.run(configuration: configuration, handler: Handler())
59-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
60-
}
61-
62-
func testCallbackFailure() {
63-
let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom"))))
64-
XCTAssertNoThrow(try server.start().wait())
65-
defer { XCTAssertNoThrow(try server.stop().wait()) }
66-
67-
struct Handler: LambdaHandler {
68-
typealias In = Request
69-
typealias Out = Response
70-
71-
func handle(context: Lambda.Context, payload: Request, callback: (Result<Response, Error>) -> Void) {
72-
callback(.failure(TestError("boom")))
73-
}
74-
}
75-
76-
let maxTimes = Int.random(in: 1 ... 10)
77-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
78-
let result = Lambda.run(configuration: configuration, handler: Handler())
79-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
80-
}
81-
82-
func testEventLoopSuccess() {
83-
let server = MockLambdaServer(behavior: Behavior())
84-
XCTAssertNoThrow(try server.start().wait())
85-
defer { XCTAssertNoThrow(try server.stop().wait()) }
86-
87-
struct Handler: EventLoopLambdaHandler {
88-
typealias In = Request
89-
typealias Out = Response
90-
91-
func handle(context: Lambda.Context, payload: Request) -> EventLoopFuture<Response> {
92-
context.eventLoop.makeSucceededFuture(Response(requestId: payload.requestId))
93-
}
94-
}
95-
96-
let maxTimes = Int.random(in: 1 ... 10)
97-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
98-
let result = Lambda.run(configuration: configuration, handler: Handler())
99-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
100-
}
101-
102-
func testVoidEventLoopSuccess() {
103-
let server = MockLambdaServer(behavior: Behavior(result: .success(nil)))
104-
XCTAssertNoThrow(try server.start().wait())
105-
defer { XCTAssertNoThrow(try server.stop().wait()) }
106-
107-
struct Handler: EventLoopLambdaHandler {
108-
typealias In = Request
109-
typealias Out = Void
110-
111-
func handle(context: Lambda.Context, payload: Request) -> EventLoopFuture<Void> {
112-
context.eventLoop.makeSucceededFuture(())
113-
}
114-
}
115-
116-
let maxTimes = Int.random(in: 1 ... 10)
117-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
118-
let result = Lambda.run(configuration: configuration, handler: Handler())
119-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
120-
}
121-
122-
func testEventLoopFailure() {
123-
let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom"))))
124-
XCTAssertNoThrow(try server.start().wait())
125-
defer { XCTAssertNoThrow(try server.stop().wait()) }
126-
127-
struct Handler: EventLoopLambdaHandler {
128-
typealias In = Request
129-
typealias Out = Response
130-
131-
func handle(context: Lambda.Context, payload: Request) -> EventLoopFuture<Response> {
132-
context.eventLoop.makeFailedFuture(TestError("boom"))
133-
}
134-
}
135-
136-
let maxTimes = Int.random(in: 1 ... 10)
137-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
138-
let result = Lambda.run(configuration: configuration, handler: Handler())
139-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
140-
}
141-
142-
func testClosureSuccess() {
143-
let server = MockLambdaServer(behavior: Behavior())
144-
XCTAssertNoThrow(try server.start().wait())
145-
defer { XCTAssertNoThrow(try server.stop().wait()) }
146-
147-
let maxTimes = Int.random(in: 1 ... 10)
148-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
149-
let result = Lambda.run(configuration: configuration) { (_, payload: Request, callback) in
150-
callback(.success(Response(requestId: payload.requestId)))
151-
}
152-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
26+
override func setUp() {
27+
self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
15328
}
15429

155-
func testVoidClosureSuccess() {
156-
let server = MockLambdaServer(behavior: Behavior(result: .success(nil)))
157-
XCTAssertNoThrow(try server.start().wait())
158-
defer { XCTAssertNoThrow(try server.stop().wait()) }
159-
160-
let maxTimes = Int.random(in: 1 ... 10)
161-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
162-
let result = Lambda.run(configuration: configuration) { (_, _: Request, callback: (Result<Void, Error>) -> Void) in
163-
callback(.success(()))
164-
}
165-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
166-
}
167-
168-
func testClosureFailure() {
169-
let server = MockLambdaServer(behavior: Behavior(result: .failure(TestError("boom"))))
170-
XCTAssertNoThrow(try server.start().wait())
171-
defer { XCTAssertNoThrow(try server.stop().wait()) }
172-
173-
let maxTimes = Int.random(in: 1 ... 10)
174-
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes))
175-
let result: Result<Int, Error> = Lambda.run(configuration: configuration) { (_, _: Request, callback: (Result<Response, Error>) -> Void) in
176-
callback(.failure(TestError("boom")))
177-
}
178-
assertLambdaLifecycleResult(result, shoudHaveRun: maxTimes)
30+
override func tearDown() {
31+
try! self.eventLoopGroup.syncShutdownGracefully()
17932
}
18033

181-
func testBootstrapFailure() {
182-
let server = MockLambdaServer(behavior: FailedBootstrapBehavior())
183-
XCTAssertNoThrow(try server.start().wait())
184-
defer { XCTAssertNoThrow(try server.stop().wait()) }
185-
186-
struct Handler: LambdaHandler {
187-
typealias In = Request
188-
typealias Out = Response
34+
func testCodableVoidClosureWrapper() {
35+
let request = Request(requestId: UUID().uuidString)
36+
var inputBuffer: ByteBuffer?
37+
var outputBuffer: ByteBuffer?
18938

190-
init(eventLoop: EventLoop) throws {
191-
throw TestError("kaboom")
192-
}
193-
194-
func handle(context: Lambda.Context, payload: Request, callback: (Result<Response, Error>) -> Void) {
195-
callback(.failure(TestError("should not be called")))
196-
}
39+
let closureWrapper = CodableVoidClosureWrapper { (_, _: Request, completion) in
40+
XCTAssertEqual(request, request)
41+
completion(.success(()))
19742
}
19843

199-
let result = Lambda.run(factory: Handler.init)
200-
assertLambdaLifecycleResult(result, shouldFailWithError: TestError("kaboom"))
201-
}
202-
}
203-
204-
// TODO: taking advantage of the fact we know the serialization is json
205-
private struct Behavior: LambdaServerBehavior {
206-
let requestId: String
207-
let payload: String
208-
let result: Result<String?, TestError>
209-
210-
init(requestId: String = UUID().uuidString, payload: String = "hello", result: Result<String?, TestError> = .success("hello")) {
211-
self.requestId = requestId
212-
self.payload = payload
213-
self.result = result
44+
XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator))
45+
XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), payload: XCTUnwrap(inputBuffer)).wait())
46+
XCTAssertNil(outputBuffer)
21447
}
21548

216-
func getWork() -> GetWorkResult {
217-
guard let payload = try? JSONEncoder().encode(Request(requestId: requestId)) else {
218-
XCTFail("encoding error")
219-
return .failure(.internalServerError)
220-
}
221-
guard let payloadAsString = String(data: payload, encoding: .utf8) else {
222-
XCTFail("encoding error")
223-
return .failure(.internalServerError)
224-
}
225-
return .success((requestId: self.requestId, payload: payloadAsString))
226-
}
49+
func testCodableClosureWrapper() {
50+
let request = Request(requestId: UUID().uuidString)
51+
var inputBuffer: ByteBuffer?
52+
var outputBuffer: ByteBuffer?
53+
var response: Response?
22754

228-
func processResponse(requestId: String, response: String?) -> Result<Void, ProcessResponseError> {
229-
switch self.result {
230-
case .success(let expected) where expected != nil:
231-
guard let data = response?.data(using: .utf8) else {
232-
XCTFail("decoding error")
233-
return .failure(.internalServerError)
234-
}
235-
guard let response = try? JSONDecoder().decode(Response.self, from: data) else {
236-
XCTFail("decoding error")
237-
return .failure(.internalServerError)
238-
}
239-
XCTAssertEqual(self.requestId, response.requestId, "expecting requestId to match")
240-
return .success(())
241-
case .success(let expected) where expected == nil:
242-
XCTAssertNil(response)
243-
return .success(())
244-
case .failure:
245-
XCTFail("unexpected to fail, but succeeded with: \(response ?? "undefined")")
246-
return .failure(.internalServerError)
247-
default:
248-
preconditionFailure("invalid state")
55+
let closureWrapper = CodableClosureWrapper { (_, req: Request, completion: (Result<Response, Error>) -> Void) in
56+
XCTAssertEqual(request, request)
57+
completion(.success(Response(requestId: req.requestId)))
24958
}
250-
}
25159

252-
func processError(requestId: String, error: ErrorResponse) -> Result<Void, ProcessErrorError> {
253-
XCTAssertEqual(self.requestId, requestId, "expecting requestId to match")
254-
switch self.result {
255-
case .success:
256-
XCTFail("unexpected to succeed, but failed with: \(error)")
257-
return .failure(.internalServerError)
258-
case .failure(let expected):
259-
XCTAssertEqual(expected.description, error.errorMessage, "expecting error to match")
260-
return .success(())
261-
}
60+
XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator))
61+
XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), payload: XCTUnwrap(inputBuffer)).wait())
62+
XCTAssertNoThrow(response = try JSONDecoder().decode(Response.self, from: XCTUnwrap(outputBuffer)))
63+
XCTAssertEqual(response?.requestId, request.requestId)
26264
}
26365

264-
func processInitError(error: ErrorResponse) -> Result<Void, ProcessErrorError> {
265-
XCTFail("should not report init error")
266-
return .failure(.internalServerError)
66+
// convencience method
67+
func newContext() -> Lambda.Context {
68+
Lambda.Context(requestId: UUID().uuidString,
69+
traceId: "abc123",
70+
invokedFunctionArn: "aws:arn:",
71+
deadline: .now() + .seconds(3),
72+
cognitoIdentity: nil,
73+
clientContext: nil,
74+
logger: Logger(label: "test"),
75+
eventLoop: self.eventLoopGroup.next())
26776
}
26877
}
26978

270-
private struct Request: Codable {
79+
private struct Request: Codable, Equatable {
27180
let requestId: String
27281
init(requestId: String) {
27382
self.requestId = requestId
27483
}
27584
}
27685

277-
private struct Response: Codable {
86+
private struct Response: Codable, Equatable {
27887
let requestId: String
27988
init(requestId: String) {
28089
self.requestId = requestId
28190
}
28291
}
283-
#endif

0 commit comments

Comments
 (0)