Skip to content

Commit 935ea0f

Browse files
sebstoCopilot
andauthored
Remove dependency on XCTest (#516)
Remove dependency on XCTest ### Motivation: As 6.1 does not include XCTest anymore, finish the migration to Swift testing ### Modifications: Replace XCTest by Swift Testing in two files ### Result: `swift test` works on 6.1.2 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 41c5eda commit 935ea0f

File tree

7 files changed

+263
-113
lines changed

7 files changed

+263
-113
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ Package.resolved
1111
.serverless
1212
.vscode
1313
Makefile
14-
.devcontainer
14+
.devcontainer
15+
.amazonq

Tests/AWSLambdaRuntimeTests/ControlPlaneRequestEncoderTests.swift

Lines changed: 133 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -15,148 +15,184 @@
1515
import NIOCore
1616
import NIOEmbedded
1717
import NIOHTTP1
18-
import XCTest
18+
import Testing
1919

2020
@testable import AWSLambdaRuntime
2121

22-
final class ControlPlaneRequestEncoderTests: XCTestCase {
23-
let host = "192.168.0.1"
22+
#if canImport(FoundationEssentials)
23+
import FoundationEssentials
24+
#else
25+
import Foundation
26+
#endif
2427

25-
var client: EmbeddedChannel!
26-
var server: EmbeddedChannel!
28+
struct ControlPlaneRequestEncoderTests {
29+
let host = "192.168.0.1"
2730

28-
override func setUp() {
29-
self.client = EmbeddedChannel(handler: ControlPlaneRequestEncoderHandler(host: self.host))
30-
self.server = EmbeddedChannel(handlers: [
31+
func createChannels() -> (client: EmbeddedChannel, server: EmbeddedChannel) {
32+
let client = EmbeddedChannel(handler: ControlPlaneRequestEncoderHandler(host: self.host))
33+
let server = EmbeddedChannel(handlers: [
3134
ByteToMessageHandler(HTTPRequestDecoder(leftOverBytesStrategy: .dropBytes)),
3235
NIOHTTPServerRequestAggregator(maxContentLength: 1024 * 1024),
3336
])
37+
return (client, server)
3438
}
3539

36-
override func tearDown() {
37-
XCTAssertNoThrow(try self.client.finish(acceptAlreadyClosed: false))
38-
XCTAssertNoThrow(try self.server.finish(acceptAlreadyClosed: false))
39-
self.client = nil
40-
self.server = nil
41-
}
40+
@Test
41+
func testNextRequest() throws {
42+
let (client, server) = createChannels()
43+
defer {
44+
_ = try? client.finish(acceptAlreadyClosed: false)
45+
_ = try? server.finish(acceptAlreadyClosed: false)
46+
}
4247

43-
func testNextRequest() {
44-
var request: NIOHTTPServerRequestFull?
45-
XCTAssertNoThrow(request = try self.sendRequest(.next))
48+
let request = try sendRequest(.next, client: client, server: server)
4649

47-
XCTAssertEqual(request?.head.isKeepAlive, true)
48-
XCTAssertEqual(request?.head.method, .GET)
49-
XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/next")
50-
XCTAssertEqual(request?.head.version, .http1_1)
51-
XCTAssertEqual(request?.head.headers["host"], [self.host])
52-
XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent])
50+
#expect(request?.head.isKeepAlive == true)
51+
#expect(request?.head.method == .GET)
52+
#expect(request?.head.uri == "/2018-06-01/runtime/invocation/next")
53+
#expect(request?.head.version == .http1_1)
54+
#expect(request?.head.headers["host"] == [self.host])
55+
#expect(request?.head.headers["user-agent"] == [.userAgent])
5356

54-
XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self))
57+
#expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil)
5558
}
5659

57-
func testPostInvocationSuccessWithoutBody() {
60+
@Test
61+
func testPostInvocationSuccessWithoutBody() throws {
62+
let (client, server) = createChannels()
63+
defer {
64+
_ = try? client.finish(acceptAlreadyClosed: false)
65+
_ = try? server.finish(acceptAlreadyClosed: false)
66+
}
67+
5868
let requestID = UUID().uuidString
59-
var request: NIOHTTPServerRequestFull?
60-
XCTAssertNoThrow(request = try self.sendRequest(.invocationResponse(requestID, nil)))
61-
62-
XCTAssertEqual(request?.head.isKeepAlive, true)
63-
XCTAssertEqual(request?.head.method, .POST)
64-
XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/response")
65-
XCTAssertEqual(request?.head.version, .http1_1)
66-
XCTAssertEqual(request?.head.headers["host"], [self.host])
67-
XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent])
68-
XCTAssertEqual(request?.head.headers["content-length"], ["0"])
69-
70-
XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self))
69+
let request = try sendRequest(.invocationResponse(requestID, nil), client: client, server: server)
70+
71+
#expect(request?.head.isKeepAlive == true)
72+
#expect(request?.head.method == .POST)
73+
#expect(request?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response")
74+
#expect(request?.head.version == .http1_1)
75+
#expect(request?.head.headers["host"] == [self.host])
76+
#expect(request?.head.headers["user-agent"] == [.userAgent])
77+
#expect(request?.head.headers["content-length"] == ["0"])
78+
79+
#expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil)
7180
}
7281

