1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 Google Inc. All rights reserved. 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 "encoding/json" 19*333d2b36SAndroid Build Coastguard Worker "io/ioutil" 20*333d2b36SAndroid Build Coastguard Worker "path/filepath" 21*333d2b36SAndroid Build Coastguard Worker "sort" 22*333d2b36SAndroid Build Coastguard Worker "strings" 23*333d2b36SAndroid Build Coastguard Worker "testing" 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Worker// testProjectJson run the generation of rust-project.json. It returns the raw 29*333d2b36SAndroid Build Coastguard Worker// content of the generated file. 30*333d2b36SAndroid Build Coastguard Workerfunc testProjectJson(t *testing.T, bp string) []byte { 31*333d2b36SAndroid Build Coastguard Worker result := android.GroupFixturePreparers( 32*333d2b36SAndroid Build Coastguard Worker prepareForRustTest, 33*333d2b36SAndroid Build Coastguard Worker android.FixtureMergeEnv(map[string]string{"SOONG_GEN_RUST_PROJECT": "1"}), 34*333d2b36SAndroid Build Coastguard Worker ).RunTestWithBp(t, bp) 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Worker // The JSON file is generated via WriteFileToOutputDir. Therefore, it 37*333d2b36SAndroid Build Coastguard Worker // won't appear in the Output of the TestingSingleton. Manually verify 38*333d2b36SAndroid Build Coastguard Worker // it exists. 39*333d2b36SAndroid Build Coastguard Worker content, err := ioutil.ReadFile(filepath.Join(result.Config.SoongOutDir(), rustProjectJsonFileName)) 40*333d2b36SAndroid Build Coastguard Worker if err != nil { 41*333d2b36SAndroid Build Coastguard Worker t.Errorf("rust-project.json has not been generated") 42*333d2b36SAndroid Build Coastguard Worker } 43*333d2b36SAndroid Build Coastguard Worker return content 44*333d2b36SAndroid Build Coastguard Worker} 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Worker// validateJsonCrates validates that content follows the basic structure of 47*333d2b36SAndroid Build Coastguard Worker// rust-project.json. It returns the crates attribute if the validation 48*333d2b36SAndroid Build Coastguard Worker// succeeded. 49*333d2b36SAndroid Build Coastguard Worker// It uses an empty interface instead of relying on a defined structure to 50*333d2b36SAndroid Build Coastguard Worker// avoid a strong dependency on our implementation. 51*333d2b36SAndroid Build Coastguard Workerfunc validateJsonCrates(t *testing.T, rawContent []byte) []interface{} { 52*333d2b36SAndroid Build Coastguard Worker var content interface{} 53*333d2b36SAndroid Build Coastguard Worker err := json.Unmarshal(rawContent, &content) 54*333d2b36SAndroid Build Coastguard Worker if err != nil { 55*333d2b36SAndroid Build Coastguard Worker t.Errorf("Unable to parse the rust-project.json as JSON: %v", err) 56*333d2b36SAndroid Build Coastguard Worker } 57*333d2b36SAndroid Build Coastguard Worker root, ok := content.(map[string]interface{}) 58*333d2b36SAndroid Build Coastguard Worker if !ok { 59*333d2b36SAndroid Build Coastguard Worker t.Errorf("Unexpected JSON format: %v", content) 60*333d2b36SAndroid Build Coastguard Worker } 61*333d2b36SAndroid Build Coastguard Worker if _, ok = root["crates"]; !ok { 62*333d2b36SAndroid Build Coastguard Worker t.Errorf("No crates attribute in rust-project.json: %v", root) 63*333d2b36SAndroid Build Coastguard Worker } 64*333d2b36SAndroid Build Coastguard Worker crates, ok := root["crates"].([]interface{}) 65*333d2b36SAndroid Build Coastguard Worker if !ok { 66*333d2b36SAndroid Build Coastguard Worker t.Errorf("Unexpected crates format: %v", root["crates"]) 67*333d2b36SAndroid Build Coastguard Worker } 68*333d2b36SAndroid Build Coastguard Worker return crates 69*333d2b36SAndroid Build Coastguard Worker} 70*333d2b36SAndroid Build Coastguard Worker 71*333d2b36SAndroid Build Coastguard Worker// validateCrate ensures that a crate can be parsed as a map. 72*333d2b36SAndroid Build Coastguard Workerfunc validateCrate(t *testing.T, crate interface{}) map[string]interface{} { 73*333d2b36SAndroid Build Coastguard Worker c, ok := crate.(map[string]interface{}) 74*333d2b36SAndroid Build Coastguard Worker if !ok { 75*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for crate: %v", c) 76*333d2b36SAndroid Build Coastguard Worker } 77*333d2b36SAndroid Build Coastguard Worker return c 78*333d2b36SAndroid Build Coastguard Worker} 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker// validateDependencies parses the dependencies for a crate. It returns a list 81*333d2b36SAndroid Build Coastguard Worker// of the dependencies name. 82*333d2b36SAndroid Build Coastguard Workerfunc validateDependencies(t *testing.T, crate map[string]interface{}) []string { 83*333d2b36SAndroid Build Coastguard Worker var dependencies []string 84*333d2b36SAndroid Build Coastguard Worker deps, ok := crate["deps"].([]interface{}) 85*333d2b36SAndroid Build Coastguard Worker if !ok { 86*333d2b36SAndroid Build Coastguard Worker t.Errorf("Unexpected format for deps: %v", crate["deps"]) 87*333d2b36SAndroid Build Coastguard Worker } 88*333d2b36SAndroid Build Coastguard Worker for _, dep := range deps { 89*333d2b36SAndroid Build Coastguard Worker d, ok := dep.(map[string]interface{}) 90*333d2b36SAndroid Build Coastguard Worker if !ok { 91*333d2b36SAndroid Build Coastguard Worker t.Errorf("Unexpected format for dependency: %v", dep) 92*333d2b36SAndroid Build Coastguard Worker } 93*333d2b36SAndroid Build Coastguard Worker name, ok := d["name"].(string) 94*333d2b36SAndroid Build Coastguard Worker if !ok { 95*333d2b36SAndroid Build Coastguard Worker t.Errorf("Dependency is missing the name key: %v", d) 96*333d2b36SAndroid Build Coastguard Worker } 97*333d2b36SAndroid Build Coastguard Worker dependencies = append(dependencies, name) 98*333d2b36SAndroid Build Coastguard Worker } 99*333d2b36SAndroid Build Coastguard Worker return dependencies 100*333d2b36SAndroid Build Coastguard Worker} 101*333d2b36SAndroid Build Coastguard Worker 102*333d2b36SAndroid Build Coastguard Workerfunc TestProjectJsonDep(t *testing.T) { 103*333d2b36SAndroid Build Coastguard Worker bp := ` 104*333d2b36SAndroid Build Coastguard Worker rust_library { 105*333d2b36SAndroid Build Coastguard Worker name: "liba", 106*333d2b36SAndroid Build Coastguard Worker srcs: ["a/src/lib.rs"], 107*333d2b36SAndroid Build Coastguard Worker crate_name: "a" 108*333d2b36SAndroid Build Coastguard Worker } 109*333d2b36SAndroid Build Coastguard Worker rust_library { 110*333d2b36SAndroid Build Coastguard Worker name: "libb", 111*333d2b36SAndroid Build Coastguard Worker srcs: ["b/src/lib.rs"], 112*333d2b36SAndroid Build Coastguard Worker crate_name: "b", 113*333d2b36SAndroid Build Coastguard Worker rlibs: ["liba"], 114*333d2b36SAndroid Build Coastguard Worker } 115*333d2b36SAndroid Build Coastguard Worker ` 116*333d2b36SAndroid Build Coastguard Worker jsonContent := testProjectJson(t, bp) 117*333d2b36SAndroid Build Coastguard Worker validateJsonCrates(t, jsonContent) 118*333d2b36SAndroid Build Coastguard Worker} 119*333d2b36SAndroid Build Coastguard Worker 120*333d2b36SAndroid Build Coastguard Workerfunc TestProjectJsonProcMacroDep(t *testing.T) { 121*333d2b36SAndroid Build Coastguard Worker bp := ` 122*333d2b36SAndroid Build Coastguard Worker rust_proc_macro { 123*333d2b36SAndroid Build Coastguard Worker name: "libproc_macro", 124*333d2b36SAndroid Build Coastguard Worker srcs: ["a/src/lib.rs"], 125*333d2b36SAndroid Build Coastguard Worker crate_name: "proc_macro" 126*333d2b36SAndroid Build Coastguard Worker } 127*333d2b36SAndroid Build Coastguard Worker rust_library { 128*333d2b36SAndroid Build Coastguard Worker name: "librust", 129*333d2b36SAndroid Build Coastguard Worker srcs: ["b/src/lib.rs"], 130*333d2b36SAndroid Build Coastguard Worker crate_name: "rust", 131*333d2b36SAndroid Build Coastguard Worker proc_macros: ["libproc_macro"], 132*333d2b36SAndroid Build Coastguard Worker } 133*333d2b36SAndroid Build Coastguard Worker ` 134*333d2b36SAndroid Build Coastguard Worker jsonContent := testProjectJson(t, bp) 135*333d2b36SAndroid Build Coastguard Worker crates := validateJsonCrates(t, jsonContent) 136*333d2b36SAndroid Build Coastguard Worker libproc_macro_count := 0 137*333d2b36SAndroid Build Coastguard Worker librust_count := 0 138*333d2b36SAndroid Build Coastguard Worker for _, c := range crates { 139*333d2b36SAndroid Build Coastguard Worker crate := validateCrate(t, c) 140*333d2b36SAndroid Build Coastguard Worker procMacro, ok := crate["is_proc_macro"].(bool) 141*333d2b36SAndroid Build Coastguard Worker if !ok { 142*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for is_proc_macro: %v", crate["is_proc_macro"]) 143*333d2b36SAndroid Build Coastguard Worker } 144*333d2b36SAndroid Build Coastguard Worker 145*333d2b36SAndroid Build Coastguard Worker name, ok := crate["display_name"].(string) 146*333d2b36SAndroid Build Coastguard Worker if !ok { 147*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for display_name: %v", crate["display_name"]) 148*333d2b36SAndroid Build Coastguard Worker } 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker switch name { 151*333d2b36SAndroid Build Coastguard Worker case "libproc_macro": 152*333d2b36SAndroid Build Coastguard Worker libproc_macro_count += 1 153*333d2b36SAndroid Build Coastguard Worker if !procMacro { 154*333d2b36SAndroid Build Coastguard Worker t.Fatalf("'libproc_macro' is marked with is_proc_macro=false") 155*333d2b36SAndroid Build Coastguard Worker } 156*333d2b36SAndroid Build Coastguard Worker case "librust": 157*333d2b36SAndroid Build Coastguard Worker librust_count += 1 158*333d2b36SAndroid Build Coastguard Worker if procMacro { 159*333d2b36SAndroid Build Coastguard Worker t.Fatalf("'librust' is not a proc macro crate, but is marked with is_proc_macro=true") 160*333d2b36SAndroid Build Coastguard Worker } 161*333d2b36SAndroid Build Coastguard Worker default: 162*333d2b36SAndroid Build Coastguard Worker break 163*333d2b36SAndroid Build Coastguard Worker } 164*333d2b36SAndroid Build Coastguard Worker } 165*333d2b36SAndroid Build Coastguard Worker 166*333d2b36SAndroid Build Coastguard Worker if libproc_macro_count != 1 || librust_count != 1 { 167*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected crate counts: libproc_macro_count: %v, librust_count: %v", 168*333d2b36SAndroid Build Coastguard Worker libproc_macro_count, librust_count) 169*333d2b36SAndroid Build Coastguard Worker } 170*333d2b36SAndroid Build Coastguard Worker} 171*333d2b36SAndroid Build Coastguard Worker 172*333d2b36SAndroid Build Coastguard Workerfunc TestProjectJsonFeature(t *testing.T) { 173*333d2b36SAndroid Build Coastguard Worker bp := ` 174*333d2b36SAndroid Build Coastguard Worker rust_library { 175*333d2b36SAndroid Build Coastguard Worker name: "liba", 176*333d2b36SAndroid Build Coastguard Worker srcs: ["a/src/lib.rs"], 177*333d2b36SAndroid Build Coastguard Worker crate_name: "a", 178*333d2b36SAndroid Build Coastguard Worker features: ["f1", "f2"] 179*333d2b36SAndroid Build Coastguard Worker } 180*333d2b36SAndroid Build Coastguard Worker ` 181*333d2b36SAndroid Build Coastguard Worker jsonContent := testProjectJson(t, bp) 182*333d2b36SAndroid Build Coastguard Worker crates := validateJsonCrates(t, jsonContent) 183*333d2b36SAndroid Build Coastguard Worker for _, c := range crates { 184*333d2b36SAndroid Build Coastguard Worker crate := validateCrate(t, c) 185*333d2b36SAndroid Build Coastguard Worker cfgs, ok := crate["cfg"].([]interface{}) 186*333d2b36SAndroid Build Coastguard Worker if !ok { 187*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for cfgs: %v", crate) 188*333d2b36SAndroid Build Coastguard Worker } 189*333d2b36SAndroid Build Coastguard Worker expectedCfgs := []string{"feature=\"f1\"", "feature=\"f2\""} 190*333d2b36SAndroid Build Coastguard Worker foundCfgs := []string{} 191*333d2b36SAndroid Build Coastguard Worker for _, cfg := range cfgs { 192*333d2b36SAndroid Build Coastguard Worker cfg, ok := cfg.(string) 193*333d2b36SAndroid Build Coastguard Worker if !ok { 194*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for cfg: %v", cfg) 195*333d2b36SAndroid Build Coastguard Worker } 196*333d2b36SAndroid Build Coastguard Worker foundCfgs = append(foundCfgs, cfg) 197*333d2b36SAndroid Build Coastguard Worker } 198*333d2b36SAndroid Build Coastguard Worker sort.Strings(foundCfgs) 199*333d2b36SAndroid Build Coastguard Worker for i, foundCfg := range foundCfgs { 200*333d2b36SAndroid Build Coastguard Worker if foundCfg != expectedCfgs[i] { 201*333d2b36SAndroid Build Coastguard Worker t.Errorf("Incorrect features: got %v; want %v", foundCfg, expectedCfgs[i]) 202*333d2b36SAndroid Build Coastguard Worker } 203*333d2b36SAndroid Build Coastguard Worker } 204*333d2b36SAndroid Build Coastguard Worker } 205*333d2b36SAndroid Build Coastguard Worker} 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Workerfunc TestProjectJsonBinary(t *testing.T) { 208*333d2b36SAndroid Build Coastguard Worker bp := ` 209*333d2b36SAndroid Build Coastguard Worker rust_binary { 210*333d2b36SAndroid Build Coastguard Worker name: "libz", 211*333d2b36SAndroid Build Coastguard Worker srcs: ["z/src/lib.rs"], 212*333d2b36SAndroid Build Coastguard Worker crate_name: "z" 213*333d2b36SAndroid Build Coastguard Worker } 214*333d2b36SAndroid Build Coastguard Worker ` 215*333d2b36SAndroid Build Coastguard Worker jsonContent := testProjectJson(t, bp) 216*333d2b36SAndroid Build Coastguard Worker crates := validateJsonCrates(t, jsonContent) 217*333d2b36SAndroid Build Coastguard Worker for _, c := range crates { 218*333d2b36SAndroid Build Coastguard Worker crate := validateCrate(t, c) 219*333d2b36SAndroid Build Coastguard Worker rootModule, ok := crate["root_module"].(string) 220*333d2b36SAndroid Build Coastguard Worker if !ok { 221*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for root_module: %v", crate["root_module"]) 222*333d2b36SAndroid Build Coastguard Worker } 223*333d2b36SAndroid Build Coastguard Worker if rootModule == "z/src/lib.rs" { 224*333d2b36SAndroid Build Coastguard Worker return 225*333d2b36SAndroid Build Coastguard Worker } 226*333d2b36SAndroid Build Coastguard Worker } 227*333d2b36SAndroid Build Coastguard Worker t.Errorf("Entry for binary %q not found: %s", "a", jsonContent) 228*333d2b36SAndroid Build Coastguard Worker} 229*333d2b36SAndroid Build Coastguard Worker 230*333d2b36SAndroid Build Coastguard Workerfunc TestProjectJsonBindGen(t *testing.T) { 231*333d2b36SAndroid Build Coastguard Worker buildOS := android.TestConfig(t.TempDir(), nil, "", nil).BuildOS 232*333d2b36SAndroid Build Coastguard Worker 233*333d2b36SAndroid Build Coastguard Worker bp := ` 234*333d2b36SAndroid Build Coastguard Worker rust_library { 235*333d2b36SAndroid Build Coastguard Worker name: "libd", 236*333d2b36SAndroid Build Coastguard Worker srcs: ["d/src/lib.rs"], 237*333d2b36SAndroid Build Coastguard Worker rlibs: ["libbindings1"], 238*333d2b36SAndroid Build Coastguard Worker crate_name: "d" 239*333d2b36SAndroid Build Coastguard Worker } 240*333d2b36SAndroid Build Coastguard Worker rust_bindgen { 241*333d2b36SAndroid Build Coastguard Worker name: "libbindings1", 242*333d2b36SAndroid Build Coastguard Worker crate_name: "bindings1", 243*333d2b36SAndroid Build Coastguard Worker source_stem: "bindings1", 244*333d2b36SAndroid Build Coastguard Worker host_supported: true, 245*333d2b36SAndroid Build Coastguard Worker wrapper_src: "src/any.h", 246*333d2b36SAndroid Build Coastguard Worker } 247*333d2b36SAndroid Build Coastguard Worker rust_library_host { 248*333d2b36SAndroid Build Coastguard Worker name: "libe", 249*333d2b36SAndroid Build Coastguard Worker srcs: ["e/src/lib.rs"], 250*333d2b36SAndroid Build Coastguard Worker rustlibs: ["libbindings2"], 251*333d2b36SAndroid Build Coastguard Worker crate_name: "e" 252*333d2b36SAndroid Build Coastguard Worker } 253*333d2b36SAndroid Build Coastguard Worker rust_bindgen_host { 254*333d2b36SAndroid Build Coastguard Worker name: "libbindings2", 255*333d2b36SAndroid Build Coastguard Worker crate_name: "bindings2", 256*333d2b36SAndroid Build Coastguard Worker source_stem: "bindings2", 257*333d2b36SAndroid Build Coastguard Worker wrapper_src: "src/any.h", 258*333d2b36SAndroid Build Coastguard Worker } 259*333d2b36SAndroid Build Coastguard Worker ` 260*333d2b36SAndroid Build Coastguard Worker jsonContent := testProjectJson(t, bp) 261*333d2b36SAndroid Build Coastguard Worker crates := validateJsonCrates(t, jsonContent) 262*333d2b36SAndroid Build Coastguard Worker for _, c := range crates { 263*333d2b36SAndroid Build Coastguard Worker crate := validateCrate(t, c) 264*333d2b36SAndroid Build Coastguard Worker rootModule, ok := crate["root_module"].(string) 265*333d2b36SAndroid Build Coastguard Worker if !ok { 266*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for root_module: %v", crate["root_module"]) 267*333d2b36SAndroid Build Coastguard Worker } 268*333d2b36SAndroid Build Coastguard Worker if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") { 269*333d2b36SAndroid Build Coastguard Worker t.Errorf("The source path for libbindings1 does not contain android_arm64, got %v", rootModule) 270*333d2b36SAndroid Build Coastguard Worker } 271*333d2b36SAndroid Build Coastguard Worker if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, buildOS.String()) { 272*333d2b36SAndroid Build Coastguard Worker t.Errorf("The source path for libbindings2 does not contain the BuildOs, got %v; want %v", 273*333d2b36SAndroid Build Coastguard Worker rootModule, buildOS.String()) 274*333d2b36SAndroid Build Coastguard Worker } 275*333d2b36SAndroid Build Coastguard Worker // Check that libbindings1 does not depend on itself. 276*333d2b36SAndroid Build Coastguard Worker if strings.Contains(rootModule, "libbindings1") { 277*333d2b36SAndroid Build Coastguard Worker for _, depName := range validateDependencies(t, crate) { 278*333d2b36SAndroid Build Coastguard Worker if depName == "bindings1" { 279*333d2b36SAndroid Build Coastguard Worker t.Errorf("libbindings1 depends on itself") 280*333d2b36SAndroid Build Coastguard Worker } 281*333d2b36SAndroid Build Coastguard Worker } 282*333d2b36SAndroid Build Coastguard Worker } 283*333d2b36SAndroid Build Coastguard Worker if strings.Contains(rootModule, "d/src/lib.rs") { 284*333d2b36SAndroid Build Coastguard Worker // Check that libd depends on libbindings1 285*333d2b36SAndroid Build Coastguard Worker found := false 286*333d2b36SAndroid Build Coastguard Worker for _, depName := range validateDependencies(t, crate) { 287*333d2b36SAndroid Build Coastguard Worker if depName == "bindings1" { 288*333d2b36SAndroid Build Coastguard Worker found = true 289*333d2b36SAndroid Build Coastguard Worker break 290*333d2b36SAndroid Build Coastguard Worker } 291*333d2b36SAndroid Build Coastguard Worker } 292*333d2b36SAndroid Build Coastguard Worker if !found { 293*333d2b36SAndroid Build Coastguard Worker t.Errorf("libd does not depend on libbindings1: %v", crate) 294*333d2b36SAndroid Build Coastguard Worker } 295*333d2b36SAndroid Build Coastguard Worker // Check that OUT_DIR is populated. 296*333d2b36SAndroid Build Coastguard Worker env, ok := crate["env"].(map[string]interface{}) 297*333d2b36SAndroid Build Coastguard Worker if !ok { 298*333d2b36SAndroid Build Coastguard Worker t.Errorf("libd does not have its environment variables set: %v", crate) 299*333d2b36SAndroid Build Coastguard Worker } 300*333d2b36SAndroid Build Coastguard Worker if _, ok = env["OUT_DIR"]; !ok { 301*333d2b36SAndroid Build Coastguard Worker t.Errorf("libd does not have its OUT_DIR set: %v", env) 302*333d2b36SAndroid Build Coastguard Worker } 303*333d2b36SAndroid Build Coastguard Worker 304*333d2b36SAndroid Build Coastguard Worker } 305*333d2b36SAndroid Build Coastguard Worker } 306*333d2b36SAndroid Build Coastguard Worker} 307*333d2b36SAndroid Build Coastguard Worker 308*333d2b36SAndroid Build Coastguard Workerfunc TestProjectJsonMultiVersion(t *testing.T) { 309*333d2b36SAndroid Build Coastguard Worker bp := ` 310*333d2b36SAndroid Build Coastguard Worker rust_library { 311*333d2b36SAndroid Build Coastguard Worker name: "liba1", 312*333d2b36SAndroid Build Coastguard Worker srcs: ["a1/src/lib.rs"], 313*333d2b36SAndroid Build Coastguard Worker crate_name: "a" 314*333d2b36SAndroid Build Coastguard Worker } 315*333d2b36SAndroid Build Coastguard Worker rust_library { 316*333d2b36SAndroid Build Coastguard Worker name: "liba2", 317*333d2b36SAndroid Build Coastguard Worker srcs: ["a2/src/lib.rs"], 318*333d2b36SAndroid Build Coastguard Worker crate_name: "a", 319*333d2b36SAndroid Build Coastguard Worker } 320*333d2b36SAndroid Build Coastguard Worker rust_library { 321*333d2b36SAndroid Build Coastguard Worker name: "libb", 322*333d2b36SAndroid Build Coastguard Worker srcs: ["b/src/lib.rs"], 323*333d2b36SAndroid Build Coastguard Worker crate_name: "b", 324*333d2b36SAndroid Build Coastguard Worker rustlibs: ["liba1", "liba2"], 325*333d2b36SAndroid Build Coastguard Worker } 326*333d2b36SAndroid Build Coastguard Worker ` 327*333d2b36SAndroid Build Coastguard Worker jsonContent := testProjectJson(t, bp) 328*333d2b36SAndroid Build Coastguard Worker crates := validateJsonCrates(t, jsonContent) 329*333d2b36SAndroid Build Coastguard Worker for _, c := range crates { 330*333d2b36SAndroid Build Coastguard Worker crate := validateCrate(t, c) 331*333d2b36SAndroid Build Coastguard Worker rootModule, ok := crate["root_module"].(string) 332*333d2b36SAndroid Build Coastguard Worker if !ok { 333*333d2b36SAndroid Build Coastguard Worker t.Fatalf("Unexpected type for root_module: %v", crate["root_module"]) 334*333d2b36SAndroid Build Coastguard Worker } 335*333d2b36SAndroid Build Coastguard Worker // Make sure that b has 2 different dependencies. 336*333d2b36SAndroid Build Coastguard Worker if rootModule == "b/src/lib.rs" { 337*333d2b36SAndroid Build Coastguard Worker aCount := 0 338*333d2b36SAndroid Build Coastguard Worker deps := validateDependencies(t, crate) 339*333d2b36SAndroid Build Coastguard Worker for _, depName := range deps { 340*333d2b36SAndroid Build Coastguard Worker if depName == "a" { 341*333d2b36SAndroid Build Coastguard Worker aCount++ 342*333d2b36SAndroid Build Coastguard Worker } 343*333d2b36SAndroid Build Coastguard Worker } 344*333d2b36SAndroid Build Coastguard Worker if aCount != 2 { 345*333d2b36SAndroid Build Coastguard Worker t.Errorf("Unexpected number of liba dependencies want %v, got %v: %v", 2, aCount, deps) 346*333d2b36SAndroid Build Coastguard Worker } 347*333d2b36SAndroid Build Coastguard Worker return 348*333d2b36SAndroid Build Coastguard Worker } 349*333d2b36SAndroid Build Coastguard Worker } 350*333d2b36SAndroid Build Coastguard Worker t.Errorf("libb crate has not been found: %v", crates) 351*333d2b36SAndroid Build Coastguard Worker} 352