-
Notifications
You must be signed in to change notification settings - Fork 113
Added header when reporting failing invocations or initializations #116 #128
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
Changes from 15 commits
2841197
4162c6b
a207384
03c33da
d75e2f2
5c81588
8da17fd
1e57c4b
f8da566
72c2b8e
d0b3712
196b335
1ccd68e
c520b22
f5bcbd7
e5dd619
5f5f09c
eabbc10
c375ab6
84e19d2
60c4dc4
24c9d1b
d8a18e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,11 @@ | |
//===----------------------------------------------------------------------===// | ||
|
||
@testable import AWSLambdaRuntimeCore | ||
import Logging | ||
import NIO | ||
import NIOFoundationCompat | ||
@testable import NIOHTTP1 | ||
import NIOTestUtils | ||
import XCTest | ||
|
||
class LambdaRuntimeClientTest: XCTestCase { | ||
|
@@ -209,6 +214,110 @@ class LambdaRuntimeClientTest: XCTestCase { | |
XCTAssertEqual(#"{"errorType":"error","errorMessage":"🥑👨👩👧👧👩👩👧👧👨👨👧"}"#, String(decoding: emojiBytes, as: Unicode.UTF8.self)) | ||
} | ||
|
||
func testInitializationErrorReport() { | ||
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) | ||
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) } | ||
|
||
let server = NIOHTTP1TestServer(group: eventLoopGroup) | ||
defer { XCTAssertNoThrow(try server.stop()) } | ||
|
||
let logger = Logger(label: "TestLogger") | ||
let client = Lambda.RuntimeClient(eventLoop: eventLoopGroup.next(), configuration: .init(baseURL: "127.0.0.1:\(server.serverPort)")) | ||
let result = client.reportInitializationError(logger: logger, error: TestError("boom")) | ||
|
||
var inboundHeader: HTTPServerRequestPart? | ||
XCTAssertNoThrow(inboundHeader = try server.readInbound()) | ||
guard case .head(let head) = try? XCTUnwrap(inboundHeader) else { XCTFail("Expected to get a head first"); return } | ||
XCTAssertEqual(head.headers["lambda-runtime-function-error-type"], ["Unhandled"]) | ||
XCTAssertEqual(head.headers["user-agent"], ["Swift-Lambda/Unknown"]) | ||
|
||
var inboundBody: HTTPServerRequestPart? | ||
XCTAssertNoThrow(inboundBody = try server.readInbound()) | ||
guard case .body(let body) = try? XCTUnwrap(inboundBody) else { XCTFail("Expected body after head"); return } | ||
XCTAssertEqual(try JSONDecoder().decode(ErrorResponse.self, from: body).errorMessage, "boom") | ||
|
||
XCTAssertEqual(try server.readInbound(), .end(nil)) | ||
|
||
XCTAssertNoThrow(try server.writeOutbound(.head(.init(version: .init(major: 1, minor: 1), status: .accepted)))) | ||
XCTAssertNoThrow(try server.writeOutbound(.end(nil))) | ||
XCTAssertNoThrow(try result.wait()) | ||
} | ||
|
||
func testInvocationErrorReport() { | ||
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) | ||
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) } | ||
|
||
let server = NIOHTTP1TestServer(group: eventLoopGroup) | ||
defer { XCTAssertNoThrow(try server.stop()) } | ||
|
||
let logger = Logger(label: "TestLogger") | ||
let client = Lambda.RuntimeClient(eventLoop: eventLoopGroup.next(), configuration: .init(baseURL: "127.0.0.1:\(server.serverPort)")) | ||
|
||
let header = HTTPHeaders([ | ||
(AmazonHeaders.requestID, "test"), | ||
(AmazonHeaders.deadline, String(Date(timeIntervalSinceNow: 60).millisSinceEpoch)), | ||
(AmazonHeaders.invokedFunctionARN, "arn:aws:lambda:us-east-1:123456789012:function:custom-runtime"), | ||
(AmazonHeaders.traceID, "Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1"), | ||
]) | ||
var inv: Lambda.Invocation? | ||
XCTAssertNoThrow(inv = try Lambda.Invocation(headers: header)) | ||
guard let invocation = inv else { return } | ||
|
||
let result = client.reportResults(logger: logger, invocation: invocation, result: Result.failure(TestError("boom"))) | ||
|
||
var inboundHeader: HTTPServerRequestPart? | ||
XCTAssertNoThrow(inboundHeader = try server.readInbound()) | ||
guard case .head(let head) = try? XCTUnwrap(inboundHeader) else { XCTFail("Expected to get a head first"); return } | ||
XCTAssertEqual(head.headers["lambda-runtime-function-error-type"], ["Unhandled"]) | ||
XCTAssertEqual(head.headers["user-agent"], ["Swift-Lambda/Unknown"]) | ||
|
||
var inboundBody: HTTPServerRequestPart? | ||
XCTAssertNoThrow(inboundBody = try server.readInbound()) | ||
guard case .body(let body) = try? XCTUnwrap(inboundBody) else { XCTFail("Expected body after head"); return } | ||
XCTAssertEqual(try JSONDecoder().decode(ErrorResponse.self, from: body).errorMessage, "boom") | ||
|
||
XCTAssertEqual(try server.readInbound(), .end(nil)) | ||
|
||
XCTAssertNoThrow(try server.writeOutbound(.head(.init(version: .init(major: 1, minor: 1), status: .accepted)))) | ||
XCTAssertNoThrow(try server.writeOutbound(.end(nil))) | ||
XCTAssertNoThrow(try result.wait()) | ||
} | ||
|
||
func testSuccessHeaders() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I would rename this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Ro-M yes |
||
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) | ||
defer { XCTAssertNoThrow(try eventLoopGroup.syncShutdownGracefully()) } | ||
|
||
let server = NIOHTTP1TestServer(group: eventLoopGroup) | ||
defer { XCTAssertNoThrow(try server.stop()) } | ||
|
||
let logger = Logger(label: "TestLogger") | ||
let client = Lambda.RuntimeClient(eventLoop: eventLoopGroup.next(), configuration: .init(baseURL: "127.0.0.1:\(server.serverPort)")) | ||
|
||
let header = HTTPHeaders([ | ||
(AmazonHeaders.requestID, "test"), | ||
(AmazonHeaders.deadline, String(Date(timeIntervalSinceNow: 60).millisSinceEpoch)), | ||
(AmazonHeaders.invokedFunctionARN, "arn:aws:lambda:us-east-1:123456789012:function:custom-runtime"), | ||
(AmazonHeaders.traceID, "Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1"), | ||
]) | ||
var inv: Lambda.Invocation? | ||
XCTAssertNoThrow(inv = try Lambda.Invocation(headers: header)) | ||
guard let invocation = inv else { return } | ||
|
||
let result = client.reportResults(logger: logger, invocation: invocation, result: Result.success(nil)) | ||
|
||
var inboundHeader: HTTPServerRequestPart? | ||
XCTAssertNoThrow(inboundHeader = try server.readInbound()) | ||
guard case .head(let head) = try? XCTUnwrap(inboundHeader) else { XCTFail("Expected to get a head first"); return } | ||
XCTAssertFalse(head.headers.contains(name: "lambda-runtime-function-error-type")) | ||
XCTAssertEqual(head.headers["user-agent"], ["Swift-Lambda/Unknown"]) | ||
|
||
XCTAssertEqual(try server.readInbound(), .end(nil)) | ||
|
||
XCTAssertNoThrow(try server.writeOutbound(.head(.init(version: .init(major: 1, minor: 1), status: .accepted)))) | ||
XCTAssertNoThrow(try server.writeOutbound(.end(nil))) | ||
XCTAssertNoThrow(try result.wait()) | ||
} | ||
|
||
class Behavior: LambdaServerBehavior { | ||
var state = 0 | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomerd I would vote to inject all headers on every call and to not have them split over two files. wdyt? In hindsight having static headers directly on the HTTPClient doesn't make much sense IMHO.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @fabianfett do you mean have
RuntimeClient
fully control the headers instead of injecting "additional" ones? if so, that sounds good to me.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be ok to include that change in this PR or should I make a separate one for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we fix it in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I moved the static header declaration into an extension on
RuntimeClient
. Theget
andpost
methods onHTTPClient
now have a non-optionalheaders
parameter (without a default value). I also moved theheaders
parameter to come after theurl
parameter ... that ordering made a more cohesive impression to me ^^