Merge "Move functionality to test install rules into testing.go."

This commit is contained in:
Treehugger Robot 2022-02-22 20:41:23 +00:00 committed by Gerrit Code Review
commit 489be090e7
3 changed files with 91 additions and 85 deletions

View file

@ -15,12 +15,9 @@
package android package android
import ( import (
"bytes"
"path/filepath" "path/filepath"
"runtime" "runtime"
"testing" "testing"
mkparser "android/soong/androidmk/parser"
) )
func TestSrcIsModule(t *testing.T) { func TestSrcIsModule(t *testing.T) {
@ -475,21 +472,10 @@ func TestInstallKatiEnabled(t *testing.T) {
prepareForModuleTests, prepareForModuleTests,
PrepareForTestWithArchMutator, PrepareForTestWithArchMutator,
FixtureModifyConfig(SetKatiEnabledForTests), FixtureModifyConfig(SetKatiEnabledForTests),
FixtureRegisterWithContext(func(ctx RegistrationContext) { PrepareForTestWithMakevars,
ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
}),
).RunTestWithBp(t, bp) ).RunTestWithBp(t, bp)
installs := result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting rules := result.InstallMakeRulesForTesting(t)
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)
module := func(name string, host bool) TestingModule { module := func(name string, host bool) TestingModule {
variant := "android_common" variant := "android_common"
@ -501,121 +487,78 @@ func TestInstallKatiEnabled(t *testing.T) {
outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) } 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 { for _, rule := range rules {
if rule.target == output { if rule.Target == output {
return rule return rule
} }
} }
t.Fatalf("no make install rule for %s", output) 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)) 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)) return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
} }
hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(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)) 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)) return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
} }
assertDeps := func(rule installMakeRule, deps ...string) { assertDeps := func(rule InstallMakeRule, deps ...string) {
t.Helper() 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() t.Helper()
AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.orderOnlyDeps) AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.OrderOnlyDeps)
} }
// Check host install rule dependencies // Check host install rule dependencies
assertDeps(hostInstallRule("foo"), assertDeps(hostInstallRule("foo"),
hostOutputRule("foo").Output.String(), hostOutputRule("foo").Output.String(),
hostInstallRule("bar").target, hostInstallRule("bar").Target,
hostSymlinkRule("bar").target, hostSymlinkRule("bar").Target,
hostInstallRule("baz").target, hostInstallRule("baz").Target,
hostSymlinkRule("baz").target, hostSymlinkRule("baz").Target,
hostInstallRule("qux").target, hostInstallRule("qux").Target,
hostSymlinkRule("qux").target, hostSymlinkRule("qux").Target,
) )
assertOrderOnlys(hostInstallRule("foo")) assertOrderOnlys(hostInstallRule("foo"))
// Check host symlink rule dependencies. Host symlinks must use a normal dependency, not an // 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. // 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")) assertOrderOnlys(hostSymlinkRule("foo"))
// Check device install rule dependencies // Check device install rule dependencies
assertDeps(installRule("foo"), outputRule("foo").Output.String()) assertDeps(installRule("foo"), outputRule("foo").Output.String())
assertOrderOnlys(installRule("foo"), assertOrderOnlys(installRule("foo"),
installRule("bar").target, installRule("bar").Target,
symlinkRule("bar").target, symlinkRule("bar").Target,
installRule("baz").target, installRule("baz").Target,
symlinkRule("baz").target, symlinkRule("baz").Target,
installRule("qux").target, installRule("qux").Target,
symlinkRule("qux").target, symlinkRule("qux").Target,
) )
// Check device symlink rule dependencies. Device symlinks could use an order-only dependency, // Check device symlink rule dependencies. Device symlinks could use an order-only dependency,
// but the current implementation uses a normal dependency. // but the current implementation uses a normal dependency.
assertDeps(symlinkRule("foo"), installRule("foo").target) assertDeps(symlinkRule("foo"), installRule("foo").Target)
assertOrderOnlys(symlinkRule("foo")) 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 { type PropsTestModuleEmbedded struct {
Embedded_prop *string Embedded_prop *string
} }

View file

@ -46,8 +46,8 @@ var prepareForSingletonModuleTest = GroupFixturePreparers(
PrepareForTestWithAndroidMk, PrepareForTestWithAndroidMk,
FixtureRegisterWithContext(func(ctx RegistrationContext) { FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory) ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory)
ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
}), }),
PrepareForTestWithMakevars,
) )
func TestSingletonModule(t *testing.T) { func TestSingletonModule(t *testing.T) {

View file

@ -15,6 +15,7 @@
package android package android
import ( import (
"bytes"
"fmt" "fmt"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -23,6 +24,8 @@ import (
"sync" "sync"
"testing" "testing"
mkparser "android/soong/androidmk/parser"
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
) )
@ -115,6 +118,10 @@ var PrepareForTestWithNamespace = FixtureRegisterWithContext(func(ctx Registrati
ctx.PreArchMutators(RegisterNamespaceMutator) ctx.PreArchMutators(RegisterNamespaceMutator)
}) })
var PrepareForTestWithMakevars = FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
})
// Test fixture preparer that will register most java build components. // 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 // 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)) "\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 { func (ctx *TestContext) Config() Config {
return ctx.config return ctx.config
} }