diff --git a/Package.swift b/Package.swift index 0e5823f6..cacb867b 100644 --- a/Package.swift +++ b/Package.swift @@ -16,8 +16,11 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/apple/swift-nio.git", .upToNextMajor(from: "2.17.0")), +// .package(url: "https://github.com/pokryfka/swift-nio.git", .branch("feature/tracing")), .package(url: "https://github.com/apple/swift-log.git", .upToNextMajor(from: "1.0.0")), .package(url: "https://github.com/swift-server/swift-backtrace.git", .upToNextMajor(from: "1.1.0")), + // TODO: use swift-tracing when available + .package(url: "https://github.com/pokryfka/aws-xray-sdk-swift.git", .upToNextMinor(from: "0.7.1")), ], targets: [ .target(name: "AWSLambdaRuntime", dependencies: [ @@ -29,6 +32,7 @@ let package = Package( .product(name: "Logging", package: "swift-log"), .product(name: "Backtrace", package: "swift-backtrace"), .product(name: "NIOHTTP1", package: "swift-nio"), + .product(name: "AWSXRaySDK", package: "aws-xray-sdk-swift"), ]), .testTarget(name: "AWSLambdaRuntimeCoreTests", dependencies: [ .byName(name: "AWSLambdaRuntimeCore"), @@ -38,6 +42,7 @@ let package = Package( .testTarget(name: "AWSLambdaRuntimeTests", dependencies: [ .byName(name: "AWSLambdaRuntimeCore"), .byName(name: "AWSLambdaRuntime"), + .product(name: "AWSXRayRecorder", package: "aws-xray-sdk-swift"), ]), .target(name: "AWSLambdaEvents", dependencies: []), .testTarget(name: "AWSLambdaEventsTests", dependencies: ["AWSLambdaEvents"]), @@ -45,6 +50,7 @@ let package = Package( .target(name: "AWSLambdaTesting", dependencies: [ .byName(name: "AWSLambdaRuntime"), .product(name: "NIO", package: "swift-nio"), + .product(name: "AWSXRayRecorder", package: "aws-xray-sdk-swift"), ]), .testTarget(name: "AWSLambdaTestingTests", dependencies: ["AWSLambdaTesting"]), // for perf testing diff --git a/Sources/AWSLambdaRuntimeCore/HTTPClient.swift b/Sources/AWSLambdaRuntimeCore/HTTPClient.swift index fcd2a450..9b894890 100644 --- a/Sources/AWSLambdaRuntimeCore/HTTPClient.swift +++ b/Sources/AWSLambdaRuntimeCore/HTTPClient.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import Baggage import NIO import NIOConcurrencyHelpers import NIOHTTP1 @@ -23,31 +24,35 @@ internal final class HTTPClient { private let eventLoop: EventLoop private let configuration: Lambda.Configuration.RuntimeEngine private let targetHost: String + private let tracer: TracingInstrument private var state = State.disconnected private var executing = false - init(eventLoop: EventLoop, configuration: Lambda.Configuration.RuntimeEngine) { + init(eventLoop: EventLoop, configuration: Lambda.Configuration.RuntimeEngine, tracer: TracingInstrument) { self.eventLoop = eventLoop self.configuration = configuration self.targetHost = "\(self.configuration.ip):\(self.configuration.port)" + self.tracer = tracer } - func get(url: String, headers: HTTPHeaders, timeout: TimeAmount? = nil) -> EventLoopFuture { + func get(url: String, headers: HTTPHeaders, timeout: TimeAmount? = nil, context: BaggageContext) -> EventLoopFuture { self.execute(Request(targetHost: self.targetHost, url: url, method: .GET, headers: headers, - timeout: timeout ?? self.configuration.requestTimeout)) + timeout: timeout ?? self.configuration.requestTimeout), + context: context) } - func post(url: String, headers: HTTPHeaders, body: ByteBuffer?, timeout: TimeAmount? = nil) -> EventLoopFuture { + func post(url: String, headers: HTTPHeaders, body: ByteBuffer?, timeout: TimeAmount? = nil, context: BaggageContext) -> EventLoopFuture { self.execute(Request(targetHost: self.targetHost, url: url, method: .POST, headers: headers, body: body, - timeout: timeout ?? self.configuration.requestTimeout)) + timeout: timeout ?? self.configuration.requestTimeout), + context: context) } /// cancels the current request if there is one @@ -65,7 +70,7 @@ internal final class HTTPClient { } // TODO: cap reconnect attempt - private func execute(_ request: Request, validate: Bool = true) -> EventLoopFuture { + private func execute(_ request: Request, validate: Bool = true, context: BaggageContext) -> EventLoopFuture { if validate { precondition(self.executing == false, "expecting single request at a time") self.executing = true @@ -75,14 +80,16 @@ internal final class HTTPClient { case .disconnected: return self.connect().flatMap { channel -> EventLoopFuture in self.state = .connected(channel) - return self.execute(request, validate: false) + return self.execute(request, validate: false, context: context) } case .connected(let channel): guard channel.isActive else { self.state = .disconnected - return self.execute(request, validate: false) + return self.execute(request, validate: false, context: context) } + let segment = self.tracer.beginSegment(name: "HTTPClient", baggage: context) + segment.setHTTPRequest(method: request.method.rawValue, url: request.url) let promise = channel.eventLoop.makePromise(of: Response.self) promise.futureResult.whenComplete { _ in precondition(self.executing == true, "invalid execution state") @@ -90,7 +97,7 @@ internal final class HTTPClient { } let wrapper = HTTPRequestWrapper(request: request, promise: promise) channel.writeAndFlush(wrapper).cascadeFailure(to: promise) - return promise.futureResult + return promise.futureResult.endSegment(segment) } } diff --git a/Sources/AWSLambdaRuntimeCore/Lambda.swift b/Sources/AWSLambdaRuntimeCore/Lambda.swift index 5dc27648..9287489b 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda.swift @@ -18,6 +18,7 @@ import Glibc import Darwin.C #endif +import AWSXRaySDK import Backtrace import Logging import NIO @@ -106,8 +107,12 @@ public enum Lambda { logger.logLevel = configuration.general.logLevel var result: Result! + // TODO: bootstrap/configure the trace lifecycle + let tracer: XRayRecorder = XRayRecorder(eventLoopGroupProvider: .createNew) MultiThreadedEventLoopGroup.withCurrentThreadAsEventLoop { eventLoop in - let lifecycle = Lifecycle(eventLoop: eventLoop, logger: logger, configuration: configuration, factory: factory) +// let tracer = XRayRecorder(eventLoopGroupProvider: .shared(eventLoop)) + let lifecycle = Lifecycle(eventLoop: eventLoop, logger: logger, tracer: tracer, + configuration: configuration, factory: factory) #if DEBUG let signalSource = trap(signal: configuration.lifecycle.stopSignal) { signal in logger.info("intercepted signal: \(signal)") @@ -130,6 +135,14 @@ public enum Lambda { } } + // TODO: this is broken, the tracer tries to eat cake and have cake: flash on eventLoop then syncShutdown + // fix in XRayRecorder + tracer.shutdown { error in + if let error = error { + preconditionFailure("Failed to shutdown tracer: \(error)") + } + } + logger.info("shutdown completed") return result } diff --git a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift index 9b9ec8fb..f8243256 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift @@ -26,7 +26,8 @@ extension Lambda { self.init(general: .init(), lifecycle: .init(), runtimeEngine: .init()) } - init(general: General? = nil, lifecycle: Lifecycle? = nil, runtimeEngine: RuntimeEngine? = nil) { + init(general: General? = nil, lifecycle: Lifecycle? = nil, runtimeEngine: RuntimeEngine? = nil) + { self.general = general ?? General() self.lifecycle = lifecycle ?? Lifecycle() self.runtimeEngine = runtimeEngine ?? RuntimeEngine() diff --git a/Sources/AWSLambdaRuntimeCore/LambdaContext.swift b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift index ab30dd7b..cd7a04ca 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaContext.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift @@ -12,9 +12,12 @@ // //===----------------------------------------------------------------------===// +import AWSXRayRecorder +import Baggage import Dispatch import Logging import NIO +import NIOConcurrencyHelpers // MARK: - InitializationContext @@ -50,6 +53,9 @@ extension Lambda { /// Lambda runtime context. /// The Lambda runtime generates and passes the `Context` to the Lambda handler as an argument. public final class Context: CustomDebugStringConvertible { + // TODO: use RWLock (separate PR) + private let lock = Lock() + /// The request ID, which identifies the request that triggered the function invocation. public let requestID: String @@ -68,11 +74,23 @@ extension Lambda { /// For invocations from the AWS Mobile SDK, data about the client application and device. public let clientContext: String? + // TODO: or should the Lambda "runtime" context and the Baggage context be separate? + private var _baggage: BaggageContext + + /// Baggage context. + public var baggage: BaggageContext { + get { self.lock.withLock { _baggage } } + set { self.lock.withLockVoid { _baggage = newValue } } + } + /// `Logger` to log with /// /// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable. public let logger: Logger + /// Tracing instrument. + public let tracer: TracingInstrument + /// The `EventLoop` the Lambda is executed on. Use this to schedule work with. /// This is useful when implementing the `EventLoopLambdaHandler` protocol. /// @@ -91,8 +109,10 @@ extension Lambda { cognitoIdentity: String? = nil, clientContext: String? = nil, logger: Logger, + tracer: TracingInstrument, eventLoop: EventLoop, - allocator: ByteBufferAllocator) { + allocator: ByteBufferAllocator) + { self.requestID = requestID self.traceID = traceID self.invokedFunctionARN = invokedFunctionARN @@ -106,7 +126,12 @@ extension Lambda { var logger = logger logger[metadataKey: "awsRequestID"] = .string(requestID) logger[metadataKey: "awsTraceID"] = .string(traceID) + var baggage = BaggageContext() + // TODO: use `swift-tracing` API, note that, regardless, we can ONLY extract X-Ray Context + baggage.xRayContext = try? XRayContext(tracingHeader: traceID) + self._baggage = baggage self.logger = logger + self.tracer = tracer } public func getRemainingTime() -> TimeAmount { diff --git a/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift b/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift index 16eba1cb..0889eccf 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaHandler.swift @@ -129,18 +129,31 @@ public protocol EventLoopLambdaHandler: ByteBufferLambdaHandler { public extension EventLoopLambdaHandler { /// Driver for `ByteBuffer` -> `In` decoding and `Out` -> `ByteBuffer` encoding func handle(context: Lambda.Context, event: ByteBuffer) -> EventLoopFuture { - switch self.decodeIn(buffer: event) { + let segment = context.tracer.beginSegment(name: "HandleEvent", baggage: context.baggage) + let decodedEvent = segment.subsegment(name: "DecodeIn") { _ in + self.decodeIn(buffer: event) + } + switch decodedEvent { case .failure(let error): + segment.addError(error) + segment.end() return context.eventLoop.makeFailedFuture(CodecError.requestDecoding(error)) case .success(let `in`): - return self.handle(context: context, event: `in`).flatMapThrowing { out in - switch self.encodeOut(allocator: context.allocator, value: out) { - case .failure(let error): - throw CodecError.responseEncoding(error) - case .success(let buffer): - return buffer + let subsegment = segment.beginSubsegment(name: "HandleIn") + context.baggage = subsegment.baggage + return self.handle(context: context, event: `in`) + .endSegment(subsegment) + .flatMapThrowing { out in + try context.tracer.segment(name: "EncodeOut", baggage: segment.baggage) { _ in + switch self.encodeOut(allocator: context.allocator, value: out) { + case .failure(let error): + throw CodecError.responseEncoding(error) + case .success(let buffer): + return buffer + } + } } - } + .endSegment(segment) } } diff --git a/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift b/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift index ec609901..028f1dc3 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import AWSXRaySDK import Logging import NIO import NIOConcurrencyHelpers @@ -26,6 +27,7 @@ extension Lambda { private let logger: Logger private let configuration: Configuration private let factory: HandlerFactory + private let tracer: TracingInstrument private var state = State.idle { willSet { @@ -41,13 +43,16 @@ extension Lambda { /// - logger: A `Logger` to log the Lambda events. /// - factory: A `LambdaHandlerFactory` to create the concrete Lambda handler. public convenience init(eventLoop: EventLoop, logger: Logger, factory: @escaping HandlerFactory) { - self.init(eventLoop: eventLoop, logger: logger, configuration: .init(), factory: factory) + self.init(eventLoop: eventLoop, logger: logger, tracer: NoOpTracingInstrument(), configuration: .init(), + factory: factory) } - init(eventLoop: EventLoop, logger: Logger, configuration: Configuration, factory: @escaping HandlerFactory) { + init(eventLoop: EventLoop, logger: Logger, tracer: TracingInstrument, configuration: Configuration, + factory: @escaping HandlerFactory) { self.eventLoop = eventLoop self.shutdownPromise = eventLoop.makePromise(of: Int.self) self.logger = logger + self.tracer = tracer self.configuration = configuration self.factory = factory } @@ -78,7 +83,7 @@ extension Lambda { var logger = self.logger logger[metadataKey: "lifecycleId"] = .string(self.configuration.lifecycle.id) - let runner = Runner(eventLoop: self.eventLoop, configuration: self.configuration) + let runner = Runner(eventLoop: self.eventLoop, configuration: self.configuration, tracer: self.tracer) let startupFuture = runner.initialize(logger: logger, factory: self.factory) startupFuture.flatMap { handler -> EventLoopFuture<(ByteBufferLambdaHandler, Result)> in diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift index 8fc22de3..8ca19b4c 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift @@ -12,22 +12,31 @@ // //===----------------------------------------------------------------------===// +import AWSXRaySDK // TODO: use swift-tracing when available +import Baggage import Dispatch import Logging import NIO +// type names defined in `TracingInstrument`, aliases will be removed +public typealias TracingInstrument = XRayRecorder +public typealias NoOpTracingInstrument = XRayNoOpRecorder + extension Lambda { /// LambdaRunner manages the Lambda runtime workflow, or business logic. internal final class Runner { private let runtimeClient: RuntimeClient + private let tracer: TracingInstrument private let eventLoop: EventLoop private let allocator: ByteBufferAllocator private var isGettingNextInvocation = false - init(eventLoop: EventLoop, configuration: Configuration) { + init(eventLoop: EventLoop, configuration: Configuration, tracer: TracingInstrument = NoOpTracingInstrument()) { self.eventLoop = eventLoop - self.runtimeClient = RuntimeClient(eventLoop: self.eventLoop, configuration: configuration.runtimeEngine) + self.runtimeClient = RuntimeClient(eventLoop: self.eventLoop, configuration: configuration.runtimeEngine, + tracer: tracer) + self.tracer = tracer self.allocator = ByteBufferAllocator() } @@ -60,15 +69,20 @@ extension Lambda { logger.debug("lambda invocation sequence starting") // 1. request invocation from lambda runtime engine self.isGettingNextInvocation = true + // we will get the trace context in the invocation + let startTime = XRayRecorder.Timestamp.now() return self.runtimeClient.getNextInvocation(logger: logger).peekError { error in logger.error("could not fetch work from lambda runtime engine: \(error)") }.flatMap { invocation, event in // 2. send invocation to handler self.isGettingNextInvocation = false let context = Context(logger: logger, + tracer: self.tracer, eventLoop: self.eventLoop, allocator: self.allocator, invocation: invocation) + let baggage = context.baggage + self.tracer.beginSegment(name: "getNextInvocation", baggage: context.baggage, startTime: startTime).end() logger.debug("sending invocation to lambda handler \(handler)") return handler.handle(context: context, event: event) // Hopping back to "our" EventLoop is importnant in case the handler returns a future that @@ -80,14 +94,19 @@ extension Lambda { if case .failure(let error) = result { logger.warning("lambda handler returned an error: \(error)") } - return (invocation, result) + return (invocation, result, baggage) } - }.flatMap { invocation, result in + }.flatMap { invocation, result, baggage in // 3. report results to runtime engine - self.runtimeClient.reportResults(logger: logger, invocation: invocation, result: result).peekError { error in - logger.error("could not report results to lambda runtime engine: \(error)") + self.tracer.segment(name: "ReportResults", baggage: baggage) { segment in + self.runtimeClient.reportResults(logger: logger, invocation: invocation, result: result, + context: segment.baggage).peekError { error in + logger.error("could not report results to lambda runtime engine: \(error)") + } } } + // flush the tracer after each invocation + .flush(self.tracer, recover: false) } /// cancels the current run, if we are waiting for next invocation (long poll from Lambda control plane) @@ -101,7 +120,7 @@ extension Lambda { } private extension Lambda.Context { - convenience init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator, invocation: Lambda.Invocation) { + convenience init(logger: Logger, tracer: TracingInstrument, eventLoop: EventLoop, allocator: ByteBufferAllocator, invocation: Lambda.Invocation) { self.init(requestID: invocation.requestID, traceID: invocation.traceID, invokedFunctionARN: invocation.invokedFunctionARN, @@ -109,6 +128,7 @@ private extension Lambda.Context { cognitoIdentity: invocation.cognitoIdentity, clientContext: invocation.clientContext, logger: logger, + tracer: tracer, eventLoop: eventLoop, allocator: allocator) } diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index 5e9e6aea..e6b9cd0b 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -12,6 +12,8 @@ // //===----------------------------------------------------------------------===// +import AWSXRayRecorder +import Baggage import Logging import NIO import NIOHTTP1 @@ -27,16 +29,18 @@ extension Lambda { private let allocator = ByteBufferAllocator() private let httpClient: HTTPClient - init(eventLoop: EventLoop, configuration: Configuration.RuntimeEngine) { + init(eventLoop: EventLoop, configuration: Configuration.RuntimeEngine, + tracer: TracingInstrument = NoOpTracingInstrument()) { self.eventLoop = eventLoop - self.httpClient = HTTPClient(eventLoop: eventLoop, configuration: configuration) + self.httpClient = HTTPClient(eventLoop: eventLoop, configuration: configuration, tracer: tracer) } /// Requests invocation from the control plane. func getNextInvocation(logger: Logger) -> EventLoopFuture<(Invocation, ByteBuffer)> { let url = Consts.invocationURLPrefix + Consts.getNextInvocationURLSuffix logger.debug("requesting work from lambda runtime engine using \(url)") - return self.httpClient.get(url: url, headers: RuntimeClient.defaultHeaders).flatMapThrowing { response in + // we will get the trace context in the invocation response + return self.httpClient.get(url: url, headers: RuntimeClient.defaultHeaders, context: .init()).flatMapThrowing { response in guard response.status == .ok else { throw RuntimeError.badStatusCode(response.status) } @@ -58,7 +62,7 @@ extension Lambda { } /// Reports a result to the Runtime Engine. - func reportResults(logger: Logger, invocation: Invocation, result: Result) -> EventLoopFuture { + func reportResults(logger: Logger, invocation: Invocation, result: Result, context: BaggageContext) -> EventLoopFuture { var url = Consts.invocationURLPrefix + "/" + invocation.requestID var body: ByteBuffer? let headers: HTTPHeaders @@ -77,7 +81,7 @@ extension Lambda { headers = RuntimeClient.errorHeaders } logger.debug("reporting results to lambda runtime engine using \(url)") - return self.httpClient.post(url: url, headers: headers, body: body).flatMapThrowing { response in + return self.httpClient.post(url: url, headers: headers, body: body, context: context).flatMapThrowing { response in guard response.status == .accepted else { throw RuntimeError.badStatusCode(response.status) } @@ -102,7 +106,7 @@ extension Lambda { var body = self.allocator.buffer(capacity: bytes.count) body.writeBytes(bytes) logger.warning("reporting initialization error to lambda runtime engine using \(url)") - return self.httpClient.post(url: url, headers: RuntimeClient.errorHeaders, body: body).flatMapThrowing { response in + return self.httpClient.post(url: url, headers: RuntimeClient.errorHeaders, body: body, context: .init()).flatMapThrowing { response in guard response.status == .accepted else { throw RuntimeError.badStatusCode(response.status) } diff --git a/Sources/AWSLambdaTesting/Lambda+Testing.swift b/Sources/AWSLambdaTesting/Lambda+Testing.swift index 981ca736..2dadddc4 100644 --- a/Sources/AWSLambdaTesting/Lambda+Testing.swift +++ b/Sources/AWSLambdaTesting/Lambda+Testing.swift @@ -102,6 +102,7 @@ extension Lambda { invokedFunctionARN: config.invokedFunctionARN, deadline: .now() + config.timeout, logger: logger, + tracer: NoOpTracingInstrument(), eventLoop: eventLoop, allocator: ByteBufferAllocator()) diff --git a/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift index 94c8ac62..00a2e4ce 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift @@ -263,7 +263,7 @@ class LambdaRuntimeClientTest: XCTestCase { 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"))) + let result = client.reportResults(logger: logger, invocation: invocation, result: Result.failure(TestError("boom")), context: .init()) var inboundHeader: HTTPServerRequestPart? XCTAssertNoThrow(inboundHeader = try server.readInbound()) @@ -303,7 +303,8 @@ class LambdaRuntimeClientTest: XCTestCase { 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)) + let result = client.reportResults(logger: logger, invocation: invocation, result: Result.success(nil), + context: .init()) var inboundHeader: HTTPServerRequestPart? XCTAssertNoThrow(inboundHeader = try server.readInbound()) diff --git a/Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift index 30fed618..5f67e395 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaTest.swift @@ -263,6 +263,7 @@ class LambdaTest: XCTestCase { cognitoIdentity: nil, clientContext: nil, logger: Logger(label: "test"), + tracer: NoOpTracingInstrument(), eventLoop: MultiThreadedEventLoopGroup(numberOfThreads: 1).next(), allocator: ByteBufferAllocator()) XCTAssertGreaterThan(context.deadline, .now()) @@ -274,6 +275,7 @@ class LambdaTest: XCTestCase { cognitoIdentity: context.cognitoIdentity, clientContext: context.clientContext, logger: context.logger, + tracer: NoOpTracingInstrument(), eventLoop: context.eventLoop, allocator: context.allocator) XCTAssertLessThan(expiredContext.deadline, .now()) @@ -287,6 +289,7 @@ class LambdaTest: XCTestCase { cognitoIdentity: nil, clientContext: nil, logger: Logger(label: "test"), + tracer: NoOpTracingInstrument(), eventLoop: MultiThreadedEventLoopGroup(numberOfThreads: 1).next(), allocator: ByteBufferAllocator()) XCTAssertLessThanOrEqual(context.getRemainingTime(), .seconds(1)) diff --git a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift index 9aa3f72a..4175fd11 100644 --- a/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift +++ b/Tests/AWSLambdaRuntimeTests/Lambda+CodeableTest.swift @@ -72,6 +72,7 @@ class CodableLambdaTest: XCTestCase { cognitoIdentity: nil, clientContext: nil, logger: Logger(label: "test"), + tracer: NoOpTracingInstrument(), eventLoop: self.eventLoopGroup.next(), allocator: ByteBufferAllocator()) }