Skip to content

Commit d342138

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

File tree

2 files changed

+58
-259
lines changed

2 files changed

+58
-259
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: 58 additions & 247 deletions
Original file line numberDiff line numberDiff line change
@@ -12,272 +12,83 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
#if false
15+
1616
@testable import AWSLambdaRuntime
1717
@testable import AWSLambdaRuntimeCore
1818
import NIO
19+
import NIOFoundationCompat
1920
import XCTest
21+
import Logging
2022

2123
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()) }
26-
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-
}
24+
25+
var eventLoopGroup: EventLoopGroup!
26+
let allocator = ByteBufferAllocator()
27+
28+
override func setUp() {
29+
self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
30+
}
31+
32+
override func tearDown() {
33+
try! self.eventLoopGroup.syncShutdownGracefully()
34+
}
35+
36+
func testCodableVoidClosureWrapper() {
37+
let request = Request(requestId: UUID().uuidString)
38+
var inputBuffer: ByteBuffer?
39+
var outputBuffer: ByteBuffer?
40+
41+
let closureWrapper = CodableVoidClosureWrapper { (ctx, req: Request, completion) in
42+
XCTAssertEqual(request, request)
43+
completion(.success(()))
11444
}
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-
}
45+
46+
XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator))
47+
XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), payload: XCTUnwrap(inputBuffer)).wait())
48+
XCTAssertNil(outputBuffer)
49+
}
50+
51+
func testCodableClosureWrapper() {
52+
let request = Request(requestId: UUID().uuidString)
53+
var inputBuffer: ByteBuffer?
54+
var outputBuffer: ByteBuffer?
55+
var response: Response?
56+
57+
let closureWrapper = CodableClosureWrapper { (ctx, req: Request, completion: (Result<Response, Error>) -> ()) in
58+
XCTAssertEqual(request, request)
59+
completion(.success(Response(requestId: req.requestId)))
13460
}
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)
153-
}
154-
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)
179-
}
180-
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
189-
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-
}
197-
}
198-
199-
let result = Lambda.run(factory: Handler.init)
200-
assertLambdaLifecycleResult(result, shouldFailWithError: TestError("kaboom"))
61+
62+
XCTAssertNoThrow(inputBuffer = try JSONEncoder().encode(request, using: self.allocator))
63+
XCTAssertNoThrow(outputBuffer = try closureWrapper.handle(context: self.newContext(), payload: XCTUnwrap(inputBuffer)).wait())
64+
XCTAssertNoThrow(response = try JSONDecoder().decode(Response.self, from: XCTUnwrap(outputBuffer)))
65+
XCTAssertEqual(response?.requestId, request.requestId)
66+
}
67+
68+
// convencience method
69+
func newContext() -> Lambda.Context {
70+
Lambda.Context(requestId: UUID().uuidString,
71+
traceId: "abc123",
72+
invokedFunctionArn: "aws:arn:",
73+
deadline: .now() + .seconds(3),
74+
cognitoIdentity: nil,
75+
clientContext: nil,
76+
logger: Logger(label: "test"),
77+
eventLoop: self.eventLoopGroup.next())
20178
}
20279
}
20380

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
214-
}
215-
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-
}
227-
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")
249-
}
250-
}
251-
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-
}
262-
}
263-
264-
func processInitError(error: ErrorResponse) -> Result<Void, ProcessErrorError> {
265-
XCTFail("should not report init error")
266-
return .failure(.internalServerError)
267-
}
268-
}
269-
270-
private struct Request: Codable {
81+
private struct Request: Codable, Equatable {
27182
let requestId: String
27283
init(requestId: String) {
27384
self.requestId = requestId
27485
}
27586
}
27687

277-
private struct Response: Codable {
88+
private struct Response: Codable, Equatable {
27889
let requestId: String
27990
init(requestId: String) {
28091
self.requestId = requestId
28192
}
28293
}
283-
#endif
94+

0 commit comments

Comments
 (0)