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