diff --git a/android/module_test.go b/android/module_test.go index a1bab6d01..1dcddf71b 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -15,12 +15,9 @@ package android import ( - "bytes" "path/filepath" "runtime" "testing" - - mkparser "android/soong/androidmk/parser" ) func TestSrcIsModule(t *testing.T) { @@ -475,21 +472,10 @@ func TestInstallKatiEnabled(t *testing.T) { prepareForModuleTests, PrepareForTestWithArchMutator, FixtureModifyConfig(SetKatiEnabledForTests), - FixtureRegisterWithContext(func(ctx RegistrationContext) { - ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc) - }), + PrepareForTestWithMakevars, ).RunTestWithBp(t, bp) - installs := result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting - buf := bytes.NewBuffer(append([]byte(nil), installs...)) - parser := mkparser.NewParser("makevars", buf) - - nodes, errs := parser.Parse() - if len(errs) > 0 { - t.Fatalf("error parsing install rules: %s", errs[0]) - } - - rules := parseMkRules(t, result.Config, nodes) + rules := result.InstallMakeRulesForTesting(t) module := func(name string, host bool) TestingModule { variant := "android_common" @@ -501,121 +487,78 @@ func TestInstallKatiEnabled(t *testing.T) { outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) } - ruleForOutput := func(output string) installMakeRule { + ruleForOutput := func(output string) InstallMakeRule { for _, rule := range rules { - if rule.target == output { + if rule.Target == output { return rule } } t.Fatalf("no make install rule for %s", output) - return installMakeRule{} + return InstallMakeRule{} } - installRule := func(name string) installMakeRule { + installRule := func(name string) InstallMakeRule { return ruleForOutput(filepath.Join("out/target/product/test_device/system", name)) } - symlinkRule := func(name string) installMakeRule { + symlinkRule := func(name string) InstallMakeRule { return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name)) } hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) } - hostInstallRule := func(name string) installMakeRule { + hostInstallRule := func(name string) InstallMakeRule { return ruleForOutput(filepath.Join("out/host/linux-x86", name)) } - hostSymlinkRule := func(name string) installMakeRule { + hostSymlinkRule := func(name string) InstallMakeRule { return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name)) } - assertDeps := func(rule installMakeRule, deps ...string) { + assertDeps := func(rule InstallMakeRule, deps ...string) { t.Helper() - AssertArrayString(t, "expected inputs", deps, rule.deps) + AssertArrayString(t, "expected inputs", deps, rule.Deps) } - assertOrderOnlys := func(rule installMakeRule, orderonlys ...string) { + assertOrderOnlys := func(rule InstallMakeRule, orderonlys ...string) { t.Helper() - AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.orderOnlyDeps) + AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.OrderOnlyDeps) } // Check host install rule dependencies assertDeps(hostInstallRule("foo"), hostOutputRule("foo").Output.String(), - hostInstallRule("bar").target, - hostSymlinkRule("bar").target, - hostInstallRule("baz").target, - hostSymlinkRule("baz").target, - hostInstallRule("qux").target, - hostSymlinkRule("qux").target, + hostInstallRule("bar").Target, + hostSymlinkRule("bar").Target, + hostInstallRule("baz").Target, + hostSymlinkRule("baz").Target, + hostInstallRule("qux").Target, + hostSymlinkRule("qux").Target, ) assertOrderOnlys(hostInstallRule("foo")) // Check host symlink rule dependencies. Host symlinks must use a normal dependency, not an // order-only dependency, so that the tool gets updated when the symlink is depended on. - assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").target) + assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").Target) assertOrderOnlys(hostSymlinkRule("foo")) // Check device install rule dependencies assertDeps(installRule("foo"), outputRule("foo").Output.String()) assertOrderOnlys(installRule("foo"), - installRule("bar").target, - symlinkRule("bar").target, - installRule("baz").target, - symlinkRule("baz").target, - installRule("qux").target, - symlinkRule("qux").target, + installRule("bar").Target, + symlinkRule("bar").Target, + installRule("baz").Target, + symlinkRule("baz").Target, + installRule("qux").Target, + symlinkRule("qux").Target, ) // Check device symlink rule dependencies. Device symlinks could use an order-only dependency, // but the current implementation uses a normal dependency. - assertDeps(symlinkRule("foo"), installRule("foo").target) + assertDeps(symlinkRule("foo"), installRule("foo").Target) assertOrderOnlys(symlinkRule("foo")) } -type installMakeRule struct { - target string - deps []string - orderOnlyDeps []string -} - -func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installMakeRule { - var rules []installMakeRule - for _, node := range nodes { - if mkParserRule, ok := node.(*mkparser.Rule); ok { - var rule installMakeRule - - if targets := mkParserRule.Target.Words(); len(targets) == 0 { - t.Fatalf("no targets for rule %s", mkParserRule.Dump()) - } else if len(targets) > 1 { - t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump()) - } else if !targets[0].Const() { - t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump()) - } else { - rule.target = normalizeStringRelativeToTop(config, targets[0].Value(nil)) - } - - prereqList := &rule.deps - for _, prereq := range mkParserRule.Prerequisites.Words() { - if !prereq.Const() { - t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump()) - } - - if prereq.Value(nil) == "|" { - prereqList = &rule.orderOnlyDeps - continue - } - - *prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil))) - } - - rules = append(rules, rule) - } - } - - return rules -} - type PropsTestModuleEmbedded struct { Embedded_prop *string } diff --git a/android/singleton_module_test.go b/android/singleton_module_test.go index eb5554c01..9d98478e2 100644 --- a/android/singleton_module_test.go +++ b/android/singleton_module_test.go @@ -46,8 +46,8 @@ var prepareForSingletonModuleTest = GroupFixturePreparers( PrepareForTestWithAndroidMk, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory) - ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc) }), + PrepareForTestWithMakevars, ) func TestSingletonModule(t *testing.T) { diff --git a/android/testing.go b/android/testing.go index 39864e103..a9632e96b 100644 --- a/android/testing.go +++ b/android/testing.go @@ -15,6 +15,7 @@ package android import ( + "bytes" "fmt" "path/filepath" "regexp" @@ -23,6 +24,8 @@ import ( "sync" "testing" + mkparser "android/soong/androidmk/parser" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -115,6 +118,10 @@ var PrepareForTestWithNamespace = FixtureRegisterWithContext(func(ctx Registrati ctx.PreArchMutators(RegisterNamespaceMutator) }) +var PrepareForTestWithMakevars = FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc) +}) + // Test fixture preparer that will register most java build components. // // Singletons and mutators should only be added here if they are needed for a majority of java @@ -602,6 +609,62 @@ func (ctx *TestContext) SingletonForTests(name string) TestingSingleton { "\nall singletons: %v", name, allSingletonNames)) } +type InstallMakeRule struct { + Target string + Deps []string + OrderOnlyDeps []string +} + +func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []InstallMakeRule { + var rules []InstallMakeRule + for _, node := range nodes { + if mkParserRule, ok := node.(*mkparser.Rule); ok { + var rule InstallMakeRule + + if targets := mkParserRule.Target.Words(); len(targets) == 0 { + t.Fatalf("no targets for rule %s", mkParserRule.Dump()) + } else if len(targets) > 1 { + t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump()) + } else if !targets[0].Const() { + t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump()) + } else { + rule.Target = normalizeStringRelativeToTop(config, targets[0].Value(nil)) + } + + prereqList := &rule.Deps + for _, prereq := range mkParserRule.Prerequisites.Words() { + if !prereq.Const() { + t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump()) + } + + if prereq.Value(nil) == "|" { + prereqList = &rule.OrderOnlyDeps + continue + } + + *prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil))) + } + + rules = append(rules, rule) + } + } + + return rules +} + +func (ctx *TestContext) InstallMakeRulesForTesting(t *testing.T) []InstallMakeRule { + installs := ctx.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting + buf := bytes.NewBuffer(append([]byte(nil), installs...)) + parser := mkparser.NewParser("makevars", buf) + + nodes, errs := parser.Parse() + if len(errs) > 0 { + t.Fatalf("error parsing install rules: %s", errs[0]) + } + + return parseMkRules(t, ctx.config, nodes) +} + func (ctx *TestContext) Config() Config { return ctx.config }