diff options
| -rw-r--r-- | android/androidmk_test.go | 26 | ||||
| -rw-r--r-- | android/apex_test.go | 2 | ||||
| -rw-r--r-- | android/arch_test.go | 69 | ||||
| -rw-r--r-- | android/config.go | 21 | ||||
| -rw-r--r-- | android/csuite_config.go | 6 | ||||
| -rw-r--r-- | android/csuite_config_test.go | 33 | ||||
| -rw-r--r-- | android/defaults_test.go | 70 | ||||
| -rw-r--r-- | android/fixture.go | 21 | ||||
| -rw-r--r-- | android/fixture_test.go | 5 | ||||
| -rw-r--r-- | android/module_test.go | 40 | ||||
| -rw-r--r-- | android/namespace_test.go | 57 | ||||
| -rw-r--r-- | android/paths_test.go | 114 | ||||
| -rw-r--r-- | android/rule_builder_test.go | 167 | ||||
| -rw-r--r-- | android/test_asserts.go | 9 | ||||
| -rw-r--r-- | apex/apex.go | 2 | ||||
| -rw-r--r-- | apex/apex_test.go | 7 | ||||
| -rw-r--r-- | java/platform_compat_config.go | 44 | ||||
| -rw-r--r-- | ui/build/soong.go | 18 | ||||
| -rw-r--r-- | xml/Android.bp | 1 | ||||
| -rw-r--r-- | xml/testing.go | 19 | ||||
| -rw-r--r-- | xml/xml.go | 6 | ||||
| -rw-r--r-- | xml/xml_test.go | 66 |
22 files changed, 368 insertions, 435 deletions
diff --git a/android/androidmk_test.go b/android/androidmk_test.go index 2f568fb13..230b1ec0b 100644 --- a/android/androidmk_test.go +++ b/android/androidmk_test.go @@ -141,21 +141,17 @@ func customModuleFactory() Module { // bp module and then returns the config and the custom module called "foo". func buildContextAndCustomModuleFoo(t *testing.T, bp string) (*TestContext, *customModule) { t.Helper() - config := TestConfig(buildDir, nil, bp, nil) - config.katiEnabled = true // Enable androidmk Singleton - - ctx := NewTestContext(config) - ctx.RegisterSingletonType("androidmk", AndroidMkSingleton) - ctx.RegisterModuleType("custom", customModuleFactory) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) - - module := ctx.ModuleForTests("foo", "").Module().(*customModule) - return ctx, module + result := emptyTestFixtureFactory.RunTest(t, + // Enable androidmk Singleton + PrepareForTestWithAndroidMk, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("custom", customModuleFactory) + }), + FixtureWithRootAndroidBp(bp), + ) + + module := result.ModuleForTests("foo", "").Module().(*customModule) + return result.TestContext, module } func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) { diff --git a/android/apex_test.go b/android/apex_test.go index 1f786e65f..b5323e8af 100644 --- a/android/apex_test.go +++ b/android/apex_test.go @@ -121,7 +121,7 @@ func Test_mergeApexVariations(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - config := TestConfig(buildDir, nil, "", nil) + config := TestConfig(t.TempDir(), nil, "", nil) ctx := &configErrorWrapper{config: config} gotMerged, gotAliases := mergeApexVariations(ctx, tt.in) if !reflect.DeepEqual(gotMerged, tt.wantMerged) { diff --git a/android/arch_test.go b/android/arch_test.go index 4cef4c8e6..09cb52370 100644 --- a/android/arch_test.go +++ b/android/arch_test.go @@ -273,6 +273,13 @@ func archTestModuleFactory() Module { return m } +var prepareForArchTest = GroupFixturePreparers( + PrepareForTestWithArchMutator, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("module", archTestModuleFactory) + }), +) + func TestArchMutator(t *testing.T) { var buildOSVariants []string var buildOS32Variants []string @@ -309,7 +316,7 @@ func TestArchMutator(t *testing.T) { testCases := []struct { name string - config func(Config) + preparer FixturePreparer fooVariants []string barVariants []string bazVariants []string @@ -317,7 +324,7 @@ func TestArchMutator(t *testing.T) { }{ { name: "normal", - config: nil, + preparer: nil, fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"}, barVariants: append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"), bazVariants: nil, @@ -325,11 +332,11 @@ func TestArchMutator(t *testing.T) { }, { name: "host-only", - config: func(config Config) { + preparer: FixtureModifyConfig(func(config Config) { config.BuildOSTarget = Target{} config.BuildOSCommonTarget = Target{} config.Targets[Android] = nil - }, + }), fooVariants: nil, barVariants: buildOSVariants, bazVariants: nil, @@ -351,19 +358,13 @@ func TestArchMutator(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - config := TestArchConfig(buildDir, nil, bp, nil) - - ctx := NewTestArchContext(config) - ctx.RegisterModuleType("module", archTestModuleFactory) - ctx.Register() - if tt.config != nil { - tt.config(config) - } - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + result := emptyTestFixtureFactory.RunTest(t, + prepareForArchTest, + // Test specific preparer + OptionalFixturePreparer(tt.preparer), + FixtureWithRootAndroidBp(bp), + ) + ctx := result.TestContext if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) { t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g) @@ -412,14 +413,14 @@ func TestArchMutatorNativeBridge(t *testing.T) { testCases := []struct { name string - config func(Config) + preparer FixturePreparer fooVariants []string barVariants []string bazVariants []string }{ { name: "normal", - config: nil, + preparer: nil, fooVariants: []string{"android_x86_64_silvermont", "android_x86_silvermont"}, barVariants: []string{"android_x86_64_silvermont", "android_native_bridge_arm64_armv8-a", "android_x86_silvermont", "android_native_bridge_arm_armv7-a-neon"}, bazVariants: []string{"android_native_bridge_arm64_armv8-a", "android_native_bridge_arm_armv7-a-neon"}, @@ -440,19 +441,23 @@ func TestArchMutatorNativeBridge(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - config := TestArchConfigNativeBridge(buildDir, nil, bp, nil) - - ctx := NewTestArchContext(config) - ctx.RegisterModuleType("module", archTestModuleFactory) - ctx.Register() - if tt.config != nil { - tt.config(config) - } - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + result := emptyTestFixtureFactory.RunTest(t, + prepareForArchTest, + // Test specific preparer + OptionalFixturePreparer(tt.preparer), + // Prepare for native bridge test + FixtureModifyConfig(func(config Config) { + config.Targets[Android] = []Target{ + {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, + {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false}, + {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64", false}, + {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm", false}, + } + }), + FixtureWithRootAndroidBp(bp), + ) + + ctx := result.TestContext if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) { t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g) diff --git a/android/config.go b/android/config.go index 2f8cb57f1..b6c862ddc 100644 --- a/android/config.go +++ b/android/config.go @@ -73,6 +73,10 @@ func (c Config) NinjaBuildDir() string { return c.buildDir } +func (c Config) DebugCompilation() bool { + return false // Never compile Go code in the main build for debugging +} + func (c Config) SrcDir() string { return c.srcDir } @@ -279,23 +283,6 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string return Config{config} } -// TestArchConfigNativeBridge returns a Config object suitable for using -// for tests that need to run the arch mutator for native bridge supported -// archs. -func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { - testConfig := TestArchConfig(buildDir, env, bp, fs) - config := testConfig.config - - config.Targets[Android] = []Target{ - {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, - {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false}, - {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64", false}, - {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm", false}, - } - - return testConfig -} - func fuchsiaTargets() map[OsType][]Target { return map[OsType][]Target{ Fuchsia: { diff --git a/android/csuite_config.go b/android/csuite_config.go index 56d240874..20bd03563 100644 --- a/android/csuite_config.go +++ b/android/csuite_config.go @@ -15,7 +15,11 @@ package android func init() { - RegisterModuleType("csuite_config", CSuiteConfigFactory) + registerCSuiteBuildComponents(InitRegistrationContext) +} + +func registerCSuiteBuildComponents(ctx RegistrationContext) { + ctx.RegisterModuleType("csuite_config", CSuiteConfigFactory) } type csuiteConfigProperties struct { diff --git a/android/csuite_config_test.go b/android/csuite_config_test.go index 9ac959e18..d30ff6926 100644 --- a/android/csuite_config_test.go +++ b/android/csuite_config_test.go @@ -18,32 +18,21 @@ import ( "testing" ) -func testCSuiteConfig(test *testing.T, bpFileContents string) *TestContext { - config := TestArchConfig(buildDir, nil, bpFileContents, nil) - - ctx := NewTestArchContext(config) - ctx.RegisterModuleType("csuite_config", CSuiteConfigFactory) - ctx.Register() - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(test, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(test, errs) - return ctx -} - func TestCSuiteConfig(t *testing.T) { - ctx := testCSuiteConfig(t, ` -csuite_config { name: "plain"} -csuite_config { name: "with_manifest", test_config: "manifest.xml" } -`) + result := emptyTestFixtureFactory.RunTest(t, + PrepareForTestWithArchMutator, + FixtureRegisterWithContext(registerCSuiteBuildComponents), + FixtureWithRootAndroidBp(` + csuite_config { name: "plain"} + csuite_config { name: "with_manifest", test_config: "manifest.xml" } + `), + ) - variants := ctx.ModuleVariantsForTests("plain") + variants := result.ModuleVariantsForTests("plain") if len(variants) > 1 { t.Errorf("expected 1, got %d", len(variants)) } - expectedOutputFilename := ctx.ModuleForTests( + outputFilename := result.ModuleForTests( "plain", variants[0]).Module().(*CSuiteConfig).OutputFilePath.Base() - if expectedOutputFilename != "plain" { - t.Errorf("expected plain, got %q", expectedOutputFilename) - } + AssertStringEquals(t, "output file name", "plain", outputFilename) } diff --git a/android/defaults_test.go b/android/defaults_test.go index 2689d864e..b33cb527c 100644 --- a/android/defaults_test.go +++ b/android/defaults_test.go @@ -15,10 +15,7 @@ package android import ( - "reflect" "testing" - - "github.com/google/blueprint/proptools" ) type defaultsTestProperties struct { @@ -58,6 +55,14 @@ func defaultsTestDefaultsFactory() Module { return defaults } +var prepareForDefaultsTest = GroupFixturePreparers( + PrepareForTestWithDefaults, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("test", defaultsTestModuleFactory) + ctx.RegisterModuleType("defaults", defaultsTestDefaultsFactory) + }), +) + func TestDefaults(t *testing.T) { bp := ` defaults { @@ -78,27 +83,14 @@ func TestDefaults(t *testing.T) { } ` - config := TestConfig(buildDir, nil, bp, nil) - - ctx := NewTestContext(config) - - ctx.RegisterModuleType("test", defaultsTestModuleFactory) - ctx.RegisterModuleType("defaults", defaultsTestDefaultsFactory) - - ctx.PreArchMutators(RegisterDefaultsPreArchMutators) - - ctx.Register() + result := emptyTestFixtureFactory.RunTest(t, + prepareForDefaultsTest, + FixtureWithRootAndroidBp(bp), + ) - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + foo := result.Module("foo", "").(*defaultsTestModule) - foo := ctx.ModuleForTests("foo", "").Module().(*defaultsTestModule) - - if g, w := foo.properties.Foo, []string{"transitive", "defaults", "module"}; !reflect.DeepEqual(g, w) { - t.Errorf("expected foo %q, got %q", w, g) - } + AssertDeepEquals(t, "foo", []string{"transitive", "defaults", "module"}, foo.properties.Foo) } func TestDefaultsAllowMissingDependencies(t *testing.T) { @@ -122,34 +114,18 @@ func TestDefaultsAllowMissingDependencies(t *testing.T) { } ` - config := TestConfig(buildDir, nil, bp, nil) - config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true) - - ctx := NewTestContext(config) - ctx.SetAllowMissingDependencies(true) - - ctx.RegisterModuleType("test", defaultsTestModuleFactory) - ctx.RegisterModuleType("defaults", defaultsTestDefaultsFactory) - - ctx.PreArchMutators(RegisterDefaultsPreArchMutators) - - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + result := emptyTestFixtureFactory.RunTest(t, + prepareForDefaultsTest, + PrepareForTestWithAllowMissingDependencies, + FixtureWithRootAndroidBp(bp), + ) - missingDefaults := ctx.ModuleForTests("missing_defaults", "").Output("out") - missingTransitiveDefaults := ctx.ModuleForTests("missing_transitive_defaults", "").Output("out") + missingDefaults := result.ModuleForTests("missing_defaults", "").Output("out") + missingTransitiveDefaults := result.ModuleForTests("missing_transitive_defaults", "").Output("out") - if missingDefaults.Rule != ErrorRule { - t.Errorf("expected missing_defaults rule to be ErrorRule, got %#v", missingDefaults.Rule) - } + AssertSame(t, "missing_defaults rule", ErrorRule, missingDefaults.Rule) - if g, w := missingDefaults.Args["error"], "module missing_defaults missing dependencies: missing\n"; g != w { - t.Errorf("want error %q, got %q", w, g) - } + AssertStringEquals(t, "missing_defaults", "module missing_defaults missing dependencies: missing\n", missingDefaults.Args["error"]) // TODO: missing transitive defaults is currently not handled _ = missingTransitiveDefaults diff --git a/android/fixture.go b/android/fixture.go index 928967d8c..6db43e25a 100644 --- a/android/fixture.go +++ b/android/fixture.go @@ -381,6 +381,19 @@ func GroupFixturePreparers(preparers ...FixturePreparer) FixturePreparer { return &compositeFixturePreparer{dedupAndFlattenPreparers(nil, preparers)} } +// NullFixturePreparer is a preparer that does nothing. +var NullFixturePreparer = GroupFixturePreparers() + +// OptionalFixturePreparer will return the supplied preparer if it is non-nil, otherwise it will +// return the NullFixturePreparer +func OptionalFixturePreparer(preparer FixturePreparer) FixturePreparer { + if preparer == nil { + return NullFixturePreparer + } else { + return preparer + } +} + type simpleFixturePreparerVisitor func(preparer *simpleFixturePreparer) // FixturePreparer is an opaque interface that can change a fixture. @@ -493,6 +506,14 @@ var FixtureExpectsNoErrors = FixtureCustomErrorHandler( }, ) +// FixtureIgnoreErrors ignores any errors. +// +// If this is used then it is the responsibility of the test to check the TestResult.Errs does not +// contain any unexpected errors. +var FixtureIgnoreErrors = FixtureCustomErrorHandler(func(t *testing.T, result *TestResult) { + // Ignore the errors +}) + // FixtureExpectsAtLeastOneMatchingError returns an error handler that will cause the test to fail // if at least one error that matches the regular expression is not found. // diff --git a/android/fixture_test.go b/android/fixture_test.go index a31ef1654..0042e5b16 100644 --- a/android/fixture_test.go +++ b/android/fixture_test.go @@ -30,9 +30,10 @@ func TestFixtureDedup(t *testing.T) { preparer1 := appendToList("preparer1") preparer2 := appendToList("preparer2") preparer3 := appendToList("preparer3") - preparer4 := appendToList("preparer4") + preparer4 := OptionalFixturePreparer(appendToList("preparer4")) + nilPreparer := OptionalFixturePreparer(nil) - preparer1Then2 := GroupFixturePreparers(preparer1, preparer2) + preparer1Then2 := GroupFixturePreparers(preparer1, preparer2, nilPreparer) preparer2Then1 := GroupFixturePreparers(preparer2, preparer1) diff --git a/android/module_test.go b/android/module_test.go index e3cc61332..99bf30afc 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -163,6 +163,10 @@ func depsModuleFactory() Module { return m } +var prepareForModuleTests = FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("deps", depsModuleFactory) +}) + func TestErrorDependsOnDisabledModule(t *testing.T) { bp := ` deps { @@ -175,20 +179,15 @@ func TestErrorDependsOnDisabledModule(t *testing.T) { } ` - config := TestConfig(buildDir, nil, bp, nil) - - ctx := NewTestContext(config) - ctx.RegisterModuleType("deps", depsModuleFactory) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfNoMatchingErrors(t, `module "foo": depends on disabled module "bar"`, errs) + emptyTestFixtureFactory. + ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": depends on disabled module "bar"`)). + RunTest(t, + prepareForModuleTests, + FixtureWithRootAndroidBp(bp)) } func TestValidateCorrectBuildParams(t *testing.T) { - config := TestConfig(buildDir, nil, "", nil) + config := TestConfig(t.TempDir(), nil, "", nil) pathContext := PathContextForTesting(config) bparams := convertBuildParams(BuildParams{ // Test with Output @@ -214,7 +213,7 @@ func TestValidateCorrectBuildParams(t *testing.T) { } func TestValidateIncorrectBuildParams(t *testing.T) { - config := TestConfig(buildDir, nil, "", nil) + config := TestConfig(t.TempDir(), nil, "", nil) pathContext := PathContextForTesting(config) params := BuildParams{ Output: PathForOutput(pathContext, "regular_output"), @@ -257,16 +256,6 @@ func TestDistErrorChecking(t *testing.T) { } ` - config := TestConfig(buildDir, nil, bp, nil) - - ctx := NewTestContext(config) - ctx.RegisterModuleType("deps", depsModuleFactory) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - expectedErrs := []string{ "\\QAndroid.bp:5:13: module \"foo\": dist.dest: Path is outside directory: ../invalid-dest\\E", "\\QAndroid.bp:6:12: module \"foo\": dist.dir: Path is outside directory: ../invalid-dir\\E", @@ -278,5 +267,10 @@ func TestDistErrorChecking(t *testing.T) { "\\QAndroid.bp:17:14: module \"foo\": dists[1].dir: Path is outside directory: ../invalid-dir1\\E", "\\QAndroid.bp:18:17: module \"foo\": dists[1].suffix: Suffix may not contain a '/' character.\\E", } - CheckErrorsAgainstExpectations(t, errs, expectedErrs) + + emptyTestFixtureFactory. + ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)). + RunTest(t, + prepareForModuleTests, + FixtureWithRootAndroidBp(bp)) } diff --git a/android/namespace_test.go b/android/namespace_test.go index 45e2cdb7b..1caf5a87f 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -143,7 +143,7 @@ func TestDependingOnModuleInImportedNamespace(t *testing.T) { } func TestDependingOnModuleInNonImportedNamespace(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` soong_namespace { @@ -378,7 +378,7 @@ func TestTwoNamespacesCanImportEachOther(t *testing.T) { } func TestImportingNonexistentNamespace(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` soong_namespace { @@ -402,7 +402,7 @@ func TestImportingNonexistentNamespace(t *testing.T) { } func TestNamespacesDontInheritParentNamespaces(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` soong_namespace { @@ -455,7 +455,7 @@ func TestModulesDoReceiveParentNamespace(t *testing.T) { } func TestNamespaceImportsNotTransitive(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` soong_namespace { @@ -496,7 +496,7 @@ Module "a" can be found in these namespaces: ["dir1"]`), } func TestTwoNamepacesInSameDir(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` soong_namespace { @@ -516,7 +516,7 @@ func TestTwoNamepacesInSameDir(t *testing.T) { } func TestNamespaceNotAtTopOfFile(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` test_module { @@ -537,7 +537,7 @@ func TestNamespaceNotAtTopOfFile(t *testing.T) { } func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) { - _, errs := setupTestExpectErrs( + _, errs := setupTestExpectErrs(t, map[string]string{ "dir1": ` soong_namespace { @@ -562,7 +562,7 @@ func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) { } func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) { - _, errs := setupTestFromFiles( + _, errs := setupTestFromFiles(t, map[string][]byte{ "Android.bp": []byte(` build = ["include.bp"] @@ -632,39 +632,38 @@ func mockFiles(bps map[string]string) (files map[string][]byte) { return files } -func setupTestFromFiles(bps map[string][]byte) (ctx *TestContext, errs []error) { - config := TestConfig(buildDir, nil, "", bps) +func setupTestFromFiles(t *testing.T, bps MockFS) (ctx *TestContext, errs []error) { + result := emptyTestFixtureFactory. + // Ignore errors for now so tests can check them later. + ExtendWithErrorHandler(FixtureIgnoreErrors). + RunTest(t, + FixtureModifyContext(func(ctx *TestContext) { + ctx.RegisterModuleType("test_module", newTestModule) + ctx.RegisterModuleType("soong_namespace", NamespaceFactory) + ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule) + ctx.PreArchMutators(RegisterNamespaceMutator) + ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { + ctx.BottomUp("rename", renameMutator) + }) + }), + bps.AddToFixture(), + ) - ctx = NewTestContext(config) - ctx.RegisterModuleType("test_module", newTestModule) - ctx.RegisterModuleType("soong_namespace", NamespaceFactory) - ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule) - ctx.PreArchMutators(RegisterNamespaceMutator) - ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { - ctx.BottomUp("rename", renameMutator) - }) - ctx.Register() - - _, errs = ctx.ParseBlueprintsFiles("Android.bp") - if len(errs) > 0 { - return ctx, errs - } - _, errs = ctx.PrepareBuildActions(config) - return ctx, errs + return result.TestContext, result.Errs } -func setupTestExpectErrs(bps map[string]string) (ctx *TestContext, errs []error) { +func setupTestExpectErrs(t *testing.T, bps map[string]string) (ctx *TestContext, errs []error) { files := make(map[string][]byte, len(bps)) files["Android.bp"] = []byte("") for dir, text := range bps { files[filepath.Join(dir, "Android.bp")] = []byte(text) } - return setupTestFromFiles(files) + return setupTestFromFiles(t, files) } func setupTest(t *testing.T, bps map[string]string) (ctx *TestContext) { t.Helper() - ctx, errs := setupTestExpectErrs(bps) + ctx, errs := setupTestExpectErrs(t, bps) FailIfErrored(t, errs) return ctx } diff --git a/android/paths_test.go b/android/paths_test.go index 3734ed201..c5fc10ebb 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -21,8 +21,6 @@ import ( "strconv" "strings" "testing" - - "github.com/google/blueprint/proptools" ) type strsTestCase struct { @@ -977,7 +975,7 @@ type pathForModuleSrcTestCase struct { rel string } -func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) { +func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { fgBp := ` @@ -995,7 +993,7 @@ func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSr } ` - mockFS := map[string][]byte{ + mockFS := MockFS{ "fg/Android.bp": []byte(fgBp), "foo/Android.bp": []byte(test.bp), "ofp/Android.bp": []byte(ofpBp), @@ -1007,37 +1005,21 @@ func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSr "foo/src_special/$": nil, } - config := TestConfig(buildDir, nil, "", mockFS) - - ctx := NewTestContext(config) - - ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) - ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory) - ctx.RegisterModuleType("filegroup", FileGroupFactory) - - ctx.Register() - _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) - - m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) - - if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) { - t.Errorf("want srcs %q, got %q", w, g) - } - - if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) { - t.Errorf("want rels %q, got %q", w, g) - } - - if g, w := m.src, test.src; g != w { - t.Errorf("want src %q, got %q", w, g) - } - - if g, w := m.rel, test.rel; g != w { - t.Errorf("want rel %q, got %q", w, g) - } + result := emptyTestFixtureFactory.RunTest(t, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) + ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory) + ctx.RegisterModuleType("filegroup", FileGroupFactory) + }), + mockFS.AddToFixture(), + ) + + m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) + + AssertStringPathsRelativeToTopEquals(t, "srcs", result.Config, test.srcs, m.srcs) + AssertStringPathsRelativeToTopEquals(t, "rels", result.Config, test.rels, m.rels) + AssertStringPathRelativeToTopEquals(t, "src", result.Config, test.src, m.src) + AssertStringPathRelativeToTopEquals(t, "rel", result.Config, test.rel, m.rel) }) } } @@ -1094,7 +1076,7 @@ func TestPathsForModuleSrc(t *testing.T) { name: "foo", srcs: [":b"], }`, - srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"}, + srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"}, rels: []string{"gen/b"}, }, { @@ -1104,7 +1086,7 @@ func TestPathsForModuleSrc(t *testing.T) { name: "foo", srcs: [":b{.tagged}"], }`, - srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"}, + srcs: []string{"out/soong/.intermediates/ofp/b/gen/c"}, rels: []string{"gen/c"}, }, { @@ -1119,7 +1101,7 @@ func TestPathsForModuleSrc(t *testing.T) { name: "c", outs: ["gen/c"], }`, - srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"}, + srcs: []string{"out/soong/.intermediates/ofp/b/gen/b"}, rels: []string{"gen/b"}, }, { @@ -1134,7 +1116,7 @@ func TestPathsForModuleSrc(t *testing.T) { }, } - testPathForModuleSrc(t, buildDir, tests) + testPathForModuleSrc(t, tests) } func TestPathForModuleSrc(t *testing.T) { @@ -1176,7 +1158,7 @@ func TestPathForModuleSrc(t *testing.T) { name: "foo", src: ":b", }`, - src: buildDir + "/.intermediates/ofp/b/gen/b", + src: "out/soong/.intermediates/ofp/b/gen/b", rel: "gen/b", }, { @@ -1186,7 +1168,7 @@ func TestPathForModuleSrc(t *testing.T) { name: "foo", src: ":b{.tagged}", }`, - src: buildDir + "/.intermediates/ofp/b/gen/c", + src: "out/soong/.intermediates/ofp/b/gen/c", rel: "gen/c", }, { @@ -1201,7 +1183,7 @@ func TestPathForModuleSrc(t *testing.T) { }, } - testPathForModuleSrc(t, buildDir, tests) + testPathForModuleSrc(t, tests) } func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) { @@ -1221,44 +1203,24 @@ func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) { } ` - config := TestConfig(buildDir, nil, bp, nil) - config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true) - - ctx := NewTestContext(config) - ctx.SetAllowMissingDependencies(true) - - ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) - - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) - - foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) - - if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) { - t.Errorf("want foo missing deps %q, got %q", w, g) - } - - if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) { - t.Errorf("want foo srcs %q, got %q", w, g) - } + result := emptyTestFixtureFactory.RunTest(t, + PrepareForTestWithAllowMissingDependencies, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) + }), + FixtureWithRootAndroidBp(bp), + ) - if g, w := foo.src, ""; g != w { - t.Errorf("want foo src %q, got %q", w, g) - } + foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) - bar := ctx.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule) + AssertArrayString(t, "foo missing deps", []string{"a", "b", "c"}, foo.missingDeps) + AssertArrayString(t, "foo srcs", []string{}, foo.srcs) + AssertStringEquals(t, "foo src", "", foo.src) - if g, w := bar.missingDeps, []string{"d", "e"}; !reflect.DeepEqual(g, w) { - t.Errorf("want bar missing deps %q, got %q", w, g) - } + bar := result.ModuleForTests("bar", "").Module().(*pathForModuleSrcTestModule) - if g, w := bar.srcs, []string{}; !reflect.DeepEqual(g, w) { - t.Errorf("want bar srcs %q, got %q", w, g) - } + AssertArrayString(t, "bar missing deps", []string{"d", "e"}, bar.missingDeps) + AssertArrayString(t, "bar srcs", []string{}, bar.srcs) } func TestPathRelativeToTop(t *testing.T) { diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go index 080e236b4..bd3582070 100644 --- a/android/rule_builder_test.go +++ b/android/rule_builder_test.go @@ -17,7 +17,6 @@ package android import ( "fmt" "path/filepath" - "reflect" "regexp" "strings" "testing" @@ -361,32 +360,16 @@ func TestRuleBuilder(t *testing.T) { wantDepMergerCommand := "out/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer out/DepFile out/depfile out/ImplicitDepFile out/depfile2" - if g, w := rule.Commands(), wantCommands; !reflect.DeepEqual(g, w) { - t.Errorf("\nwant rule.Commands() = %#v\n got %#v", w, g) - } + AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) - if g, w := rule.Inputs(), wantInputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", w, g) - } - if g, w := rule.Outputs(), wantOutputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", w, g) - } - if g, w := rule.SymlinkOutputs(), wantSymlinkOutputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.SymlinkOutputs() = %#v\n got %#v", w, g) - } - if g, w := rule.DepFiles(), wantDepFiles; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.DepFiles() = %#v\n got %#v", w, g) - } - if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Tools() = %#v\n got %#v", w, g) - } - if g, w := rule.OrderOnlys(), wantOrderOnlys; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.OrderOnlys() = %#v\n got %#v", w, g) - } + AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) + AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) + AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs()) + AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) + AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) + AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) - if g, w := rule.depFileMergerCmd(rule.DepFiles()).String(), wantDepMergerCommand; g != w { - t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n got %#v", w, g) - } + AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) t.Run("sbox", func(t *testing.T) { @@ -402,29 +385,15 @@ func TestRuleBuilder(t *testing.T) { wantDepMergerCommand := "out/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" - if g, w := rule.Commands(), wantCommands; !reflect.DeepEqual(g, w) { - t.Errorf("\nwant rule.Commands() = %#v\n got %#v", w, g) - } + AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) - if g, w := rule.Inputs(), wantInputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", w, g) - } - if g, w := rule.Outputs(), wantOutputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", w, g) - } - if g, w := rule.DepFiles(), wantDepFiles; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.DepFiles() = %#v\n got %#v", w, g) - } - if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Tools() = %#v\n got %#v", w, g) - } - if g, w := rule.OrderOnlys(), wantOrderOnlys; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.OrderOnlys() = %#v\n got %#v", w, g) - } + AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) + AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) + AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) + AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) + AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) - if g, w := rule.depFileMergerCmd(rule.DepFiles()).String(), wantDepMergerCommand; g != w { - t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n got %#v", w, g) - } + AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) t.Run("sbox tools", func(t *testing.T) { @@ -440,29 +409,15 @@ func TestRuleBuilder(t *testing.T) { wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" - if g, w := rule.Commands(), wantCommands; !reflect.DeepEqual(g, w) { - t.Errorf("\nwant rule.Commands() = %#v\n got %#v", w, g) - } + AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) - if g, w := rule.Inputs(), wantInputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Inputs() = %#v\n got %#v", w, g) - } - if g, w := rule.Outputs(), wantOutputs; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Outputs() = %#v\n got %#v", w, g) - } - if g, w := rule.DepFiles(), wantDepFiles; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.DepFiles() = %#v\n got %#v", w, g) - } - if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.Tools() = %#v\n got %#v", w, g) - } - if g, w := rule.OrderOnlys(), wantOrderOnlys; !reflect.DeepEqual(w, g) { - t.Errorf("\nwant rule.OrderOnlys() = %#v\n got %#v", w, g) - } + AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) + AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) + AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) + AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) + AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) - if g, w := rule.depFileMergerCmd(rule.DepFiles()).String(), wantDepMergerCommand; g != w { - t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n got %#v", w, g) - } + AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) } @@ -524,8 +479,13 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, out, outDep, outDir, ma rule.Build("rule", "desc") } +var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory) + ctx.RegisterSingletonType("rule_builder_test", testRuleBuilderSingletonFactory) +}) + func TestRuleBuilder_Build(t *testing.T) { - fs := map[string][]byte{ + fs := MockFS{ "bar": nil, "cp": nil, } @@ -543,60 +503,46 @@ func TestRuleBuilder_Build(t *testing.T) { } ` - config := TestConfig(buildDir, nil, bp, fs) - ctx := NewTestContext(config) - ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory) - ctx.RegisterSingletonType("rule_builder_test", testRuleBuilderSingletonFactory) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + result := emptyTestFixtureFactory.RunTest(t, + prepareForRuleBuilderTest, + FixtureWithRootAndroidBp(bp), + fs.AddToFixture(), + ) check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraImplicits, extraCmdDeps []string) { t.Helper() command := params.RuleParams.Command re := regexp.MustCompile(" # hash of input list: [a-z0-9]*$") command = re.ReplaceAllLiteralString(command, "") - if command != wantCommand { - t.Errorf("\nwant RuleParams.Command = %q\n got %q", wantCommand, params.RuleParams.Command) - } + + AssertStringEquals(t, "RuleParams.Command", wantCommand, command) wantDeps := append([]string{"cp"}, extraCmdDeps...) - if !reflect.DeepEqual(params.RuleParams.CommandDeps, wantDeps) { - t.Errorf("\nwant RuleParams.CommandDeps = %q\n got %q", wantDeps, params.RuleParams.CommandDeps) - } + AssertArrayString(t, "RuleParams.CommandDeps", wantDeps, params.RuleParams.CommandDeps) - if params.RuleParams.Restat != wantRestat { - t.Errorf("want RuleParams.Restat = %v, got %v", wantRestat, params.RuleParams.Restat) - } + AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat) wantImplicits := append([]string{"bar"}, extraImplicits...) - if !reflect.DeepEqual(params.Implicits.Strings(), wantImplicits) { - t.Errorf("want Implicits = [%q], got %q", "bar", params.Implicits.Strings()) - } + AssertArrayString(t, "Implicits", wantImplicits, params.Implicits.Strings()) - if params.Output.String() != wantOutput { - t.Errorf("want Output = %q, got %q", wantOutput, params.Output) - } + AssertStringEquals(t, "Output", wantOutput, params.Output.String()) if len(params.ImplicitOutputs) != 0 { t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings()) } - if params.Depfile.String() != wantDepfile { - t.Errorf("want Depfile = %q, got %q", wantDepfile, params.Depfile) - } + AssertStringEquals(t, "Depfile", wantDepfile, params.Depfile.String()) if params.Deps != blueprint.DepsGCC { t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps) } } + buildDir := result.Config.BuildDir() + t.Run("module", func(t *testing.T) { outFile := filepath.Join(buildDir, ".intermediates", "foo", "gen", "foo") - check(t, ctx.ModuleForTests("foo", "").Rule("rule"), + check(t, result.ModuleForTests("foo", "").Rule("rule"), "cp bar "+outFile, outFile, outFile+".d", true, nil, nil) }) @@ -605,18 +551,18 @@ func TestRuleBuilder_Build(t *testing.T) { outFile := filepath.Join(outDir, "gen/foo_sbox") depFile := filepath.Join(outDir, "gen/foo_sbox.d") manifest := filepath.Join(outDir, "sbox.textproto") - sbox := filepath.Join(buildDir, "host", config.PrebuiltOS(), "bin/sbox") + sbox := filepath.Join(buildDir, "host", result.Config.PrebuiltOS(), "bin/sbox") sandboxPath := shared.TempDirForOutDir(buildDir) cmd := `rm -rf ` + outDir + `/gen && ` + sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest - check(t, ctx.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox"), + check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox"), cmd, outFile, depFile, false, []string{manifest}, []string{sbox}) }) t.Run("singleton", func(t *testing.T) { outFile := filepath.Join(buildDir, "singleton/gen/baz") - check(t, ctx.SingletonForTests("rule_builder_test").Rule("rule"), + check(t, result.SingletonForTests("rule_builder_test").Rule("rule"), "cp bar "+outFile, outFile, outFile+".d", true, nil, nil) }) } @@ -666,29 +612,22 @@ func TestRuleBuilderHashInputs(t *testing.T) { }, } - config := TestConfig(buildDir, nil, bp, nil) - ctx := NewTestContext(config) - ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + result := emptyTestFixtureFactory.RunTest(t, + prepareForRuleBuilderTest, + FixtureWithRootAndroidBp(bp), + ) for _, test := range testcases { t.Run(test.name, func(t *testing.T) { t.Run("sbox", func(t *testing.T) { - gen := ctx.ModuleForTests(test.name+"_sbox", "") + gen := result.ModuleForTests(test.name+"_sbox", "") manifest := RuleBuilderSboxProtoForTests(t, gen.Output("sbox.textproto")) hash := manifest.Commands[0].GetInputHash() - if g, w := hash, test.expectedHash; g != w { - t.Errorf("Expected has %q, got %q", w, g) - } + AssertStringEquals(t, "hash", test.expectedHash, hash) }) t.Run("", func(t *testing.T) { - gen := ctx.ModuleForTests(test.name+"", "") + gen := result.ModuleForTests(test.name+"", "") command := gen.Output("gen/" + test.name).RuleParams.Command if g, w := command, " # hash of input list: "+test.expectedHash; !strings.HasSuffix(g, w) { t.Errorf("Expected command line to end with %q, got %q", w, g) diff --git a/android/test_asserts.go b/android/test_asserts.go index e2df12fa9..4b5e9343e 100644 --- a/android/test_asserts.go +++ b/android/test_asserts.go @@ -22,6 +22,15 @@ import ( // This file contains general purpose test assert functions. +// AssertSame checks if the expected and actual values are equal and if they are not then +// it reports an error prefixed with the supplied message and including a reason for why it failed. +func AssertSame(t *testing.T, message string, expected interface{}, actual interface{}) { + t.Helper() + if actual != expected { + t.Errorf("%s: expected:\n%#v\nactual:\n%#v", message, expected, actual) + } +} + // AssertBoolEquals checks if the expected and actual values are equal and if they are not then it // reports an error prefixed with the supplied message and including a reason for why it failed. func AssertBoolEquals(t *testing.T, message string, expected bool, actual bool) { diff --git a/apex/apex.go b/apex/apex.go index d70d390b6..429465d80 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -569,7 +569,7 @@ var ( executableTag = dependencyTag{name: "executable", payload: true} fsTag = dependencyTag{name: "filesystem", payload: true} bootImageTag = dependencyTag{name: "bootImage", payload: true} - compatConfigTag = dependencyTag{name: "compatConfig", payload: true} + compatConfigTag = dependencyTag{name: "compatConfig", payload: true, sourceOnly: true} javaLibTag = dependencyTag{name: "javaLib", payload: true} jniLibTag = dependencyTag{name: "jniLib", payload: true} keyTag = dependencyTag{name: "key"} diff --git a/apex/apex_test.go b/apex/apex_test.go index 21cf5dfab..c01525b2a 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6018,6 +6018,13 @@ func TestCompatConfig(t *testing.T) { system_modules: "none", apex_available: [ "myapex" ], } + + // Make sure that a preferred prebuilt does not affect the apex contents. + prebuilt_platform_compat_config { + name: "myjar-platform-compat-config", + metadata: "compat-config/metadata.xml", + prefer: true, + } `) ctx := result.TestContext ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 4c3143a48..3c43a8e55 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -26,6 +26,7 @@ func init() { func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) { ctx.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory) ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory) + ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory) ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory) } @@ -116,6 +117,49 @@ func PlatformCompatConfigFactory() android.Module { return module } +// A prebuilt version of the platform compat config module. +type prebuiltCompatConfigModule struct { + android.ModuleBase + android.SdkBase + prebuilt android.Prebuilt + + properties prebuiltCompatConfigProperties + + metadataFile android.Path +} + +type prebuiltCompatConfigProperties struct { + Metadata *string `android:"path"` +} + +func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt { + return &module.prebuilt +} + +func (module *prebuiltCompatConfigModule) Name() string { + return module.prebuilt.Name(module.ModuleBase.Name()) +} + +func (module *prebuiltCompatConfigModule) compatConfigMetadata() android.Path { + return module.metadataFile +} + +var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil) + +func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + module.metadataFile = module.prebuilt.SingleSourcePath(ctx) +} + +// A prebuilt version of platform_compat_config that provides the metadata. +func prebuiltCompatConfigFactory() android.Module { + m := &prebuiltCompatConfigModule{} + m.AddProperties(&m.properties) + android.InitSingleSourcePrebuiltModule(m, &m.properties, "Metadata") + android.InitSdkAwareModule(m) + android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) + return m +} + // compat singleton rules type platformCompatConfigSingleton struct { metadata android.Path diff --git a/ui/build/soong.go b/ui/build/soong.go index fee5723bb..9afcb88ca 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -65,9 +65,10 @@ func writeEnvironmentFile(ctx Context, envFile string, envDeps map[string]string // A tiny struct used to tell Blueprint that it's in bootstrap mode. It would // probably be nicer to use a flag in bootstrap.Args instead. type BlueprintConfig struct { - srcDir string - buildDir string - ninjaBuildDir string + srcDir string + buildDir string + ninjaBuildDir string + debugCompilation bool } func (c BlueprintConfig) SrcDir() string { @@ -82,6 +83,10 @@ func (c BlueprintConfig) NinjaBuildDir() string { return c.ninjaBuildDir } +func (c BlueprintConfig) DebugCompilation() bool { + return c.debugCompilation +} + func bootstrapBlueprint(ctx Context, config Config) { ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap") defer ctx.EndTrace() @@ -102,9 +107,10 @@ func bootstrapBlueprint(ctx Context, config Config) { blueprintCtx := blueprint.NewContext() blueprintCtx.SetIgnoreUnknownModuleTypes(true) blueprintConfig := BlueprintConfig{ - srcDir: os.Getenv("TOP"), - buildDir: config.SoongOutDir(), - ninjaBuildDir: config.OutDir(), + srcDir: os.Getenv("TOP"), + buildDir: config.SoongOutDir(), + ninjaBuildDir: config.OutDir(), + debugCompilation: os.Getenv("SOONG_DELVE") != "", } bootstrap.RunBlueprint(args, blueprintCtx, blueprintConfig) diff --git a/xml/Android.bp b/xml/Android.bp index a5e5f4c7f..154293032 100644 --- a/xml/Android.bp +++ b/xml/Android.bp @@ -13,6 +13,7 @@ bootstrap_go_package { "soong-etc", ], srcs: [ + "testing.go", "xml.go", ], testSrcs: [ diff --git a/xml/testing.go b/xml/testing.go new file mode 100644 index 000000000..1d09f1055 --- /dev/null +++ b/xml/testing.go @@ -0,0 +1,19 @@ +// Copyright 2018 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 xml + +import "android/soong/android" + +var PreparerForTestWithXmlBuildComponents = android.FixtureRegisterWithContext(registerXmlBuildComponents) diff --git a/xml/xml.go b/xml/xml.go index 8810ae4d5..c28107847 100644 --- a/xml/xml.go +++ b/xml/xml.go @@ -53,10 +53,14 @@ var ( ) func init() { - android.RegisterModuleType("prebuilt_etc_xml", PrebuiltEtcXmlFactory) + registerXmlBuildComponents(android.InitRegistrationContext) pctx.HostBinToolVariable("XmlLintCmd", "xmllint") } +func registerXmlBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("prebuilt_etc_xml", PrebuiltEtcXmlFactory) +} + type prebuiltEtcXmlProperties struct { // Optional DTD that will be used to validate the xml file. Schema *string `android:"path"` diff --git a/xml/xml_test.go b/xml/xml_test.go index 138503c6d..83ae51c4a 100644 --- a/xml/xml_test.go +++ b/xml/xml_test.go @@ -15,7 +15,6 @@ package xml import ( - "io/ioutil" "os" "testing" @@ -23,62 +22,33 @@ import ( "android/soong/etc" ) -var buildDir string - -func setUp() { - var err error - buildDir, err = ioutil.TempDir("", "soong_xml_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()) + os.Exit(m.Run()) } -func testXml(t *testing.T, bp string) *android.TestContext { - fs := map[string][]byte{ +var emptyFixtureFactory = android.NewFixtureFactory(nil) + +func testXml(t *testing.T, bp string) *android.TestResult { + fs := android.MockFS{ "foo.xml": nil, "foo.dtd": nil, "bar.xml": nil, "bar.xsd": nil, "baz.xml": nil, } - config := android.TestArchConfig(buildDir, nil, bp, fs) - ctx := android.NewTestArchContext(config) - ctx.RegisterModuleType("prebuilt_etc", etc.PrebuiltEtcFactory) - ctx.RegisterModuleType("prebuilt_etc_xml", PrebuiltEtcXmlFactory) - ctx.Register() - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - android.FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - android.FailIfErrored(t, errs) - return ctx -} - -func assertEqual(t *testing.T, name, expected, actual string) { - t.Helper() - if expected != actual { - t.Errorf(name+" expected %q != got %q", expected, actual) - } + return emptyFixtureFactory.RunTest(t, + android.PrepareForTestWithArchMutator, + etc.PrepareForTestWithPrebuiltEtc, + PreparerForTestWithXmlBuildComponents, + fs.AddToFixture(), + android.FixtureWithRootAndroidBp(bp), + ) } // Minimal test func TestPrebuiltEtcXml(t *testing.T) { - ctx := testXml(t, ` + result := testXml(t, ` prebuilt_etc_xml { name: "foo.xml", src: "foo.xml", @@ -103,14 +73,14 @@ func TestPrebuiltEtcXml(t *testing.T) { {rule: "xmllint-minimal", input: "baz.xml"}, } { t.Run(tc.schemaType, func(t *testing.T) { - rule := ctx.ModuleForTests(tc.input, "android_arm64_armv8-a").Rule(tc.rule) - assertEqual(t, "input", tc.input, rule.Input.String()) + rule := result.ModuleForTests(tc.input, "android_arm64_armv8-a").Rule(tc.rule) + android.AssertStringEquals(t, "input", tc.input, rule.Input.String()) if tc.schemaType != "" { - assertEqual(t, "schema", tc.schema, rule.Args[tc.schemaType]) + android.AssertStringEquals(t, "schema", tc.schema, rule.Args[tc.schemaType]) } }) } - m := ctx.ModuleForTests("foo.xml", "android_arm64_armv8-a").Module().(*prebuiltEtcXml) - assertEqual(t, "installDir", buildDir+"/target/product/test_device/system/etc", m.InstallDirPath().String()) + m := result.ModuleForTests("foo.xml", "android_arm64_armv8-a").Module().(*prebuiltEtcXml) + android.AssertPathRelativeToTopEquals(t, "installDir", "out/soong/target/product/test_device/system/etc", m.InstallDirPath()) } |