73-
func testPostInvocationSuccessWithBody() {
82+
@Test
83+
func testPostInvocationSuccessWithBody() throws {
84+
let (client, server) = createChannels()
85+
defer {
86+
_ = try? client.finish(acceptAlreadyClosed: false)
87+
_ = try? server.finish(acceptAlreadyClosed: false)
88+
}
89+
7490
let requestID = UUID().uuidString
7591
let payload = ByteBuffer(string: "hello swift lambda!")
7692

77-
var request: NIOHTTPServerRequestFull?
78-
XCTAssertNoThrow(request = try self.sendRequest(.invocationResponse(requestID, payload)))
93+
let request = try sendRequest(.invocationResponse(requestID, payload), client: client, server: server)
7994

80-
XCTAssertEqual(request?.head.isKeepAlive, true)
81-
XCTAssertEqual(request?.head.method, .POST)
82-
XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/response")
83-
XCTAssertEqual(request?.head.version, .http1_1)
84-
XCTAssertEqual(request?.head.headers["host"], [self.host])
85-
XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent])
86-
XCTAssertEqual(request?.head.headers["content-length"], ["\(payload.readableBytes)"])
87-
XCTAssertEqual(request?.body, payload)
95+
#expect(request?.head.isKeepAlive == true)
96+
#expect(request?.head.method == .POST)
97+
#expect(request?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response")
98+
#expect(request?.head.version == .http1_1)
99+
#expect(request?.head.headers["host"] == [self.host])
100+
#expect(request?.head.headers["user-agent"] == [.userAgent])
101+
#expect(request?.head.headers["content-length"] == ["\(payload.readableBytes)"])
102+
#expect(request?.body == payload)
88103

89-
XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self))
104+
#expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil)
90105
}
91106

92-
func testPostInvocationErrorWithBody() {
107+
@Test
108+
func testPostInvocationErrorWithBody() throws {
109+
let (client, server) = createChannels()
110+
defer {
111+
_ = try? client.finish(acceptAlreadyClosed: false)
112+
_ = try? server.finish(acceptAlreadyClosed: false)
113+
}
114+
93115
let requestID = UUID().uuidString
94116
let error = ErrorResponse(errorType: "SomeError", errorMessage: "An error happened")
95-
var request: NIOHTTPServerRequestFull?
96-
XCTAssertNoThrow(request = try self.sendRequest(.invocationError(requestID, error)))
97-
98-
XCTAssertEqual(request?.head.isKeepAlive, true)
99-
XCTAssertEqual(request?.head.method, .POST)
100-
XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/error")
101-
XCTAssertEqual(request?.head.version, .http1_1)
102-
XCTAssertEqual(request?.head.headers["host"], [self.host])
103-
XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent])
104-
XCTAssertEqual(request?.head.headers["lambda-runtime-function-error-type"], ["Unhandled"])
117+
let request = try sendRequest(.invocationError(requestID, error), client: client, server: server)
118+
119+
#expect(request?.head.isKeepAlive == true)
120+
#expect(request?.head.method == .POST)
121+
#expect(request?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/error")
122+
#expect(request?.head.version == .http1_1)
123+
#expect(request?.head.headers["host"] == [self.host])
124+
#expect(request?.head.headers["user-agent"] == [.userAgent])
125+
#expect(request?.head.headers["lambda-runtime-function-error-type"] == ["Unhandled"])
105126
let expectedBody = #"{"errorType":"SomeError","errorMessage":"An error happened"}"#
106127

107-
XCTAssertEqual(request?.head.headers["content-length"], ["\(expectedBody.utf8.count)"])
108-
XCTAssertEqual(
109-
try request?.body?.getString(at: 0, length: XCTUnwrap(request?.body?.readableBytes)),
110-
expectedBody
111-
)
128+
#expect(request?.head.headers["content-length"] == ["\(expectedBody.utf8.count)"])
129+
let bodyString = request?.body?.getString(at: 0, length: request?.body?.readableBytes ?? 0)
130+
#expect(bodyString == expectedBody)
112131

