From 76e1502a66512374530cd1fee9879e44e60655e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 28 Jun 2025 12:22:13 +0200 Subject: [PATCH 1/7] remove dependency on XCTest --- .gitignore | 3 +- .../ControlPlaneRequestEncoderTests.swift | 224 ++++++++++-------- .../LambdaRuntimeClientTests.swift | 2 +- .../MockLambdaServer.swift | 8 +- Tests/AWSLambdaRuntimeTests/UtilsTest.swift | 25 +- scripts/check-format-linux.sh | 40 ++++ scripts/check-format.sh | 45 ++++ 7 files changed, 234 insertions(+), 113 deletions(-) create mode 100755 scripts/check-format-linux.sh create mode 100755 scripts/check-format.sh diff --git a/.gitignore b/.gitignore index f7a26a78..b3b30ec1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ Package.resolved .serverless .vscode Makefile -.devcontainer \ No newline at end of file +.devcontainer +.amazonq \ No newline at end of file diff --git a/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift b/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift index 840a17c6..cdb5c1f3 100644 --- a/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift +++ b/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift @@ -15,148 +15,176 @@ import NIOCore import NIOEmbedded import NIOHTTP1 -import XCTest +import Testing + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif @testable import AWSLambdaRuntime -final class ControlPlaneRequestEncoderTests: XCTestCase { +struct ControlPlaneRequestEncoderTests { let host = "192.168.0.1" - var client: EmbeddedChannel! - var server: EmbeddedChannel! - - override func setUp() { - self.client = EmbeddedChannel(handler: ControlPlaneRequestEncoderHandler(host: self.host)) - self.server = EmbeddedChannel(handlers: [ + func createChannels() -> (client: EmbeddedChannel, server: EmbeddedChannel) { + let client = EmbeddedChannel(handler: ControlPlaneRequestEncoderHandler(host: self.host)) + let server = EmbeddedChannel(handlers: [ ByteToMessageHandler(HTTPRequestDecoder(leftOverBytesStrategy: .dropBytes)), NIOHTTPServerRequestAggregator(maxContentLength: 1024 * 1024), ]) + return (client, server) } - override func tearDown() { - XCTAssertNoThrow(try self.client.finish(acceptAlreadyClosed: false)) - XCTAssertNoThrow(try self.server.finish(acceptAlreadyClosed: false)) - self.client = nil - self.server = nil - } - - func testNextRequest() { - var request: NIOHTTPServerRequestFull? - XCTAssertNoThrow(request = try self.sendRequest(.next)) + @Test + func testNextRequest() throws { + let (client, server) = createChannels() + defer { + _ = try? client.finish(acceptAlreadyClosed: false) + _ = try? server.finish(acceptAlreadyClosed: false) + } + + let request = try sendRequest(.next, client: client, server: server) - XCTAssertEqual(request?.head.isKeepAlive, true) - XCTAssertEqual(request?.head.method, .GET) - XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/next") - XCTAssertEqual(request?.head.version, .http1_1) - XCTAssertEqual(request?.head.headers["host"], [self.host]) - XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent]) + #expect(request?.head.isKeepAlive == true) + #expect(request?.head.method == .GET) + #expect(request?.head.uri == "/2018-06-01/runtime/invocation/next") + #expect(request?.head.version == .http1_1) + #expect(request?.head.headers["host"] == [self.host]) + #expect(request?.head.headers["user-agent"] == [.userAgent]) - XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self)) + #expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil) } - func testPostInvocationSuccessWithoutBody() { + @Test + func testPostInvocationSuccessWithoutBody() throws { + let (client, server) = createChannels() + defer { + _ = try? client.finish(acceptAlreadyClosed: false) + _ = try? server.finish(acceptAlreadyClosed: false) + } + let requestID = UUID().uuidString - var request: NIOHTTPServerRequestFull? - XCTAssertNoThrow(request = try self.sendRequest(.invocationResponse(requestID, nil))) - - XCTAssertEqual(request?.head.isKeepAlive, true) - XCTAssertEqual(request?.head.method, .POST) - XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/response") - XCTAssertEqual(request?.head.version, .http1_1) - XCTAssertEqual(request?.head.headers["host"], [self.host]) - XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent]) - XCTAssertEqual(request?.head.headers["content-length"], ["0"]) - - XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self)) + let request = try sendRequest(.invocationResponse(requestID, nil), client: client, server: server) + + #expect(request?.head.isKeepAlive == true) + #expect(request?.head.method == .POST) + #expect(request?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response") + #expect(request?.head.version == .http1_1) + #expect(request?.head.headers["host"] == [self.host]) + #expect(request?.head.headers["user-agent"] == [.userAgent]) + #expect(request?.head.headers["content-length"] == ["0"]) + + #expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil) } - func testPostInvocationSuccessWithBody() { + @Test + func testPostInvocationSuccessWithBody() throws { + let (client, server) = createChannels() + defer { + _ = try? client.finish(acceptAlreadyClosed: false) + _ = try? server.finish(acceptAlreadyClosed: false) + } + let requestID = UUID().uuidString let payload = ByteBuffer(string: "hello swift lambda!") - var request: NIOHTTPServerRequestFull? - XCTAssertNoThrow(request = try self.sendRequest(.invocationResponse(requestID, payload))) + let request = try sendRequest(.invocationResponse(requestID, payload), client: client, server: server) - XCTAssertEqual(request?.head.isKeepAlive, true) - XCTAssertEqual(request?.head.method, .POST) - XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/response") - XCTAssertEqual(request?.head.version, .http1_1) - XCTAssertEqual(request?.head.headers["host"], [self.host]) - XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent]) - XCTAssertEqual(request?.head.headers["content-length"], ["\(payload.readableBytes)"]) - XCTAssertEqual(request?.body, payload) + #expect(request?.head.isKeepAlive == true) + #expect(request?.head.method == .POST) + #expect(request?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response") + #expect(request?.head.version == .http1_1) + #expect(request?.head.headers["host"] == [self.host]) + #expect(request?.head.headers["user-agent"] == [.userAgent]) + #expect(request?.head.headers["content-length"] == ["\(payload.readableBytes)"]) + #expect(request?.body == payload) - XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self)) + #expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil) } - func testPostInvocationErrorWithBody() { + @Test + func testPostInvocationErrorWithBody() throws { + let (client, server) = createChannels() + defer { + _ = try? client.finish(acceptAlreadyClosed: false) + _ = try? server.finish(acceptAlreadyClosed: false) + } + let requestID = UUID().uuidString let error = ErrorResponse(errorType: "SomeError", errorMessage: "An error happened") - var request: NIOHTTPServerRequestFull? - XCTAssertNoThrow(request = try self.sendRequest(.invocationError(requestID, error))) - - XCTAssertEqual(request?.head.isKeepAlive, true) - XCTAssertEqual(request?.head.method, .POST) - XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/error") - XCTAssertEqual(request?.head.version, .http1_1) - XCTAssertEqual(request?.head.headers["host"], [self.host]) - XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent]) - XCTAssertEqual(request?.head.headers["lambda-runtime-function-error-type"], ["Unhandled"]) + let request = try sendRequest(.invocationError(requestID, error), client: client, server: server) + + #expect(request?.head.isKeepAlive == true) + #expect(request?.head.method == .POST) + #expect(request?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/error") + #expect(request?.head.version == .http1_1) + #expect(request?.head.headers["host"] == [self.host]) + #expect(request?.head.headers["user-agent"] == [.userAgent]) + #expect(request?.head.headers["lambda-runtime-function-error-type"] == ["Unhandled"]) let expectedBody = #"{"errorType":"SomeError","errorMessage":"An error happened"}"# - XCTAssertEqual(request?.head.headers["content-length"], ["\(expectedBody.utf8.count)"]) - XCTAssertEqual( - try request?.body?.getString(at: 0, length: XCTUnwrap(request?.body?.readableBytes)), - expectedBody - ) + #expect(request?.head.headers["content-length"] == ["\(expectedBody.utf8.count)"]) + let bodyString = request?.body?.getString(at: 0, length: request?.body?.readableBytes ?? 0) + #expect(bodyString == expectedBody) - XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self)) + #expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil) } - func testPostStartupError() { + @Test + func testPostStartupError() throws { + let (client, server) = createChannels() + defer { + _ = try? client.finish(acceptAlreadyClosed: false) + _ = try? server.finish(acceptAlreadyClosed: false) + } + let error = ErrorResponse(errorType: "StartupError", errorMessage: "Urgh! Startup failed. 😨") - var request: NIOHTTPServerRequestFull? - XCTAssertNoThrow(request = try self.sendRequest(.initializationError(error))) - - XCTAssertEqual(request?.head.isKeepAlive, true) - XCTAssertEqual(request?.head.method, .POST) - XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/init/error") - XCTAssertEqual(request?.head.version, .http1_1) - XCTAssertEqual(request?.head.headers["host"], [self.host]) - XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent]) - XCTAssertEqual(request?.head.headers["lambda-runtime-function-error-type"], ["Unhandled"]) + let request = try sendRequest(.initializationError(error), client: client, server: server) + + #expect(request?.head.isKeepAlive == true) + #expect(request?.head.method == .POST) + #expect(request?.head.uri == "/2018-06-01/runtime/init/error") + #expect(request?.head.version == .http1_1) + #expect(request?.head.headers["host"] == [self.host]) + #expect(request?.head.headers["user-agent"] == [.userAgent]) + #expect(request?.head.headers["lambda-runtime-function-error-type"] == ["Unhandled"]) let expectedBody = #"{"errorType":"StartupError","errorMessage":"Urgh! Startup failed. 😨"}"# - XCTAssertEqual(request?.head.headers["content-length"], ["\(expectedBody.utf8.count)"]) - XCTAssertEqual( - try request?.body?.getString(at: 0, length: XCTUnwrap(request?.body?.readableBytes)), - expectedBody - ) + #expect(request?.head.headers["content-length"] == ["\(expectedBody.utf8.count)"]) + let bodyString = request?.body?.getString(at: 0, length: request?.body?.readableBytes ?? 0) + #expect(bodyString == expectedBody) - XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self)) + #expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil) } - func testMultipleNextAndResponseSuccessRequests() { + @Test + func testMultipleNextAndResponseSuccessRequests() throws { + let (client, server) = createChannels() + defer { + _ = try? client.finish(acceptAlreadyClosed: false) + _ = try? server.finish(acceptAlreadyClosed: false) + } + for _ in 0..<1000 { - var nextRequest: NIOHTTPServerRequestFull? - XCTAssertNoThrow(nextRequest = try self.sendRequest(.next)) - XCTAssertEqual(nextRequest?.head.method, .GET) - XCTAssertEqual(nextRequest?.head.uri, "/2018-06-01/runtime/invocation/next") + let nextRequest = try sendRequest(.next, client: client, server: server) + #expect(nextRequest?.head.method == .GET) + #expect(nextRequest?.head.uri == "/2018-06-01/runtime/invocation/next") let requestID = UUID().uuidString let payload = ByteBuffer(string: "hello swift lambda!") - var successRequest: NIOHTTPServerRequestFull? - XCTAssertNoThrow(successRequest = try self.sendRequest(.invocationResponse(requestID, payload))) - XCTAssertEqual(successRequest?.head.method, .POST) - XCTAssertEqual(successRequest?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/response") + let successRequest = try sendRequest(.invocationResponse(requestID, payload), client: client, server: server) + #expect(successRequest?.head.method == .POST) + #expect(successRequest?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response") } } - func sendRequest(_ request: ControlPlaneRequest) throws -> NIOHTTPServerRequestFull? { - try self.client.writeOutbound(request) - while let part = try self.client.readOutbound(as: ByteBuffer.self) { - XCTAssertNoThrow(try self.server.writeInbound(part)) + func sendRequest(_ request: ControlPlaneRequest, client: EmbeddedChannel, server: EmbeddedChannel) throws -> NIOHTTPServerRequestFull? { + try client.writeOutbound(request) + while let part = try client.readOutbound(as: ByteBuffer.self) { + try server.writeInbound(part) } - return try self.server.readInbound(as: NIOHTTPServerRequestFull.self) + return try server.readInbound(as: NIOHTTPServerRequestFull.self) } } diff --git a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift b/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift index 53afbaf6..b9076e22 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift +++ b/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift @@ -26,7 +26,7 @@ struct LambdaRuntimeClientTests { let logger = { var logger = Logger(label: "NewLambdaClientRuntimeTest") - logger.logLevel = .trace + // logger.logLevel = .trace return logger }() diff --git a/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift b/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift index 11f43ba4..bb1dce4c 100644 --- a/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift +++ b/Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift @@ -100,16 +100,16 @@ final class MockLambdaServer { guard let localAddress = channel.localAddress else { throw ServerError.cantBind } - self.logger.info("\(self) started and listening on \(localAddress)") + self.logger.trace("\(self) started and listening on \(localAddress)") return localAddress.port! } fileprivate func stop() async throws { - self.logger.info("stopping \(self)") + self.logger.trace("stopping \(self)") let channel = self.channel! try? await channel.close().get() self.shutdown = true - self.logger.info("\(self) stopped") + self.logger.trace("\(self) stopped") } } @@ -150,7 +150,7 @@ final class HTTPHandler: ChannelInboundHandler { } func processRequest(context: ChannelHandlerContext, request: (head: HTTPRequestHead, body: ByteBuffer?)) { - self.logger.info("\(self) processing \(request.head.uri)") + self.logger.trace("\(self) processing \(request.head.uri)") let requestBody = request.body.flatMap { (buffer: ByteBuffer) -> String? in var buffer = buffer diff --git a/Tests/AWSLambdaRuntimeTests/UtilsTest.swift b/Tests/AWSLambdaRuntimeTests/UtilsTest.swift index 0b3b5917..96d756e4 100644 --- a/Tests/AWSLambdaRuntimeTests/UtilsTest.swift +++ b/Tests/AWSLambdaRuntimeTests/UtilsTest.swift @@ -12,11 +12,18 @@ // //===----------------------------------------------------------------------===// -import XCTest +import Testing @testable import AWSLambdaRuntime -class UtilsTest: XCTestCase { +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +struct UtilsTest { + @Test func testGenerateXRayTraceID() { // the time and identifier should be in hexadecimal digits let invalidCharacters = CharacterSet(charactersIn: "abcdef0123456789").inverted @@ -26,15 +33,15 @@ class UtilsTest: XCTestCase { // check the format, see https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids) let traceId = AmazonHeaders.generateXRayTraceID() let segments = traceId.split(separator: "-") - XCTAssertEqual(3, segments.count) - XCTAssertEqual("1", segments[0]) - XCTAssertEqual(8, segments[1].count) - XCTAssertNil(segments[1].rangeOfCharacter(from: invalidCharacters)) - XCTAssertEqual(24, segments[2].count) - XCTAssertNil(segments[2].rangeOfCharacter(from: invalidCharacters)) + #expect(segments.count == 3) + #expect(segments[0] == "1") + #expect(segments[1].count == 8) + #expect(segments[1].rangeOfCharacter(from: invalidCharacters) == nil) + #expect(segments[2].count == 24) + #expect(segments[2].rangeOfCharacter(from: invalidCharacters) == nil) values.insert(traceId) } // check that the generated values are different - XCTAssertEqual(values.count, numTests) + #expect(values.count == numTests) } } diff --git a/scripts/check-format-linux.sh b/scripts/check-format-linux.sh new file mode 100755 index 00000000..798f11cb --- /dev/null +++ b/scripts/check-format-linux.sh @@ -0,0 +1,40 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift.org open source project +## +## Copyright (c) 2025 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 with Runtime Library Exception +## +## See https://swift.org/LICENSE.txt for license information +## See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +## +##===----------------------------------------------------------------------===## + +set +x +set -euo pipefail + +SWIFT_IMAGE=swift:latest +CHECK_FORMAT_SCRIPT=https://raw.githubusercontent.com/swiftlang/github-workflows/refs/heads/main/.github/workflows/scripts/check-swift-format.sh + +echo "Downloading check-swift-format.sh" +curl -s ${CHECK_FORMAT_SCRIPT} > format.sh && chmod u+x format.sh + +echo "Running check-swift-format.sh" +/usr/local/bin/container run --rm -v $(pwd):/workspace -w /workspace ${SWIFT_IMAGE} bash -clx "./format.sh" + +echo "Cleaning up" +rm format.sh + +YAML_LINT=https://raw.githubusercontent.com/swiftlang/github-workflows/refs/heads/main/.github/workflows/configs/yamllint.yml +YAML_IMAGE=ubuntu:latest + +echo "Downloading yamllint.yml" +curl -s ${YAML_LINT} > yamllint.yml + +echo "Running yamllint" +/usr/local/bin/container run --rm -v $(pwd):/workspace -w /workspace ${YAML_IMAGE} bash -clx "apt-get -qq update && apt-get -qq -y install yamllint && yamllint --strict --config-file /workspace/yamllint.yml .github" + +echo "Cleaning up" +rm yamllint.yml + diff --git a/scripts/check-format.sh b/scripts/check-format.sh new file mode 100755 index 00000000..a3c32216 --- /dev/null +++ b/scripts/check-format.sh @@ -0,0 +1,45 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift.org open source project +## +## Copyright (c) 2024 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 with Runtime Library Exception +## +## See https://swift.org/LICENSE.txt for license information +## See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +## +##===----------------------------------------------------------------------===## + +set -euo pipefail + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } + + +if [[ -f .swiftformatignore ]]; then + log "Found swiftformatignore file..." + + log "Running swift format format..." + tr '\n' '\0' < .swiftformatignore| xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place + + log "Running swift format lint..." + + tr '\n' '\0' < .swiftformatignore | xargs -0 -I% printf '":(exclude)%" '| xargs git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel +else + log "Running swift format format..." + git ls-files -z '*.swift' | xargs -0 swift format format --parallel --in-place + + log "Running swift format lint..." + + git ls-files -z '*.swift' | xargs -0 swift format lint --strict --parallel +fi + + + +log "Checking for modified files..." + +GIT_PAGER='' git diff --exit-code '*.swift' + +log "✅ Found no formatting issues." From 0751cd61824066f36bcb9b87da16bd1a87bf4af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 28 Jun 2025 12:24:28 +0200 Subject: [PATCH 2/7] swift format --- .../ControlPlaneRequestEncoderTests.swift | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift b/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift index cdb5c1f3..b1c22a58 100644 --- a/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift +++ b/Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift @@ -17,14 +17,14 @@ import NIOEmbedded import NIOHTTP1 import Testing +@testable import AWSLambdaRuntime + #if canImport(FoundationEssentials) import FoundationEssentials #else import Foundation #endif -@testable import AWSLambdaRuntime - struct ControlPlaneRequestEncoderTests { let host = "192.168.0.1" @@ -44,7 +44,7 @@ struct ControlPlaneRequestEncoderTests { _ = try? client.finish(acceptAlreadyClosed: false) _ = try? server.finish(acceptAlreadyClosed: false) } - + let request = try sendRequest(.next, client: client, server: server) #expect(request?.head.isKeepAlive == true) @@ -64,7 +64,7 @@ struct ControlPlaneRequestEncoderTests { _ = try? client.finish(acceptAlreadyClosed: false) _ = try? server.finish(acceptAlreadyClosed: false) } - + let requestID = UUID().uuidString let request = try sendRequest(.invocationResponse(requestID, nil), client: client, server: server) @@ -86,7 +86,7 @@ struct ControlPlaneRequestEncoderTests { _ = try? client.finish(acceptAlreadyClosed: false) _ = try? server.finish(acceptAlreadyClosed: false) } - + let requestID = UUID().uuidString let payload = ByteBuffer(string: "hello swift lambda!") @@ -111,7 +111,7 @@ struct ControlPlaneRequestEncoderTests { _ = try? client.finish(acceptAlreadyClosed: false) _ = try? server.finish(acceptAlreadyClosed: false) } - + let requestID = UUID().uuidString let error = ErrorResponse(errorType: "SomeError", errorMessage: "An error happened") let request = try sendRequest(.invocationError(requestID, error), client: client, server: server) @@ -139,7 +139,7 @@ struct ControlPlaneRequestEncoderTests { _ = try? client.finish(acceptAlreadyClosed: false) _ = try? server.finish(acceptAlreadyClosed: false) } - + let error = ErrorResponse(errorType: "StartupError", errorMessage: "Urgh! Startup failed. 😨") let request = try sendRequest(.initializationError(error), client: client, server: server) @@ -165,7 +165,7 @@ struct ControlPlaneRequestEncoderTests { _ = try? client.finish(acceptAlreadyClosed: false) _ = try? server.finish(acceptAlreadyClosed: false) } - + for _ in 0..<1000 { let nextRequest = try sendRequest(.next, client: client, server: server) #expect(nextRequest?.head.method == .GET) @@ -173,13 +173,21 @@ struct ControlPlaneRequestEncoderTests { let requestID = UUID().uuidString let payload = ByteBuffer(string: "hello swift lambda!") - let successRequest = try sendRequest(.invocationResponse(requestID, payload), client: client, server: server) + let successRequest = try sendRequest( + .invocationResponse(requestID, payload), + client: client, + server: server + ) #expect(successRequest?.head.method == .POST) #expect(successRequest?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response") } } - func sendRequest(_ request: ControlPlaneRequest, client: EmbeddedChannel, server: EmbeddedChannel) throws -> NIOHTTPServerRequestFull? { + func sendRequest( + _ request: ControlPlaneRequest, + client: EmbeddedChannel, + server: EmbeddedChannel + ) throws -> NIOHTTPServerRequestFull? { try client.writeOutbound(request) while let part = try client.readOutbound(as: ByteBuffer.self) { try server.writeInbound(part) From 88501016eaaf316f2f856f633f4573c5992caadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 28 Jun 2025 12:25:42 +0200 Subject: [PATCH 3/7] Update Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift b/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift index b9076e22..33ebde3f 100644 --- a/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift +++ b/Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift @@ -26,6 +26,7 @@ struct LambdaRuntimeClientTests { let logger = { var logger = Logger(label: "NewLambdaClientRuntimeTest") + // Uncomment the line below to enable trace-level logging for debugging purposes. // logger.logLevel = .trace return logger }() From efb67d2e6ffdaed196e488802fbad6490847619a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 28 Jun 2025 12:28:57 +0200 Subject: [PATCH 4/7] fix shell syntax and license header --- scripts/check-format-linux.sh | 19 ++++++++++++++++--- scripts/check-format.sh | 15 ++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/scripts/check-format-linux.sh b/scripts/check-format-linux.sh index 798f11cb..16c9acc2 100755 --- a/scripts/check-format-linux.sh +++ b/scripts/check-format-linux.sh @@ -1,9 +1,22 @@ #!/bin/bash ##===----------------------------------------------------------------------===## ## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2025 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## +##===----------------------------------------------------------------------===## +## ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2025 Apple Inc. and the Swift project authors +## Copyright (c) 2020 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See https://swift.org/LICENSE.txt for license information @@ -21,7 +34,7 @@ echo "Downloading check-swift-format.sh" curl -s ${CHECK_FORMAT_SCRIPT} > format.sh && chmod u+x format.sh echo "Running check-swift-format.sh" -/usr/local/bin/container run --rm -v $(pwd):/workspace -w /workspace ${SWIFT_IMAGE} bash -clx "./format.sh" +/usr/local/bin/container run --rm -v "$(pwd):/workspace" -w /workspace ${SWIFT_IMAGE} bash -clx "./format.sh" echo "Cleaning up" rm format.sh @@ -33,7 +46,7 @@ echo "Downloading yamllint.yml" curl -s ${YAML_LINT} > yamllint.yml echo "Running yamllint" -/usr/local/bin/container run --rm -v $(pwd):/workspace -w /workspace ${YAML_IMAGE} bash -clx "apt-get -qq update && apt-get -qq -y install yamllint && yamllint --strict --config-file /workspace/yamllint.yml .github" +/usr/local/bin/container run --rm -v "$(pwd):/workspace" -w /workspace ${YAML_IMAGE} bash -clx "apt-get -qq update && apt-get -qq -y install yamllint && yamllint --strict --config-file /workspace/yamllint.yml .github" echo "Cleaning up" rm yamllint.yml diff --git a/scripts/check-format.sh b/scripts/check-format.sh index a3c32216..51fd80ac 100755 --- a/scripts/check-format.sh +++ b/scripts/check-format.sh @@ -1,9 +1,22 @@ #!/bin/bash ##===----------------------------------------------------------------------===## ## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2025 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## +##===----------------------------------------------------------------------===## +## ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2024 Apple Inc. and the Swift project authors +## Copyright (c) 2020 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See https://swift.org/LICENSE.txt for license information From 96f0d05a111b8b64573f3be8f8b2e364b15d04df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 28 Jun 2025 12:38:10 +0200 Subject: [PATCH 5/7] fix license header --- scripts/check-format-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-format-linux.sh b/scripts/check-format-linux.sh index 16c9acc2..a5b06c49 100755 --- a/scripts/check-format-linux.sh +++ b/scripts/check-format-linux.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash ##===----------------------------------------------------------------------===## ## ## This source file is part of the SwiftAWSLambdaRuntime open source project From c3308e35dec362445ebd49740a2d4278709977bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Sat, 28 Jun 2025 12:53:28 +0200 Subject: [PATCH 6/7] remove dependency on CharcaterSet --- Tests/AWSLambdaRuntimeTests/UtilsTest.swift | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Tests/AWSLambdaRuntimeTests/UtilsTest.swift b/Tests/AWSLambdaRuntimeTests/UtilsTest.swift index 96d756e4..7f31ced3 100644 --- a/Tests/AWSLambdaRuntimeTests/UtilsTest.swift +++ b/Tests/AWSLambdaRuntimeTests/UtilsTest.swift @@ -16,29 +16,23 @@ import Testing @testable import AWSLambdaRuntime -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - struct UtilsTest { @Test func testGenerateXRayTraceID() { - // the time and identifier should be in hexadecimal digits - let invalidCharacters = CharacterSet(charactersIn: "abcdef0123456789").inverted let numTests = 1000 var values = Set() for _ in 0.. Date: Sat, 28 Jun 2025 12:58:47 +0200 Subject: [PATCH 7/7] move constant outside of loop --- Tests/AWSLambdaRuntimeTests/UtilsTest.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/AWSLambdaRuntimeTests/UtilsTest.swift b/Tests/AWSLambdaRuntimeTests/UtilsTest.swift index 7f31ced3..15a5fd27 100644 --- a/Tests/AWSLambdaRuntimeTests/UtilsTest.swift +++ b/Tests/AWSLambdaRuntimeTests/UtilsTest.swift @@ -19,11 +19,11 @@ import Testing struct UtilsTest { @Test func testGenerateXRayTraceID() { + // the time and identifier should be in hexadecimal digits + let allowedCharacters = "0123456789abcdef" let numTests = 1000 var values = Set() for _ in 0..