Skip to content

Commit 2978160

Browse files
glbrnttgjcairo
andauthored
Add integration tests (grpc#3)
Motivation: We didn't bring over the interop of perf tests when doing the repo split. Modifications: - Add sub-packages for the grpc interop and perf tests. - Add scripts to fetch and generate the protos for the perf tests. - Add a script to build the perf tests (but not run them) - Add a script to build and run the interop tests - Add a CI job to run the above two scripts - Bring over the existing interop and perf tests Result: Interop and perf tests are in the right place --------- Co-authored-by: Gus Cairo <[email protected]>
1 parent 1cea701 commit 2978160

39 files changed

+9603
-1
lines changed

.github/workflows/ci.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,20 @@ jobs:
3535
- name: 🧪 Test
3636
run: swift test ${{ matrix.swift-test-flags }}
3737
timeout-minutes: 20
38+
integration-tests:
39+
strategy:
40+
fail-fast: false
41+
matrix:
42+
include:
43+
- image: swiftlang/swift:nightly-jammy
44+
- image: swift:6.0-jammy
45+
name: Run integration tests using ${{ matrix.image }}
46+
runs-on: ubuntu-latest
47+
container:
48+
image: ${{ matrix.image }}
49+
steps:
50+
- uses: actions/checkout@v4
51+
- name: Build performance tests
52+
run: ./dev/build-performance-tests.sh
53+
- name: Run interop tests
54+
run: ./dev/run-interop-tests.sh
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// swift-tools-version: 6.0
2+
/*
3+
* Copyright 2024, gRPC Authors All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import PackageDescription
19+
20+
let package = Package(
21+
name: "grpc-interop-tests",
22+
platforms: [.macOS("15.0")],
23+
dependencies: [
24+
.package(path: "../.."),
25+
.package(
26+
url: "https://github.com/grpc/grpc-swift-protobuf",
27+
branch: "main"
28+
),
29+
.package(
30+
url: "https://github.com/grpc/grpc-swift-extras",
31+
branch: "main"
32+
),
33+
.package(
34+
url: "https://github.com/apple/swift-argument-parser",
35+
from: "1.5.0"
36+
),
37+
],
38+
targets: [
39+
.executableTarget(
40+
name: "grpc-interop-tests",
41+
dependencies: [
42+
.product(name: "GRPCNIOTransportHTTP2", package: "grpc-swift-nio-transport"),
43+
.product(name: "GRPCProtobuf", package: "grpc-swift-protobuf"),
44+
.product(name: "GRPCInteropTests", package: "grpc-swift-extras"),
45+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
46+
]
47+
)
48+
]
49+
)
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* Copyright 2024, gRPC Authors All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import ArgumentParser
18+
import GRPCCore
19+
import GRPCInteropTests
20+
import GRPCNIOTransportHTTP2
21+
22+
@main
23+
struct InteroperabilityTestsExecutable: AsyncParsableCommand {
24+
static let configuration = CommandConfiguration(
25+
abstract: "gRPC Swift Interoperability Runner",
26+
subcommands: [StartServer.self, ListTests.self, RunTests.self]
27+
)
28+
29+
struct StartServer: AsyncParsableCommand {
30+
static let configuration = CommandConfiguration(
31+
abstract: "Start the gRPC Swift interoperability test server."
32+
)
33+
34+
@Option(help: "The port to listen on for new connections")
35+
var port: Int
36+
37+
@Option(help: "The host to listen on for new connections")
38+
var host: String = "127.0.0.1"
39+
40+
func run() async throws {
41+
let server = GRPCServer(
42+
transport: .http2NIOPosix(
43+
address: .ipv4(host: self.host, port: self.port),
44+
config: .defaults(transportSecurity: .plaintext) {
45+
$0.compression.enabledAlgorithms = .all
46+
}
47+
),
48+
services: [TestService()]
49+
)
50+
51+
try await withThrowingDiscardingTaskGroup { group in
52+
group.addTask {
53+
try await server.serve()
54+
}
55+
56+
if let address = try await server.listeningAddress {
57+
print("listening address: \(address)")
58+
}
59+
}
60+
}
61+
}
62+
63+
struct ListTests: ParsableCommand {
64+
static let configuration = CommandConfiguration(
65+
abstract: "List all interoperability test names."
66+
)
67+
68+
func run() throws {
69+
for testCase in InteroperabilityTestCase.allCases {
70+
print(testCase.name)
71+
}
72+
}
73+
}
74+
75+
struct RunTests: AsyncParsableCommand {
76+
static let configuration = CommandConfiguration(
77+
abstract: """
78+
Run gRPC interoperability tests using a gRPC Swift client.
79+
You can specify a test name as an argument to run a single test.
80+
If no test name is given, all interoperability tests will be run.
81+
"""
82+
)
83+
84+
@Option(help: "The host the server is running on")
85+
var host: String
86+
87+
@Option(help: "The port to connect to")
88+
var port: Int
89+
90+
@Argument(help: "The name of the tests to run. If none, all tests will be run.")
91+
var testNames: [String] = InteroperabilityTestCase.allCases.map { $0.name }
92+
93+
func run() async throws {
94+
let client = try self.buildClient(host: self.host, port: self.port)
95+
96+
try await withThrowingDiscardingTaskGroup { group in
97+
group.addTask {
98+
try await client.run()
99+
}
100+
101+
for testName in testNames {
102+
guard let testCase = InteroperabilityTestCase(rawValue: testName) else {
103+
print(InteroperabilityTestError.testNotFound(name: testName))
104+
continue
105+
}
106+
await self.runTest(testCase, using: client)
107+
}
108+
109+
client.beginGracefulShutdown()
110+
}
111+
}
112+
113+
private func buildClient(host: String, port: Int) throws -> GRPCClient {
114+
let serviceConfig = ServiceConfig(loadBalancingConfig: [.roundRobin])
115+
return GRPCClient(
116+
transport: try .http2NIOPosix(
117+
target: .ipv4(host: host, port: port),
118+
config: .defaults(transportSecurity: .plaintext) {
119+
$0.compression.enabledAlgorithms = .all
120+
},
121+
serviceConfig: serviceConfig
122+
)
123+
)
124+
}
125+
126+
private func runTest(
127+
_ testCase: InteroperabilityTestCase,
128+
using client: GRPCClient
129+
) async {
130+
print("Running '\(testCase.name)' ... ", terminator: "")
131+
do {
132+
try await testCase.makeTest().run(client: client)
133+
print("PASSED")
134+
} catch {
135+
print("FAILED\n" + String(describing: InteroperabilityTestError.testFailed(cause: error)))
136+
}
137+
}
138+
}
139+
}
140+
141+
enum InteroperabilityTestError: Error, CustomStringConvertible {
142+
case testNotFound(name: String)
143+
case testFailed(cause: any Error)
144+
145+
var description: String {
146+
switch self {
147+
case .testNotFound(let name):
148+
return "Test \"\(name)\" not found."
149+
case .testFailed(let cause):
150+
return "Test failed with error: \(String(describing: cause))"
151+
}
152+
}
153+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// swift-tools-version: 6.0
2+
/*
3+
* Copyright 2024, gRPC Authors All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import PackageDescription
19+
20+
let package = Package(
21+
name: "grpc-performance-tests",
22+
platforms: [.macOS("15.0")],
23+
dependencies: [
24+
.package(path: "../.."),
25+
.package(
26+
url: "https://github.com/grpc/grpc-swift-protobuf",
27+
branch: "main"
28+
),
29+
.package(
30+
url: "https://github.com/apple/swift-argument-parser",
31+
from: "1.5.0"
32+
),
33+
.package(
34+
url: "https://github.com/apple/swift-nio",
35+
from: "2.72.0"
36+
),
37+
],
38+
targets: [
39+
.executableTarget(
40+
name: "grpc-performance-tests",
41+
dependencies: [
42+
.product(name: "GRPCNIOTransportHTTP2", package: "grpc-swift-nio-transport"),
43+
.product(name: "GRPCProtobuf", package: "grpc-swift-protobuf"),
44+
.product(name: "NIOPosix", package: "swift-nio"),
45+
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
46+
.product(name: "_NIOFileSystem", package: "swift-nio"),
47+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
48+
]
49+
)
50+
]
51+
)

0 commit comments

Comments
 (0)