5f1b3c7ad8
This is the bulk of the "allowlist v2" feature. It will disable bp2build generation for modules which have transitive dependencies without a bazel build definition. This CL includes this mutator, but doesn't register it as a bp2build mutator (outside of a few unit tests). This allows us to easily iterate on completion of this feature and ensure there are no launch blockers before we finalize the change in AOSP. Bug: 285631638 Test: Unit tests Change-Id: Ifb0a079c409ca19b02cafa3fab2efa0d3deebc50
241 lines
6.9 KiB
Go
241 lines
6.9 KiB
Go
// Copyright 2020 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package bp2build
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"android/soong/android"
|
|
)
|
|
|
|
func setUp() {
|
|
var err error
|
|
buildDir, err = ioutil.TempDir("", "bazel_queryview_test")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func tearDown() {
|
|
os.RemoveAll(buildDir)
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
run := func() int {
|
|
setUp()
|
|
defer tearDown()
|
|
|
|
return m.Run()
|
|
}
|
|
|
|
os.Exit(run())
|
|
}
|
|
|
|
func TestGenerateModuleRuleShims(t *testing.T) {
|
|
moduleTypeFactories := map[string]android.ModuleFactory{
|
|
"custom": customModuleFactoryBase,
|
|
"custom_test": customTestModuleFactoryBase,
|
|
"custom_defaults": customDefaultsModuleFactoryBasic,
|
|
}
|
|
ruleShims := CreateRuleShims(moduleTypeFactories)
|
|
|
|
if len(ruleShims) != 1 {
|
|
t.Errorf("Expected to generate 1 rule shim, but got %d", len(ruleShims))
|
|
}
|
|
|
|
ruleShim := ruleShims["bp2build"]
|
|
expectedRules := []string{
|
|
"custom",
|
|
"custom_defaults",
|
|
"custom_test_",
|
|
}
|
|
|
|
if len(ruleShim.rules) != len(expectedRules) {
|
|
t.Errorf("Expected %d rules, but got %d", len(expectedRules), len(ruleShim.rules))
|
|
}
|
|
|
|
for i, rule := range ruleShim.rules {
|
|
if rule != expectedRules[i] {
|
|
t.Errorf("Expected rule shim to contain %s, but got %s", expectedRules[i], rule)
|
|
}
|
|
}
|
|
expectedBzl := `load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo")
|
|
|
|
def _custom_impl(ctx):
|
|
return [SoongModuleInfo()]
|
|
|
|
custom = rule(
|
|
implementation = _custom_impl,
|
|
attrs = {
|
|
"soong_module_name": attr.string(mandatory = True),
|
|
"soong_module_variant": attr.string(),
|
|
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
|
|
"api": attr.string(),
|
|
"arch_paths": attr.string_list(),
|
|
"arch_paths_exclude": attr.string_list(),
|
|
# bazel_module start
|
|
# "label": attr.string(),
|
|
# "bp2build_available": attr.bool(),
|
|
# bazel_module end
|
|
"bool_prop": attr.bool(),
|
|
"bool_ptr_prop": attr.bool(),
|
|
"dir": attr.string(),
|
|
"does_not_convert_to_bazel": attr.bool(),
|
|
"embedded_prop": attr.string(),
|
|
"int64_ptr_prop": attr.int(),
|
|
# nested_props start
|
|
# "nested_prop": attr.string(),
|
|
# nested_props end
|
|
# nested_props_ptr start
|
|
# "nested_prop": attr.string(),
|
|
# nested_props_ptr end
|
|
"one_to_many_prop": attr.bool(),
|
|
"other_embedded_prop": attr.string(),
|
|
"string_list_prop": attr.string_list(),
|
|
"string_literal_prop": attr.string(),
|
|
"string_prop": attr.string(),
|
|
"string_ptr_prop": attr.string(),
|
|
"test_config_setting": attr.bool(),
|
|
},
|
|
)
|
|
|
|
def _custom_defaults_impl(ctx):
|
|
return [SoongModuleInfo()]
|
|
|
|
custom_defaults = rule(
|
|
implementation = _custom_defaults_impl,
|
|
attrs = {
|
|
"soong_module_name": attr.string(mandatory = True),
|
|
"soong_module_variant": attr.string(),
|
|
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
|
|
"api": attr.string(),
|
|
"arch_paths": attr.string_list(),
|
|
"arch_paths_exclude": attr.string_list(),
|
|
"bool_prop": attr.bool(),
|
|
"bool_ptr_prop": attr.bool(),
|
|
"dir": attr.string(),
|
|
"does_not_convert_to_bazel": attr.bool(),
|
|
"embedded_prop": attr.string(),
|
|
"int64_ptr_prop": attr.int(),
|
|
# nested_props start
|
|
# "nested_prop": attr.string(),
|
|
# nested_props end
|
|
# nested_props_ptr start
|
|
# "nested_prop": attr.string(),
|
|
# nested_props_ptr end
|
|
"one_to_many_prop": attr.bool(),
|
|
"other_embedded_prop": attr.string(),
|
|
"string_list_prop": attr.string_list(),
|
|
"string_literal_prop": attr.string(),
|
|
"string_prop": attr.string(),
|
|
"string_ptr_prop": attr.string(),
|
|
"test_config_setting": attr.bool(),
|
|
},
|
|
)
|
|
|
|
def _custom_test__impl(ctx):
|
|
return [SoongModuleInfo()]
|
|
|
|
custom_test_ = rule(
|
|
implementation = _custom_test__impl,
|
|
attrs = {
|
|
"soong_module_name": attr.string(mandatory = True),
|
|
"soong_module_variant": attr.string(),
|
|
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
|
|
"api": attr.string(),
|
|
"arch_paths": attr.string_list(),
|
|
"arch_paths_exclude": attr.string_list(),
|
|
"bool_prop": attr.bool(),
|
|
"bool_ptr_prop": attr.bool(),
|
|
"dir": attr.string(),
|
|
"does_not_convert_to_bazel": attr.bool(),
|
|
"embedded_prop": attr.string(),
|
|
"int64_ptr_prop": attr.int(),
|
|
# nested_props start
|
|
# "nested_prop": attr.string(),
|
|
# nested_props end
|
|
# nested_props_ptr start
|
|
# "nested_prop": attr.string(),
|
|
# nested_props_ptr end
|
|
"one_to_many_prop": attr.bool(),
|
|
"other_embedded_prop": attr.string(),
|
|
"string_list_prop": attr.string_list(),
|
|
"string_literal_prop": attr.string(),
|
|
"string_prop": attr.string(),
|
|
"string_ptr_prop": attr.string(),
|
|
"test_config_setting": attr.bool(),
|
|
# test_prop start
|
|
# "test_string_prop": attr.string(),
|
|
# test_prop end
|
|
},
|
|
)
|
|
`
|
|
|
|
if ruleShim.content != expectedBzl {
|
|
t.Errorf(
|
|
"Expected the generated rule shim bzl to be:\n%s\nbut got:\n%s",
|
|
expectedBzl,
|
|
ruleShim.content)
|
|
}
|
|
}
|
|
|
|
func TestGenerateSoongModuleBzl(t *testing.T) {
|
|
ruleShims := map[string]RuleShim{
|
|
"file1": RuleShim{
|
|
rules: []string{"a", "b"},
|
|
content: "irrelevant",
|
|
},
|
|
"file2": RuleShim{
|
|
rules: []string{"c", "d"},
|
|
content: "irrelevant",
|
|
},
|
|
}
|
|
files := CreateBazelFiles(ruleShims, make(map[string]BazelTargets), QueryView)
|
|
|
|
var actualSoongModuleBzl BazelFile
|
|
for _, f := range files {
|
|
if f.Basename == "soong_module.bzl" {
|
|
actualSoongModuleBzl = f
|
|
}
|
|
}
|
|
|
|
expectedLoad := `load("//build/bazel/queryview_rules:file1.bzl", "a", "b")
|
|
load("//build/bazel/queryview_rules:file2.bzl", "c", "d")
|
|
`
|
|
expectedRuleMap := `soong_module_rule_map = {
|
|
"a": a,
|
|
"b": b,
|
|
"c": c,
|
|
"d": d,
|
|
}`
|
|
if !strings.Contains(actualSoongModuleBzl.Contents, expectedLoad) {
|
|
t.Errorf(
|
|
"Generated soong_module.bzl:\n\n%s\n\n"+
|
|
"Could not find the load statement in the generated soong_module.bzl:\n%s",
|
|
actualSoongModuleBzl.Contents,
|
|
expectedLoad)
|
|
}
|
|
|
|
if !strings.Contains(actualSoongModuleBzl.Contents, expectedRuleMap) {
|
|
t.Errorf(
|
|
"Generated soong_module.bzl:\n\n%s\n\n"+
|
|
"Could not find the module -> rule map in the generated soong_module.bzl:\n%s",
|
|
actualSoongModuleBzl.Contents,
|
|
expectedRuleMap)
|
|
}
|
|
}
|