Skip to content

Commit 4153ada

Browse files
rnroglbrntt
andauthored
Integration tests for the build plugin (#31)
### Motivation: To protect against regressions in common use-cases of the grpc-swift-protobuf build plugin. ### Modifications: Add test cases which make use of the build plugin as a dependency and ensure that they can compile and use the generated code * top level config file * peer config file * separate service message protos * cross directory imports * two definitions * nested definitions The new tests are run as part of CI on PRs ### Result: More CI. --------- Co-authored-by: George Barnett <[email protected]>
1 parent 7695d98 commit 4153ada

17 files changed

+536
-0
lines changed

.github/workflows/main.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,29 @@ jobs:
1616
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
1717
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
1818
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
19+
20+
construct-plugin-tests-matrix:
21+
name: Construct plugin tests matrix
22+
runs-on: ubuntu-latest
23+
outputs:
24+
plugin-tests-matrix: '${{ steps.generate-matrix.outputs.plugin-tests-matrix }}'
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
with:
29+
persist-credentials: false
30+
- id: generate-matrix
31+
run: echo "plugin-tests-matrix=$(curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/generate_matrix.sh | bash)" >> "$GITHUB_OUTPUT"
32+
env:
33+
MATRIX_LINUX_5_9_ENABLED: false
34+
MATRIX_LINUX_5_10_ENABLED: false
35+
MATRIX_LINUX_COMMAND: "curl -s https://raw.githubusercontent.com/rnro/grpc-swift-protobuf/refs/heads/build_plugin_integration_tests/dev/plugin-tests.sh | GITHUB_ACTIONS=true bash"
36+
MATRIX_LINUX_SETUP_COMMAND: "apt-get update -y -q && apt-get install -y -q curl protobuf-compiler"
37+
38+
plugin-tests-matrix:
39+
name: Plugin tests
40+
needs: construct-plugin-tests-matrix
41+
uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main
42+
with:
43+
name: "Plugin tests"
44+
matrix_string: '${{ needs.construct-plugin-tests-matrix.outputs.plugin-tests-matrix }}'

.github/workflows/pull_request.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,32 @@ jobs:
2626
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
2727
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
2828

29+
construct-plugin-tests-matrix:
30+
name: Construct plugin tests matrix
31+
runs-on: ubuntu-latest
32+
outputs:
33+
plugin-tests-matrix: '${{ steps.generate-matrix.outputs.plugin-tests-matrix }}'
34+
steps:
35+
- name: Checkout repository
36+
uses: actions/checkout@v4
37+
with:
38+
persist-credentials: false
39+
- id: generate-matrix
40+
run: echo "plugin-tests-matrix=$(curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/generate_matrix.sh | bash)" >> "$GITHUB_OUTPUT"
41+
env:
42+
MATRIX_LINUX_5_9_ENABLED: false
43+
MATRIX_LINUX_5_10_ENABLED: false
44+
MATRIX_LINUX_COMMAND: "curl -s https://raw.githubusercontent.com/rnro/grpc-swift-protobuf/refs/heads/build_plugin_integration_tests/dev/plugin-tests.sh | GITHUB_ACTIONS=true bash"
45+
MATRIX_LINUX_SETUP_COMMAND: "apt-get update -y -q && apt-get install -y -q curl protobuf-compiler"
46+
47+
plugin-tests-matrix:
48+
name: Plugin tests
49+
needs: construct-plugin-tests-matrix
50+
uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main
51+
with:
52+
name: "Plugin tests"
53+
matrix_string: '${{ needs.construct-plugin-tests-matrix.outputs.plugin-tests-matrix }}'
54+
2955
cxx-interop:
3056
name: Cxx interop
3157
uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main

.licenseignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ dev/git.commit.template
3636
dev/version-bump.commit.template
3737
dev/protos/local/*
3838
dev/protos/upstream/*
39+
IntegrationTests/PluginTests/**/*.proto
3940
.unacceptablelanguageignore
4041
LICENSE
4142
**/*.swift
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Leading trivia.
2+
syntax = "proto3";
3+
4+
package foo;
5+
6+
message FooInput {}
7+
message FooOutput {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
syntax = "proto3";
2+
3+
import "Foo/foo-messages.proto";
4+
5+
package foo;
6+
7+
service FooService1 {
8+
rpc Foo (FooInput) returns (FooOutput) {}
9+
}
10+
11+
service FooService2 {
12+
rpc Foo (FooInput) returns (FooOutput) {}
13+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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 GRPCCore
18+
import GRPCInProcessTransport
19+
import GRPCProtobuf
20+
21+
@main
22+
struct PluginAdopter {
23+
static func main() async throws {
24+
let inProcess = InProcessTransport()
25+
try await withGRPCServer(transport: inProcess.server, services: [Greeter()]) { server in
26+
try await withGRPCClient(transport: inProcess.client) { client in
27+
try await Self.doRPC(Helloworld_Greeter.Client(wrapping: client))
28+
}
29+
}
30+
31+
try await withGRPCServer(transport: inProcess.server, services: [FooService1()]) { server in
32+
try await withGRPCClient(transport: inProcess.client) { client in
33+
try await Self.doRPC(Foo_FooService1.Client(wrapping: client))
34+
}
35+
}
36+
}
37+
38+
static func doRPC<Transport>(_ greeter: Helloworld_Greeter.Client<Transport>) async throws {
39+
do {
40+
let reply = try await greeter.sayHello(.with { $0.name = "(ignored)" })
41+
print("Reply: \(reply.message)")
42+
} catch {
43+
print("Error: \(error)")
44+
}
45+
}
46+
47+
static func doRPC<Transport>(_ fooService1: Foo_FooService1.Client<Transport>) async throws {
48+
do {
49+
let reply = try await fooService1.foo(.with { _ in () })
50+
print("Reply: \(reply.hashValue)")
51+
} catch {
52+
print("Error: \(error)")
53+
}
54+
}
55+
}
56+
57+
struct Greeter: Helloworld_Greeter.SimpleServiceProtocol {
58+
func sayHello(
59+
request: Helloworld_HelloRequest,
60+
context: ServerContext
61+
) async throws -> Helloworld_HelloReply {
62+
return .with { reply in
63+
reply.message = "Hello, world!"
64+
}
65+
}
66+
}
67+
68+
struct FooService1: Foo_FooService1.SimpleServiceProtocol {
69+
func foo(request: Foo_FooInput, context: GRPCCore.ServerContext) async throws -> Foo_FooOutput {
70+
return .with { _ in
71+
()
72+
}
73+
}
74+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2015, gRPC Authors All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
syntax = "proto3";
15+
16+
option java_multiple_files = true;
17+
option java_package = "io.grpc.examples.helloworld";
18+
option java_outer_classname = "HelloWorldProto";
19+
option objc_class_prefix = "HLW";
20+
21+
package helloworld;
22+
23+
// The greeting service definition.
24+
service Greeter {
25+
// Sends a greeting
26+
rpc SayHello (HelloRequest) returns (HelloReply) {}
27+
}
28+
29+
// The request message containing the user's name.
30+
message HelloRequest {
31+
string name = 1;
32+
}
33+
34+
// The response message containing the greetings
35+
message HelloReply {
36+
string message = 1;
37+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2015, gRPC Authors All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
syntax = "proto3";
15+
16+
option java_multiple_files = true;
17+
option java_package = "io.grpc.examples.helloworld";
18+
option java_outer_classname = "HelloWorldProto";
19+
option objc_class_prefix = "HLW";
20+
21+
package helloworld;
22+
23+
// The request message containing the user's name.
24+
message HelloRequest {
25+
string name = 1;
26+
}
27+
28+
// The response message containing the greetings
29+
message HelloReply {
30+
string message = 1;
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2015, gRPC Authors All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
syntax = "proto3";
15+
16+
option java_multiple_files = true;
17+
option java_package = "io.grpc.examples.helloworld";
18+
option java_outer_classname = "HelloWorldProto";
19+
option objc_class_prefix = "HLW";
20+
21+
package helloworld;
22+
23+
import "Messages.proto";
24+
25+
// The greeting service definition.
26+
service Greeter {
27+
// Sends a greeting
28+
rpc SayHello (HelloRequest) returns (HelloReply) {}
29+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 GRPCCore
18+
import GRPCInProcessTransport
19+
import GRPCProtobuf
20+
21+
@main
22+
struct PluginAdopter {
23+
static func main() async throws {
24+
let inProcess = InProcessTransport()
25+
try await withGRPCServer(transport: inProcess.server, services: [Greeter()]) { server in
26+
try await withGRPCClient(transport: inProcess.client) { client in
27+
try await Self.doRPC(Helloworld_Greeter.Client(wrapping: client))
28+
}
29+
}
30+
}
31+
32+
static func doRPC<Transport>(_ greeter: Helloworld_Greeter.Client<Transport>) async throws {
33+
do {
34+
let reply = try await greeter.sayHello(.with { $0.name = "(ignored)" })
35+
print("Reply: \(reply.message)")
36+
} catch {
37+
print("Error: \(error)")
38+
}
39+
}
40+
}
41+
42+
struct Greeter: Helloworld_Greeter.SimpleServiceProtocol {
43+
func sayHello(
44+
request: Helloworld_HelloRequest,
45+
context: ServerContext
46+
) async throws -> Helloworld_HelloReply {
47+
return .with { reply in
48+
reply.message = "Hello, world!"
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)