1// Copyright 2020 Google Inc. All rights reserved. 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 bp2build 16 17import ( 18 "android/soong/android" 19 "io/ioutil" 20 "os" 21 "strings" 22 "testing" 23) 24 25var buildDir string 26 27func setUp() { 28 var err error 29 buildDir, err = ioutil.TempDir("", "bazel_queryview_test") 30 if err != nil { 31 panic(err) 32 } 33} 34 35func tearDown() { 36 os.RemoveAll(buildDir) 37} 38 39func TestMain(m *testing.M) { 40 run := func() int { 41 setUp() 42 defer tearDown() 43 44 return m.Run() 45 } 46 47 os.Exit(run()) 48} 49 50func TestGenerateModuleRuleShims(t *testing.T) { 51 moduleTypeFactories := map[string]android.ModuleFactory{ 52 "custom": customModuleFactoryBase, 53 "custom_test": customTestModuleFactoryBase, 54 "custom_defaults": customDefaultsModuleFactoryBasic, 55 } 56 ruleShims := CreateRuleShims(moduleTypeFactories) 57 58 if len(ruleShims) != 1 { 59 t.Errorf("Expected to generate 1 rule shim, but got %d", len(ruleShims)) 60 } 61 62 ruleShim := ruleShims["bp2build"] 63 expectedRules := []string{ 64 "custom", 65 "custom_defaults", 66 "custom_test_", 67 } 68 69 if len(ruleShim.rules) != len(expectedRules) { 70 t.Errorf("Expected %d rules, but got %d", len(expectedRules), len(ruleShim.rules)) 71 } 72 73 for i, rule := range ruleShim.rules { 74 if rule != expectedRules[i] { 75 t.Errorf("Expected rule shim to contain %s, but got %s", expectedRules[i], rule) 76 } 77 } 78 expectedBzl := `load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo") 79 80def _custom_impl(ctx): 81 return [SoongModuleInfo()] 82 83custom = rule( 84 implementation = _custom_impl, 85 attrs = { 86 "soong_module_name": attr.string(mandatory = True), 87 "soong_module_variant": attr.string(), 88 "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]), 89 "arch_paths": attr.string_list(), 90 # bazel_module start 91# "label": attr.string(), 92# "bp2build_available": attr.bool(), 93 # bazel_module end 94 "bool_prop": attr.bool(), 95 "bool_ptr_prop": attr.bool(), 96 "int64_ptr_prop": attr.int(), 97 # nested_props start 98# "nested_prop": attr.string(), 99 # nested_props end 100 # nested_props_ptr start 101# "nested_prop": attr.string(), 102 # nested_props_ptr end 103 "string_list_prop": attr.string_list(), 104 "string_prop": attr.string(), 105 "string_ptr_prop": attr.string(), 106 }, 107) 108 109def _custom_defaults_impl(ctx): 110 return [SoongModuleInfo()] 111 112custom_defaults = rule( 113 implementation = _custom_defaults_impl, 114 attrs = { 115 "soong_module_name": attr.string(mandatory = True), 116 "soong_module_variant": attr.string(), 117 "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]), 118 "arch_paths": attr.string_list(), 119 "bool_prop": attr.bool(), 120 "bool_ptr_prop": attr.bool(), 121 "int64_ptr_prop": attr.int(), 122 # nested_props start 123# "nested_prop": attr.string(), 124 # nested_props end 125 # nested_props_ptr start 126# "nested_prop": attr.string(), 127 # nested_props_ptr end 128 "string_list_prop": attr.string_list(), 129 "string_prop": attr.string(), 130 "string_ptr_prop": attr.string(), 131 }, 132) 133 134def _custom_test__impl(ctx): 135 return [SoongModuleInfo()] 136 137custom_test_ = rule( 138 implementation = _custom_test__impl, 139 attrs = { 140 "soong_module_name": attr.string(mandatory = True), 141 "soong_module_variant": attr.string(), 142 "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]), 143 "arch_paths": attr.string_list(), 144 "bool_prop": attr.bool(), 145 "bool_ptr_prop": attr.bool(), 146 "int64_ptr_prop": attr.int(), 147 # nested_props start 148# "nested_prop": attr.string(), 149 # nested_props end 150 # nested_props_ptr start 151# "nested_prop": attr.string(), 152 # nested_props_ptr end 153 "string_list_prop": attr.string_list(), 154 "string_prop": attr.string(), 155 "string_ptr_prop": attr.string(), 156 # test_prop start 157# "test_string_prop": attr.string(), 158 # test_prop end 159 }, 160) 161` 162 163 if ruleShim.content != expectedBzl { 164 t.Errorf( 165 "Expected the generated rule shim bzl to be:\n%s\nbut got:\n%s", 166 expectedBzl, 167 ruleShim.content) 168 } 169} 170 171func TestGenerateSoongModuleBzl(t *testing.T) { 172 ruleShims := map[string]RuleShim{ 173 "file1": RuleShim{ 174 rules: []string{"a", "b"}, 175 content: "irrelevant", 176 }, 177 "file2": RuleShim{ 178 rules: []string{"c", "d"}, 179 content: "irrelevant", 180 }, 181 } 182 files := CreateBazelFiles(ruleShims, make(map[string]BazelTargets), QueryView) 183 184 var actualSoongModuleBzl BazelFile 185 for _, f := range files { 186 if f.Basename == "soong_module.bzl" { 187 actualSoongModuleBzl = f 188 } 189 } 190 191 expectedLoad := `load("//build/bazel/queryview_rules:file1.bzl", "a", "b") 192load("//build/bazel/queryview_rules:file2.bzl", "c", "d") 193` 194 expectedRuleMap := `soong_module_rule_map = { 195 "a": a, 196 "b": b, 197 "c": c, 198 "d": d, 199}` 200 if !strings.Contains(actualSoongModuleBzl.Contents, expectedLoad) { 201 t.Errorf( 202 "Generated soong_module.bzl:\n\n%s\n\n"+ 203 "Could not find the load statement in the generated soong_module.bzl:\n%s", 204 actualSoongModuleBzl.Contents, 205 expectedLoad) 206 } 207 208 if !strings.Contains(actualSoongModuleBzl.Contents, expectedRuleMap) { 209 t.Errorf( 210 "Generated soong_module.bzl:\n\n%s\n\n"+ 211 "Could not find the module -> rule map in the generated soong_module.bzl:\n%s", 212 actualSoongModuleBzl.Contents, 213 expectedRuleMap) 214 } 215} 216