xref: /aosp_15_r20/build/soong/rust/protobuf_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 The Android Open Source Project
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage rust
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"strings"
19*333d2b36SAndroid Build Coastguard Worker	"testing"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
22*333d2b36SAndroid Build Coastguard Worker)
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Workerfunc TestRustProtobuf3(t *testing.T) {
25*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
26*333d2b36SAndroid Build Coastguard Worker		rust_protobuf {
27*333d2b36SAndroid Build Coastguard Worker			name: "librust_proto",
28*333d2b36SAndroid Build Coastguard Worker			protos: ["buf.proto", "proto.proto"],
29*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_proto",
30*333d2b36SAndroid Build Coastguard Worker			source_stem: "buf",
31*333d2b36SAndroid Build Coastguard Worker			shared_libs: ["libfoo_shared"],
32*333d2b36SAndroid Build Coastguard Worker			static_libs: ["libfoo_static"],
33*333d2b36SAndroid Build Coastguard Worker		}
34*333d2b36SAndroid Build Coastguard Worker		cc_library_shared {
35*333d2b36SAndroid Build Coastguard Worker			name: "libfoo_shared",
36*333d2b36SAndroid Build Coastguard Worker			export_include_dirs: ["shared_include"],
37*333d2b36SAndroid Build Coastguard Worker		}
38*333d2b36SAndroid Build Coastguard Worker		cc_library_static {
39*333d2b36SAndroid Build Coastguard Worker			name: "libfoo_static",
40*333d2b36SAndroid Build Coastguard Worker			export_include_dirs: ["static_include"],
41*333d2b36SAndroid Build Coastguard Worker		}
42*333d2b36SAndroid Build Coastguard Worker	`)
43*333d2b36SAndroid Build Coastguard Worker	// Check that libprotobuf is added as a dependency.
44*333d2b36SAndroid Build Coastguard Worker	librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_dylib").Module().(*Module)
45*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libprotobuf", librust_proto.Properties.AndroidMkDylibs) {
46*333d2b36SAndroid Build Coastguard Worker		t.Errorf("libprotobuf dependency missing for rust_protobuf (dependency missing from AndroidMkDylibs)")
47*333d2b36SAndroid Build Coastguard Worker	}
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Worker	// Make sure the correct plugin is being used.
50*333d2b36SAndroid Build Coastguard Worker	librust_proto_out := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("buf.rs")
51*333d2b36SAndroid Build Coastguard Worker	cmd := librust_proto_out.RuleParams.Command
52*333d2b36SAndroid Build Coastguard Worker	if w := "protoc-gen-rust"; !strings.Contains(cmd, w) {
53*333d2b36SAndroid Build Coastguard Worker		t.Errorf("expected %q in %q", w, cmd)
54*333d2b36SAndroid Build Coastguard Worker	}
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker	// Check exported include directories
57*333d2b36SAndroid Build Coastguard Worker	if w := "-Ishared_include"; !strings.Contains(cmd, w) {
58*333d2b36SAndroid Build Coastguard Worker		t.Errorf("expected %q in %q", w, cmd)
59*333d2b36SAndroid Build Coastguard Worker	}
60*333d2b36SAndroid Build Coastguard Worker	if w := "-Istatic_include"; !strings.Contains(cmd, w) {
61*333d2b36SAndroid Build Coastguard Worker		t.Errorf("expected %q in %q", w, cmd)
62*333d2b36SAndroid Build Coastguard Worker	}
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Worker	// Check proto.rs, the second protobuf, is listed as an output
65*333d2b36SAndroid Build Coastguard Worker	librust_proto_outputs := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").AllOutputs()
66*333d2b36SAndroid Build Coastguard Worker	if android.InList("proto.rs", librust_proto_outputs) {
67*333d2b36SAndroid Build Coastguard Worker		t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto.rs' in list, got: %#v ",
68*333d2b36SAndroid Build Coastguard Worker			librust_proto_outputs)
69*333d2b36SAndroid Build Coastguard Worker	}
70*333d2b36SAndroid Build Coastguard Worker}
71*333d2b36SAndroid Build Coastguard Worker
72*333d2b36SAndroid Build Coastguard Workerfunc TestRustProtobufInclude(t *testing.T) {
73*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
74*333d2b36SAndroid Build Coastguard Worker		rust_protobuf {
75*333d2b36SAndroid Build Coastguard Worker			name: "librust_proto",
76*333d2b36SAndroid Build Coastguard Worker			protos: ["proto.proto"],
77*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_proto",
78*333d2b36SAndroid Build Coastguard Worker			source_stem: "proto",
79*333d2b36SAndroid Build Coastguard Worker			rustlibs: ["librust_exported_proto", "libfoo"],
80*333d2b36SAndroid Build Coastguard Worker		}
81*333d2b36SAndroid Build Coastguard Worker		rust_protobuf {
82*333d2b36SAndroid Build Coastguard Worker			name: "librust_exported_proto",
83*333d2b36SAndroid Build Coastguard Worker			protos: ["proto.proto"],
84*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_exported_proto",
85*333d2b36SAndroid Build Coastguard Worker			source_stem: "exported_proto",
86*333d2b36SAndroid Build Coastguard Worker			exported_include_dirs: ["proto"]
87*333d2b36SAndroid Build Coastguard Worker		}
88*333d2b36SAndroid Build Coastguard Worker		rust_library {
89*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
90*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
91*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
92*333d2b36SAndroid Build Coastguard Worker		}
93*333d2b36SAndroid Build Coastguard Worker	`)
94*333d2b36SAndroid Build Coastguard Worker	// Check that librust_exported_proto is added as additional crate to generate source.
95*333d2b36SAndroid Build Coastguard Worker	librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Module().(*Module).sourceProvider.(*protobufDecorator)
96*333d2b36SAndroid Build Coastguard Worker	if !android.InList("rust_exported_proto", librust_proto.additionalCrates) {
97*333d2b36SAndroid Build Coastguard Worker		t.Errorf("librust_proto should have librust_exported_proto included as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
98*333d2b36SAndroid Build Coastguard Worker	}
99*333d2b36SAndroid Build Coastguard Worker
100*333d2b36SAndroid Build Coastguard Worker	// Make sure the default crates aren't being included.
101*333d2b36SAndroid Build Coastguard Worker	if android.InList("std", librust_proto.additionalCrates) {
102*333d2b36SAndroid Build Coastguard Worker		t.Errorf("librust_proto should not have included libstd as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
103*333d2b36SAndroid Build Coastguard Worker	}
104*333d2b36SAndroid Build Coastguard Worker	if android.InList("protobuf", librust_proto.additionalCrates) {
105*333d2b36SAndroid Build Coastguard Worker		t.Errorf("librust_proto should not have included libprotobuf as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
106*333d2b36SAndroid Build Coastguard Worker	}
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker	// And make sure that non-protobuf crates aren't getting included either.
109*333d2b36SAndroid Build Coastguard Worker	if android.InList("foo", librust_proto.additionalCrates) {
110*333d2b36SAndroid Build Coastguard Worker		t.Errorf("librust_proto should not have included libfoo as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
111*333d2b36SAndroid Build Coastguard Worker	}
112*333d2b36SAndroid Build Coastguard Worker
113*333d2b36SAndroid Build Coastguard Worker	// Check librust_proto args includes -Iproto
114*333d2b36SAndroid Build Coastguard Worker	librust_proto_rule := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("proto.rs")
115*333d2b36SAndroid Build Coastguard Worker	cmd := librust_proto_rule.RuleParams.Command
116*333d2b36SAndroid Build Coastguard Worker	if w := "-Iproto"; !strings.Contains(cmd, w) {
117*333d2b36SAndroid Build Coastguard Worker		t.Errorf("expected %q in %q", w, cmd)
118*333d2b36SAndroid Build Coastguard Worker	}
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker}
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Workerfunc TestRustGrpc(t *testing.T) {
123*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
124*333d2b36SAndroid Build Coastguard Worker		rust_protobuf {
125*333d2b36SAndroid Build Coastguard Worker			name: "librust_grpcio",
126*333d2b36SAndroid Build Coastguard Worker			protos: ["buf.proto"],
127*333d2b36SAndroid Build Coastguard Worker			grpc_protos: ["foo.proto", "proto.proto"],
128*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_grpcio",
129*333d2b36SAndroid Build Coastguard Worker			source_stem: "buf",
130*333d2b36SAndroid Build Coastguard Worker		}
131*333d2b36SAndroid Build Coastguard Worker	`)
132*333d2b36SAndroid Build Coastguard Worker
133*333d2b36SAndroid Build Coastguard Worker	// Check that libprotobuf is added as a dependency.
134*333d2b36SAndroid Build Coastguard Worker	librust_grpcio_module := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_dylib").Module().(*Module)
135*333d2b36SAndroid Build Coastguard Worker
136*333d2b36SAndroid Build Coastguard Worker	// Check that libgrpcio is added as a dependency.
137*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libgrpcio", librust_grpcio_module.Properties.AndroidMkDylibs) {
138*333d2b36SAndroid Build Coastguard Worker		t.Errorf("libgrpcio dependency missing for rust_grpcio (dependency missing from AndroidMkDylibs)")
139*333d2b36SAndroid Build Coastguard Worker	}
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Worker	// Check that libfutures is added as a dependency.
142*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libfutures", librust_grpcio_module.Properties.AndroidMkDylibs) {
143*333d2b36SAndroid Build Coastguard Worker		t.Errorf("libfutures dependency missing for rust_grpcio (dependency missing from AndroidMkDylibs)")
144*333d2b36SAndroid Build Coastguard Worker	}
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Worker	// Make sure the correct plugin is being used.
147*333d2b36SAndroid Build Coastguard Worker	librust_grpcio_out := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_source").Output("foo_grpc.rs")
148*333d2b36SAndroid Build Coastguard Worker	cmd := librust_grpcio_out.RuleParams.Command
149*333d2b36SAndroid Build Coastguard Worker	if w := "protoc-gen-grpc"; !strings.Contains(cmd, w) {
150*333d2b36SAndroid Build Coastguard Worker		t.Errorf("expected %q in %q", w, cmd)
151*333d2b36SAndroid Build Coastguard Worker	}
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Worker	// Check that we're including the exported directory from libprotobuf-cpp-full
154*333d2b36SAndroid Build Coastguard Worker	if w := "-I" + rustDefaultsDir + "libprotobuf-cpp-full-includes"; !strings.Contains(cmd, w) {
155*333d2b36SAndroid Build Coastguard Worker		t.Errorf("expected %q in %q", w, cmd)
156*333d2b36SAndroid Build Coastguard Worker	}
157*333d2b36SAndroid Build Coastguard Worker
158*333d2b36SAndroid Build Coastguard Worker	// Check proto.rs, the second protobuf, is listed as an output
159*333d2b36SAndroid Build Coastguard Worker	librust_grpcio_outputs := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_source").AllOutputs()
160*333d2b36SAndroid Build Coastguard Worker	if android.InList("proto_grpc.rs", librust_grpcio_outputs) {
161*333d2b36SAndroid Build Coastguard Worker		t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto_grpc.rs' in list, got: %#v ",
162*333d2b36SAndroid Build Coastguard Worker			librust_grpcio_outputs)
163*333d2b36SAndroid Build Coastguard Worker	}
164*333d2b36SAndroid Build Coastguard Worker}
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Workerfunc TestRustProtoErrors(t *testing.T) {
167*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "A proto can only be added once to either grpc_protos or protos.*", `
168*333d2b36SAndroid Build Coastguard Worker		rust_protobuf {
169*333d2b36SAndroid Build Coastguard Worker			name: "librust_grpcio",
170*333d2b36SAndroid Build Coastguard Worker			protos: ["buf.proto"],
171*333d2b36SAndroid Build Coastguard Worker			grpc_protos: ["buf.proto"],
172*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_grpcio",
173*333d2b36SAndroid Build Coastguard Worker			source_stem: "buf",
174*333d2b36SAndroid Build Coastguard Worker		}
175*333d2b36SAndroid Build Coastguard Worker	`)
176*333d2b36SAndroid Build Coastguard Worker
177*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "proto filenames must be unique across  'protos' and 'grpc_protos'.*", `
178*333d2b36SAndroid Build Coastguard Worker		rust_protobuf {
179*333d2b36SAndroid Build Coastguard Worker			name: "librust_grpcio",
180*333d2b36SAndroid Build Coastguard Worker			protos: ["buf.proto"],
181*333d2b36SAndroid Build Coastguard Worker			grpc_protos: ["proto/buf.proto"],
182*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_grpcio",
183*333d2b36SAndroid Build Coastguard Worker			source_stem: "buf",
184*333d2b36SAndroid Build Coastguard Worker		}
185*333d2b36SAndroid Build Coastguard Worker	`)
186*333d2b36SAndroid Build Coastguard Worker}
187