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 "android/soong/cc" 23) 24 25// Test that cc modules can link against vendor_available rust_ffi_static libraries. 26func TestVendorLinkage(t *testing.T) { 27 ctx := testRustVndk(t, ` 28 cc_binary { 29 name: "fizz_vendor", 30 static_libs: ["libfoo_vendor"], 31 soc_specific: true, 32 } 33 rust_ffi_static { 34 name: "libfoo_vendor", 35 crate_name: "foo", 36 srcs: ["foo.rs"], 37 vendor_available: true, 38 } 39 `) 40 41 vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor.29_arm64_armv8-a").Module().(*cc.Module) 42 43 if !android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) { 44 t.Errorf("vendorBinary should have a dependency on libfoo_vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs) 45 } 46} 47 48// Test that variants which use the vndk emit the appropriate cfg flag. 49func TestImageVndkCfgFlag(t *testing.T) { 50 ctx := testRustVndk(t, ` 51 rust_ffi_static { 52 name: "libfoo", 53 crate_name: "foo", 54 srcs: ["foo.rs"], 55 vendor_available: true, 56 product_available: true, 57 } 58 `) 59 60 vendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_static").Rule("rustc") 61 62 if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") { 63 t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 64 } 65 if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vendor'") { 66 t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 67 } 68 if strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_product'") { 69 t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 70 } 71 72 product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc") 73 if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") { 74 t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 75 } 76 if strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vendor'") { 77 t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 78 } 79 if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_product'") { 80 t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 81 } 82 83 system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Rule("rustc") 84 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") { 85 t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"]) 86 } 87 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vendor'") { 88 t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"]) 89 } 90 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_product'") { 91 t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.Args["rustcFlags"]) 92 } 93 94} 95 96// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries. 97func TestVendorRamdiskLinkage(t *testing.T) { 98 ctx := testRustVndk(t, ` 99 cc_library_static { 100 name: "libcc_vendor_ramdisk", 101 static_libs: ["libfoo_vendor_ramdisk"], 102 system_shared_libs: [], 103 vendor_ramdisk_available: true, 104 } 105 rust_ffi_static { 106 name: "libfoo_vendor_ramdisk", 107 crate_name: "foo", 108 srcs: ["foo.rs"], 109 vendor_ramdisk_available: true, 110 } 111 `) 112 113 vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_static").Module().(*cc.Module) 114 115 if !android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) { 116 t.Errorf("libcc_vendor_ramdisk should have a dependency on libfoo_vendor_ramdisk") 117 } 118} 119 120// Test that prebuilt libraries cannot be made vendor available. 121func TestForbiddenVendorLinkage(t *testing.T) { 122 testRustVndkError(t, "Rust prebuilt modules not supported for non-system images.", ` 123 rust_prebuilt_library { 124 name: "librust_prebuilt", 125 crate_name: "rust_prebuilt", 126 rlib: { 127 srcs: ["libtest.rlib"], 128 }, 129 dylib: { 130 srcs: ["libtest.so"], 131 }, 132 vendor: true, 133 } 134 `) 135} 136 137func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) { 138 mod := ctx.ModuleForTests(name, variant).Module().(*Module) 139 partitionDefined := false 140 checkPartition := func(specific bool, partition string) { 141 if specific { 142 if expected != partition && !partitionDefined { 143 // The variant is installed to the 'partition' 144 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition) 145 } 146 partitionDefined = true 147 } else { 148 // The variant is not installed to the 'partition' 149 if expected == partition { 150 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition) 151 } 152 } 153 } 154 socSpecific := func(m *Module) bool { 155 return m.SocSpecific() 156 } 157 deviceSpecific := func(m *Module) bool { 158 return m.DeviceSpecific() 159 } 160 productSpecific := func(m *Module) bool { 161 return m.ProductSpecific() || m.productSpecificModuleContext() 162 } 163 systemExtSpecific := func(m *Module) bool { 164 return m.SystemExtSpecific() 165 } 166 checkPartition(socSpecific(mod), "vendor") 167 checkPartition(deviceSpecific(mod), "odm") 168 checkPartition(productSpecific(mod), "product") 169 checkPartition(systemExtSpecific(mod), "system_ext") 170 if !partitionDefined && expected != "system" { 171 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+ 172 " but installed to system partition", variant, name, expected) 173 } 174} 175 176func TestInstallPartition(t *testing.T) { 177 t.Parallel() 178 t.Helper() 179 ctx := testRust(t, ` 180 rust_binary { 181 name: "sample_system", 182 crate_name: "sample", 183 srcs: ["foo.rs"], 184 } 185 rust_binary { 186 name: "sample_system_ext", 187 crate_name: "sample", 188 srcs: ["foo.rs"], 189 system_ext_specific: true, 190 } 191 rust_binary { 192 name: "sample_product", 193 crate_name: "sample", 194 srcs: ["foo.rs"], 195 product_specific: true, 196 } 197 rust_binary { 198 name: "sample_vendor", 199 crate_name: "sample", 200 srcs: ["foo.rs"], 201 vendor: true, 202 } 203 rust_binary { 204 name: "sample_odm", 205 crate_name: "sample", 206 srcs: ["foo.rs"], 207 device_specific: true, 208 } 209 rust_binary { 210 name: "sample_all_available", 211 crate_name: "sample", 212 srcs: ["foo.rs"], 213 vendor_available: true, 214 product_available: true, 215 } 216 `) 217 218 checkInstallPartition(t, ctx, "sample_system", binaryCoreVariant, "system") 219 checkInstallPartition(t, ctx, "sample_system_ext", binaryCoreVariant, "system_ext") 220 checkInstallPartition(t, ctx, "sample_product", binaryProductVariant, "product") 221 checkInstallPartition(t, ctx, "sample_vendor", binaryVendorVariant, "vendor") 222 checkInstallPartition(t, ctx, "sample_odm", binaryVendorVariant, "odm") 223 224 checkInstallPartition(t, ctx, "sample_all_available", binaryCoreVariant, "system") 225} 226