113-
XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self))
132+
#expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil)
114133
}
115134

116-
func testPostStartupError() {
135+
@Test
136+
func testPostStartupError() throws {
137+
let (client, server) = createChannels()
138+
defer {
139+
_ = try? client.finish(acceptAlreadyClosed: false)
140+
_ = try? server.finish(acceptAlreadyClosed: false)
141+
}
142+
117143
let error = ErrorResponse(errorType: "StartupError", errorMessage: "Urgh! Startup failed. 😨")
118-
var request: NIOHTTPServerRequestFull?
119-
XCTAssertNoThrow(request = try self.sendRequest(.initializationError(error)))
120-
121-
XCTAssertEqual(request?.head.isKeepAlive, true)
122-
XCTAssertEqual(request?.head.method, .POST)
123-
XCTAssertEqual(request?.head.uri, "/2018-06-01/runtime/init/error")
124-
XCTAssertEqual(request?.head.version, .http1_1)
125-
XCTAssertEqual(request?.head.headers["host"], [self.host])
126-
XCTAssertEqual(request?.head.headers["user-agent"], [.userAgent])
127-
XCTAssertEqual(request?.head.headers["lambda-runtime-function-error-type"], ["Unhandled"])
144+
let request = try sendRequest(.initializationError(error), client: client, server: server)
145+
146+
#expect(request?.head.isKeepAlive == true)
147+
#expect(request?.head.method == .POST)
148+
#expect(request?.head.uri == "/2018-06-01/runtime/init/error")
149+
#expect(request?.head.version == .http1_1)
150+
#expect(request?.head.headers["host"] == [self.host])
151+
#expect(request?.head.headers["user-agent"] == [.userAgent])
152+
#expect(request?.head.headers["lambda-runtime-function-error-type"] == ["Unhandled"])
128153
let expectedBody = #"{"errorType":"StartupError","errorMessage":"Urgh! Startup failed. 😨"}"#
129-
XCTAssertEqual(request?.head.headers["content-length"], ["\(expectedBody.utf8.count)"])
130-
XCTAssertEqual(
131-
try request?.body?.getString(at: 0, length: XCTUnwrap(request?.body?.readableBytes)),
132-
expectedBody
133-
)
154+
#expect(request?.head.headers["content-length"] == ["\(expectedBody.utf8.count)"])
155+
let bodyString = request?.body?.getString(at: 0, length: request?.body?.readableBytes ?? 0)
156+
#expect(bodyString == expectedBody)
134157

135-
XCTAssertNil(try self.server.readInbound(as: NIOHTTPServerRequestFull.self))
158+
#expect(try server.readInbound(as: NIOHTTPServerRequestFull.self) == nil)
136159
}
137160

138-
func testMultipleNextAndResponseSuccessRequests() {
161+
@Test
162+
func testMultipleNextAndResponseSuccessRequests() throws {
163+
let (client, server) = createChannels()
164+
defer {
165+
_ = try? client.finish(acceptAlreadyClosed: false)
166+
_ = try? server.finish(acceptAlreadyClosed: false)
167+
}
168+
139169
for _ in 0..<1000 {
140-
var nextRequest: NIOHTTPServerRequestFull?
141-
XCTAssertNoThrow(nextRequest = try self.sendRequest(.next))
142-
XCTAssertEqual(nextRequest?.head.method, .GET)
143-
XCTAssertEqual(nextRequest?.head.uri, "/2018-06-01/runtime/invocation/next")
170+
let nextRequest = try sendRequest(.next, client: client, server: server)
171+
#expect(nextRequest?.head.method == .GET)
172+
#expect(nextRequest?.head.uri == "/2018-06-01/runtime/invocation/next")
144173

145174
let requestID = UUID().uuidString
146175
let payload = ByteBuffer(string: "hello swift lambda!")
147-
var successRequest: NIOHTTPServerRequestFull?
148-
XCTAssertNoThrow(successRequest = try self.sendRequest(.invocationResponse(requestID, payload)))
149-
XCTAssertEqual(successRequest?.head.method, .POST)
150-
XCTAssertEqual(successRequest?.head.uri, "/2018-06-01/runtime/invocation/\(requestID)/response")
176+
let successRequest = try sendRequest(
177+
.invocationResponse(requestID, payload),
178+
client: client,
179+
server: server
180+
)
181+
#expect(successRequest?.head.method == .POST)
182+
#expect(successRequest?.head.uri == "/2018-06-01/runtime/invocation/\(requestID)/response")
151183
}
152184
}
153185

154-
func sendRequest(_ request: ControlPlaneRequest) throws -> NIOHTTPServerRequestFull? {
155-
try self.client.writeOutbound(request)
156-
while let part = try self.client.readOutbound(as: ByteBuffer.self) {
157-
XCTAssertNoThrow(try self.server.writeInbound(part))
186+
func sendRequest(
187+
_ request: ControlPlaneRequest,
188+
client: EmbeddedChannel,
189+
server: EmbeddedChannel
190+
) throws -> NIOHTTPServerRequestFull? {
191+
try client.writeOutbound(request)
192+
while let part = try client.readOutbound(as: ByteBuffer.self) {
193+
try server.writeInbound(part)
158194
}
159-
return try self.server.readInbound(as: NIOHTTPServerRequestFull.self)
195+
return try server.readInbound(as: NIOHTTPServerRequestFull.self)
160196
}
161197
}
162198

Tests/AWSLambdaRuntimeTests/LambdaRuntimeClientTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ struct LambdaRuntimeClientTests {
2626

2727
let logger = {
2828
var logger = Logger(label: "NewLambdaClientRuntimeTest")
29-
logger.logLevel = .trace
29+
// Uncomment the line below to enable trace-level logging for debugging purposes.
30+
// logger.logLevel = .trace
3031
return logger
3132
}()
3233

Tests/AWSLambdaRuntimeTests/MockLambdaServer.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,16 @@ final class MockLambdaServer<Behavior: LambdaServerBehavior> {
100100
guard let localAddress = channel.localAddress else {
101101
throw ServerError.cantBind
102102
}
103-
self.logger.info("\(self) started and listening on \(localAddress)")
103+
self.logger.trace("\(self) started and listening on \(localAddress)")
104104
return localAddress.port!
105105
}
106106

107107
fileprivate func stop() async throws {
108-
self.logger.info("stopping \(self)")
108+
self.logger.trace("stopping \(self)")
109109
let channel = self.channel!
110110
try? await channel.close().get()
111111
self.shutdown = true
112-
self.logger.info("\(self) stopped")
112+
self.logger.trace("\(self) stopped")
113113
}
114114
}
115115

@@ -150,7 +150,7 @@ final class HTTPHandler: ChannelInboundHandler {
150150
}
151151

152152
func processRequest(context: ChannelHandlerContext, request: (head: HTTPRequestHead, body: ByteBuffer?)) {
153-
self.logger.info("\(self) processing \(request.head.uri)")
153+
self.logger.trace("\(self) processing \(request.head.uri)")
154154

155155
let requestBody = request.body.flatMap { (buffer: ByteBuffer) -> String? in
156156
var buffer = buffer

Tests/AWSLambdaRuntimeTests/UtilsTest.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,30 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import XCTest
15+
import Testing
1616

1717
@testable import AWSLambdaRuntime
1818

19-
class UtilsTest: XCTestCase {
19+
struct UtilsTest {
20+
@Test
2021
func testGenerateXRayTraceID() {
2122
// the time and identifier should be in hexadecimal digits
22-
let invalidCharacters = CharacterSet(charactersIn: "abcdef0123456789").inverted
23+
let allowedCharacters = "0123456789abcdef"
2324
let numTests = 1000
2425
var values = Set<String>()
2526
for _ in 0..<numTests {
2627
// check the format, see https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids)
2728
let traceId = AmazonHeaders.generateXRayTraceID()
2829
let segments = traceId.split(separator: "-")
29-
XCTAssertEqual(3, segments.count)
30-
XCTAssertEqual("1", segments[0])
31-
XCTAssertEqual(8, segments[1].count)
32-
XCTAssertNil(segments[1].rangeOfCharacter(from: invalidCharacters))
33-
XCTAssertEqual(24, segments[2].count)
34-
XCTAssertNil(segments[2].rangeOfCharacter(from: invalidCharacters))
30+
#expect(segments.count == 3)
31+
#expect(segments[0] == "1")
32+
#expect(segments[1].count == 8)
33+
#expect(segments[2].count == 24)
34+
#expect(segments[1].allSatisfy { allowedCharacters.contains($0) })
35+
#expect(segments[2].allSatisfy { allowedCharacters.contains($0) })
3536
values.insert(traceId)
3637
}
3738
// check that the generated values are different
38-
XCTAssertEqual(values.count, numTests)
39+
#expect(values.count == numTests)
3940
}
4041
}

0 commit comments

Comments
 (0)