Skip to content

add a testing harness to ease testing of lambdas #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

tomerd
Copy link
Contributor

@tomerd tomerd commented Apr 21, 2020

motivation: make testing lambda easy

changes:

  • add a AWSLambdaTesting module
  • add helper methods for testing different types of Lambda handlers / closures

@tomerd tomerd requested a review from fabianfett April 21, 2020 20:36
motivation: make testing lambda easy

changes:
* add a AWSLambdaTesting module
* add helper methods for testing different types of Lambda handlers / closures
@tomerd tomerd force-pushed the feature/testing-harness branch from 76815fb to 6b8acb3 Compare April 21, 2020 20:38
@tomerd tomerd requested a review from tachyonics April 21, 2020 20:40
Copy link
Member

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this approach. A couple of notes though:

Implemented my notes:
https://github.com/swift-server/swift-aws-lambda-runtime/pull/60/files

// testing helper
.target(name: "AWSLambdaTesting", dependencies: [
"AWSLambdaRuntime",
.product(name: "NIOHTTP1", package: "swift-nio"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see the dependency is NIO and not NIOHTTP1.

import NIO

extension Lambda {
public static func test(_ closure: @escaping StringLambdaClosure,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very excited about this API design. 😍


public static func test<In, Out, Handler: EventLoopLambdaHandler>(_ handler: Handler,
with payload: In,
_ body: @escaping (Result<Out, Error>) -> Void) where Handler.In == In, Handler.Out == Out {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to work with completion blocks here?

I would be in favor of a sync api, which returns an Out and throws:

public static func test<In, Out, Handler: EventLoopLambdaHandler>(
  _ handler: Handler,
  with payload: In) throws 
  -> Out where Handler.In == In, Handler.Out == Out 

Going for such a sync approach would safe developers from using XCTestExpectation, which should make testing code much nicer.

This change should trickle down to all other methods of course.

with payload: In,
_ body: @escaping (Result<Out, Error>) -> Void) where Handler.In == In, Handler.Out == Out {
let logger = Logger(label: "test")
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going for a sync approach, will allow us to defer { eventLoopGroup.syncShutdown() }

invokedFunctionArn: "arn:aws:lambda:us-west-1:\(DispatchTime.now().uptimeNanoseconds):function:custom-runtime",
deadline: .now() + 5,
logger: logger,
eventLoop: eventLoopGroup.next())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we maybe want to create a

struct TestConfig {
  let requestId: String
  let traceId: String
  let invokedFunctionArn: String
  let timeout: Double
}

that can be optionally injected into the Lambda.test method, which could allow developers to test Timeout handlers and so on.

deadline: .now() + 5,
logger: logger,
eventLoop: eventLoopGroup.next())
handler.handle(context: context, payload: payload).whenComplete { result in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we execute this on the eventLoop as it would happen in the real environment?

typealias Out = Void

func handle(context: Lambda.Context, payload: In, callback: @escaping (Result<Out, Error>) -> Void) {
callback(.failure(MyError()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid all those test cases work only because the callback is immediately called.

@tomerd
Copy link
Contributor Author

tomerd commented Apr 22, 2020

closing in favor of #60

@tomerd tomerd closed this Apr 22, 2020
@tomerd tomerd deleted the feature/testing-harness branch May 29, 2020 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants