1// Copyright 2020 The Android Open Source Project 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 15package rust 16 17import ( 18 "strings" 19 "testing" 20 21 "android/soong/android" 22) 23 24func TestRustProtobuf(t *testing.T) { 25 ctx := testRust(t, ` 26 rust_protobuf { 27 name: "librust_proto", 28 protos: ["buf.proto", "proto.proto"], 29 crate_name: "rust_proto", 30 source_stem: "buf", 31 shared_libs: ["libfoo_shared"], 32 static_libs: ["libfoo_static"], 33 } 34 cc_library_shared { 35 name: "libfoo_shared", 36 export_include_dirs: ["shared_include"], 37 } 38 cc_library_static { 39 name: "libfoo_static", 40 export_include_dirs: ["static_include"], 41 } 42 `) 43 // Check that libprotobuf is added as a dependency. 44 librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_dylib").Module().(*Module) 45 if !android.InList("libprotobuf", librust_proto.Properties.AndroidMkDylibs) { 46 t.Errorf("libprotobuf dependency missing for rust_protobuf (dependency missing from AndroidMkDylibs)") 47 } 48 49 // Make sure the correct plugin is being used. 50 librust_proto_out := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("buf.rs") 51 cmd := librust_proto_out.RuleParams.Command 52 if w := "protoc-gen-rust"; !strings.Contains(cmd, w) { 53 t.Errorf("expected %q in %q", w, cmd) 54 } 55 56 // Check exported include directories 57 if w := "-Ishared_include"; !strings.Contains(cmd, w) { 58 t.Errorf("expected %q in %q", w, cmd) 59 } 60 if w := "-Istatic_include"; !strings.Contains(cmd, w) { 61 t.Errorf("expected %q in %q", w, cmd) 62 } 63 64 // Check proto.rs, the second protobuf, is listed as an output 65 librust_proto_outputs := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").AllOutputs() 66 if android.InList("proto.rs", librust_proto_outputs) { 67 t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto.rs' in list, got: %#v ", 68 librust_proto_outputs) 69 } 70} 71 72func TestRustGrpc(t *testing.T) { 73 ctx := testRust(t, ` 74 rust_protobuf { 75 name: "librust_grpcio", 76 protos: ["buf.proto"], 77 grpc_protos: ["foo.proto", "proto.proto"], 78 crate_name: "rust_grpcio", 79 source_stem: "buf", 80 } 81 `) 82 83 // Check that libprotobuf is added as a dependency. 84 librust_grpcio_module := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_dylib").Module().(*Module) 85 86 // Check that libgrpcio is added as a dependency. 87 if !android.InList("libgrpcio", librust_grpcio_module.Properties.AndroidMkDylibs) { 88 t.Errorf("libgrpcio dependency missing for rust_grpcio (dependency missing from AndroidMkDylibs)") 89 } 90 91 // Check that libfutures is added as a dependency. 92 if !android.InList("libfutures", librust_grpcio_module.Properties.AndroidMkDylibs) { 93 t.Errorf("libfutures dependency missing for rust_grpcio (dependency missing from AndroidMkDylibs)") 94 } 95 96 // Make sure the correct plugin is being used. 97 librust_grpcio_out := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_source").Output("foo_grpc.rs") 98 cmd := librust_grpcio_out.RuleParams.Command 99 if w := "protoc-gen-grpc"; !strings.Contains(cmd, w) { 100 t.Errorf("expected %q in %q", w, cmd) 101 } 102 103 // Check that we're including the exported directory from libprotobuf-cpp-full 104 if w := "-I" + rustDefaultsDir + "libprotobuf-cpp-full-includes"; !strings.Contains(cmd, w) { 105 t.Errorf("expected %q in %q", w, cmd) 106 } 107 108 // Check proto.rs, the second protobuf, is listed as an output 109 librust_grpcio_outputs := ctx.ModuleForTests("librust_grpcio", "android_arm64_armv8-a_source").AllOutputs() 110 if android.InList("proto_grpc.rs", librust_grpcio_outputs) { 111 t.Errorf("rust_protobuf is not producing multiple outputs; expected 'proto_grpc.rs' in list, got: %#v ", 112 librust_grpcio_outputs) 113 } 114} 115 116func TestRustProtoErrors(t *testing.T) { 117 testRustError(t, "A proto can only be added once to either grpc_protos or protos.*", ` 118 rust_protobuf { 119 name: "librust_grpcio", 120 protos: ["buf.proto"], 121 grpc_protos: ["buf.proto"], 122 crate_name: "rust_grpcio", 123 source_stem: "buf", 124 } 125 `) 126 127 testRustError(t, "proto filenames must be unique across 'protos' and 'grpc_protos'.*", ` 128 rust_protobuf { 129 name: "librust_grpcio", 130 protos: ["buf.proto"], 131 grpc_protos: ["proto/buf.proto"], 132 crate_name: "rust_grpcio", 133 source_stem: "buf", 134 } 135 `) 136} 137