diff options
Diffstat (limited to 'bp2build/testing.go')
-rw-r--r-- | bp2build/testing.go | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/bp2build/testing.go b/bp2build/testing.go index 0e7ef4463..a81070942 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -21,6 +21,8 @@ specific-but-shared functionality among tests in package import ( "fmt" + "path/filepath" + "regexp" "sort" "strings" "testing" @@ -36,6 +38,9 @@ var ( buildDir string ) +var labelRegex = regexp.MustCompile(`^//([^: ]+):([^ ]+)$`) +var simpleModuleNameRegex = regexp.MustCompile(`^[^: /]+$`) + func checkError(t *testing.T, errs []error, expectedErr error) bool { t.Helper() @@ -82,7 +87,19 @@ type Bp2buildTestCase struct { // ExpectedBazelTargets compares the BazelTargets generated in `Dir` (if not empty). // Otherwise, it checks the BazelTargets generated by `Blueprint` in the root directory. ExpectedBazelTargets []string - Filesystem map[string]string + // AlreadyExistingBuildContents, if non-empty, simulates an already-present source BUILD file + // in the directory under test. The BUILD file has the given contents. This BUILD file + // will also be treated as "BUILD file to keep" by the simulated bp2build environment. + AlreadyExistingBuildContents string + + // StubbedBuildDefinitions, if non-empty, adds stub definitions to already-present source + // BUILD files for each bazel label given. The BUILD files with these stub definitions + // are added to the BUILD file given in AlreadyExistingBuildContents. + // Labels may be of the form //pkg/to:target_name (which would be defined in pkg/to/BUILD.bazel) + // or `target_name` (which would be defined in ./BUILD.bazel). + StubbedBuildDefinitions []string + + Filesystem map[string]string // Dir sets the directory which will be compared against the targets in ExpectedBazelTargets. // This should used in conjunction with the Filesystem property to check for targets // generated from a directory that is not the root. @@ -110,12 +127,51 @@ func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.Regi func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) { t.Helper() - dir := "." + if tc.Filesystem == nil { + tc.Filesystem = map[string]string{} + } + checkDir := "." + if tc.Dir != "" { + checkDir = tc.Dir + } + keepExistingBuildDirs := tc.KeepBuildFileForDirs + buildFilesToParse := []string{} + + if len(tc.StubbedBuildDefinitions) > 0 { + for _, buildDef := range tc.StubbedBuildDefinitions { + globalLabelMatch := labelRegex.FindStringSubmatch(buildDef) + var dir, targetName string + if len(globalLabelMatch) > 0 { + dir = globalLabelMatch[1] + targetName = globalLabelMatch[2] + } else { + if !simpleModuleNameRegex.MatchString(buildDef) { + t.Errorf("Stubbed build definition '%s' must be either a simple module name or of global target syntax (//foo/bar:baz).", buildDef) + return + } + dir = "." + targetName = buildDef + } + buildFilePath := filepath.Join(dir, "BUILD") + tc.Filesystem[buildFilePath] += + MakeBazelTarget( + "bp2build_test_stub", + targetName, + AttrNameToString{}) + keepExistingBuildDirs = append(keepExistingBuildDirs, dir) + buildFilesToParse = append(buildFilesToParse, buildFilePath) + } + } + if len(tc.AlreadyExistingBuildContents) > 0 { + buildFilePath := filepath.Join(checkDir, "BUILD") + tc.Filesystem[buildFilePath] += tc.AlreadyExistingBuildContents + keepExistingBuildDirs = append(keepExistingBuildDirs, checkDir) + buildFilesToParse = append(buildFilesToParse, buildFilePath) + } filesystem := make(map[string][]byte) for f, content := range tc.Filesystem { filesystem[f] = []byte(content) } - preparers := []android.FixturePreparer{ extraPreparer, android.FixtureMergeMockFs(filesystem), @@ -123,7 +179,7 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePre android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory) }), - android.FixtureModifyContext(func(ctx *android.TestContext) { + android.FixtureModifyContextWithMockFs(func(ctx *android.TestContext) { // A default configuration for tests to not have to specify bp2build_available on top level // targets. bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig( @@ -131,7 +187,7 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePre android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively, }, ) - for _, f := range tc.KeepBuildFileForDirs { + for _, f := range keepExistingBuildDirs { bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{ f: /*recursive=*/ false, }) @@ -141,6 +197,10 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePre // from cloning modules to their original state after mutators run. This // would lose some data intentionally set by these mutators. ctx.SkipCloneModulesAfterMutators = true + err := ctx.RegisterExistingBazelTargets(".", buildFilesToParse) + if err != nil { + t.Errorf("error parsing build files in test setup: %s", err) + } }), android.FixtureModifyEnv(func(env map[string]string) { if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps { @@ -159,10 +219,6 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePre return } - checkDir := dir - if tc.Dir != "" { - checkDir = tc.Dir - } expectedTargets := map[string][]string{ checkDir: tc.ExpectedBazelTargets, } @@ -441,7 +497,7 @@ func (m *customModule) dir() *string { return m.props.Dir } -func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { if p := m.props.One_to_many_prop; p != nil && *p { customBp2buildOneToMany(ctx, m) return @@ -461,7 +517,10 @@ func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } } } - productVariableProps := android.ProductVariableProperties(ctx, ctx.Module()) + productVariableProps, errs := android.ProductVariableProperties(ctx, ctx.Module()) + for _, err := range errs { + ctx.ModuleErrorf("ProductVariableProperties error: %s", err) + } if props, ok := productVariableProps["String_literal_prop"]; ok { for c, p := range props { if val, ok := p.(*string); ok { @@ -496,7 +555,7 @@ func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } -func (m *customModule) createConfigSetting(ctx android.TopDownMutatorContext) { +func (m *customModule) createConfigSetting(ctx android.Bp2buildMutatorContext) { csa := bazel.ConfigSettingAttributes{ Flag_values: bazel.StringMapAttribute{ "//build/bazel/rules/my_string_setting": m.Name(), @@ -531,7 +590,7 @@ func (c *customModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) // A bp2build mutator that uses load statements and creates a 1:M mapping from // module to target. -func customBp2buildOneToMany(ctx android.TopDownMutatorContext, m *customModule) { +func customBp2buildOneToMany(ctx android.Bp2buildMutatorContext, m *customModule) { baseName := m.Name() attrs := &customBazelModuleAttributes{} @@ -570,11 +629,10 @@ func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) { ctx.RegisterForBazelConversion() } -func SimpleModuleDoNotConvertBp2build(typ, name string) string { +func simpleModule(typ, name string) string { return fmt.Sprintf(` %s { name: "%s", - bazel_module: { bp2build_available: false }, }`, typ, name) } @@ -644,6 +702,7 @@ func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string { return "" } STUB_SUITE_ATTRS := map[string]string{ + "api_surface": "api_surface", "stubs_symbol_file": "symbol_file", "stubs_versions": "versions", "soname": "soname", |