Loading android/namespace_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -697,7 +697,7 @@ func findModuleById(ctx *TestContext, id string) (module TestingModule) { testModule, ok := candidate.(*testModule) if ok { if testModule.properties.Id == id { module = newTestingModule(testModule) module = newTestingModule(ctx.config, testModule) } } } Loading android/rule_builder_test.go +11 −13 Original line number Diff line number Diff line Loading @@ -562,46 +562,44 @@ func TestRuleBuilder_Build(t *testing.T) { AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat) wantImplicits := append([]string{"bar"}, extraImplicits...) AssertArrayString(t, "Implicits", wantImplicits, params.Implicits.Strings()) AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits) AssertStringEquals(t, "Output", wantOutput, params.Output.String()) AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output) if len(params.ImplicitOutputs) != 0 { t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings()) } AssertStringEquals(t, "Depfile", wantDepfile, params.Depfile.String()) AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile) 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, result.ModuleForTests("foo", "").Rule("rule"), outFile := "out/soong/.intermediates/foo/gen/foo" check(t, result.ModuleForTests("foo", "").Rule("rule").RelativeToTop(), "cp bar "+outFile, outFile, outFile+".d", true, nil, nil) }) t.Run("sbox", func(t *testing.T) { outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox") outDir := "out/soong/.intermediates/foo_sbox" 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", result.Config.PrebuiltOS(), "bin/sbox") sandboxPath := shared.TempDirForOutDir(buildDir) sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox") sandboxPath := shared.TempDirForOutDir("out/soong") cmd := `rm -rf ` + outDir + `/gen && ` + sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox"), check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox").RelativeToTop(), cmd, outFile, depFile, false, []string{manifest}, []string{sbox}) }) t.Run("singleton", func(t *testing.T) { outFile := filepath.Join(buildDir, "singleton/gen/baz") check(t, result.SingletonForTests("rule_builder_test").Rule("rule"), outFile := filepath.Join("out/soong/singleton/gen/baz") check(t, result.SingletonForTests("rule_builder_test").Rule("rule").RelativeToTop(), "cp bar "+outFile, outFile, outFile+".d", true, nil, nil) }) } Loading android/testing.go +105 −6 Original line number Diff line number Diff line Loading @@ -479,7 +479,7 @@ func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule { } } return newTestingModule(module) return newTestingModule(ctx.config, module) } func (ctx *TestContext) ModuleVariantsForTests(name string) []string { Loading @@ -499,7 +499,7 @@ func (ctx *TestContext) SingletonForTests(name string) TestingSingleton { n := ctx.SingletonName(s) if n == name { return TestingSingleton{ baseTestingComponent: newBaseTestingComponent(s.(testBuildProvider)), baseTestingComponent: newBaseTestingComponent(ctx.config, s.(testBuildProvider)), singleton: s.(*singletonAdaptor).Singleton, } } Loading @@ -522,19 +522,118 @@ type testBuildProvider interface { type TestingBuildParams struct { BuildParams RuleParams blueprint.RuleParams config Config } // RelativeToTop creates a new instance of this which has had any usages of the current test's // temporary and test specific build directory replaced with a path relative to the notional top. // // The parts of this structure which are changed are: // * BuildParams // * Args // * Path instances are intentionally not modified, use AssertPathRelativeToTopEquals or // AssertPathsRelativeToTopEquals instead which do something similar. // // * RuleParams // * Command // * Depfile // * Rspfile // * RspfileContent // * SymlinkOutputs // * CommandDeps // * CommandOrderOnly // // See PathRelativeToTop for more details. func (p TestingBuildParams) RelativeToTop() TestingBuildParams { // If this is not a valid params then just return it back. That will make it easy to use with the // Maybe...() methods. if p.Rule == nil { return p } if p.config.config == nil { panic("cannot call RelativeToTop() on a TestingBuildParams previously returned by RelativeToTop()") } // Take a copy of the build params and replace any args that contains test specific temporary // paths with paths relative to the top. bparams := p.BuildParams bparams.Args = normalizeStringMapRelativeToTop(p.config, bparams.Args) // Ditto for any fields in the RuleParams. rparams := p.RuleParams rparams.Command = normalizeStringRelativeToTop(p.config, rparams.Command) rparams.Depfile = normalizeStringRelativeToTop(p.config, rparams.Depfile) rparams.Rspfile = normalizeStringRelativeToTop(p.config, rparams.Rspfile) rparams.RspfileContent = normalizeStringRelativeToTop(p.config, rparams.RspfileContent) rparams.SymlinkOutputs = normalizeStringArrayRelativeToTop(p.config, rparams.SymlinkOutputs) rparams.CommandDeps = normalizeStringArrayRelativeToTop(p.config, rparams.CommandDeps) rparams.CommandOrderOnly = normalizeStringArrayRelativeToTop(p.config, rparams.CommandOrderOnly) return TestingBuildParams{ BuildParams: bparams, RuleParams: rparams, } } // baseTestingComponent provides functionality common to both TestingModule and TestingSingleton. type baseTestingComponent struct { config Config provider testBuildProvider } func newBaseTestingComponent(provider testBuildProvider) baseTestingComponent { return baseTestingComponent{provider} func newBaseTestingComponent(config Config, provider testBuildProvider) baseTestingComponent { return baseTestingComponent{config, provider} } // A function that will normalize a string containing paths, e.g. ninja command, by replacing // any references to the test specific temporary build directory that changes with each run to a // fixed path relative to a notional top directory. // // This is similar to StringPathRelativeToTop except that assumes the string is a single path // containing at most one instance of the temporary build directory at the start of the path while // this assumes that there can be any number at any position. func normalizeStringRelativeToTop(config Config, s string) string { // The buildDir usually looks something like: /tmp/testFoo2345/001 // // Replace any usage of the buildDir with out/soong, e.g. replace "/tmp/testFoo2345/001" with // "out/soong". outSoongDir := filepath.Clean(config.buildDir) re := regexp.MustCompile(`\Q` + outSoongDir + `\E\b`) s = re.ReplaceAllString(s, "out/soong") // Replace any usage of the buildDir/.. with out, e.g. replace "/tmp/testFoo2345" with // "out". This must come after the previous replacement otherwise this would replace // "/tmp/testFoo2345/001" with "out/001" instead of "out/soong". outDir := filepath.Dir(outSoongDir) re = regexp.MustCompile(`\Q` + outDir + `\E\b`) s = re.ReplaceAllString(s, "out") return s } // normalizeStringArrayRelativeToTop creates a new slice constructed by applying // normalizeStringRelativeToTop to each item in the slice. func normalizeStringArrayRelativeToTop(config Config, slice []string) []string { newSlice := make([]string, len(slice)) for i, s := range slice { newSlice[i] = normalizeStringRelativeToTop(config, s) } return newSlice } // normalizeStringMapRelativeToTop creates a new map constructed by applying // normalizeStringRelativeToTop to each value in the map. func normalizeStringMapRelativeToTop(config Config, m map[string]string) map[string]string { newMap := map[string]string{} for k, v := range m { newMap[k] = normalizeStringRelativeToTop(config, v) } return newMap } func (b baseTestingComponent) newTestingBuildParams(bparams BuildParams) TestingBuildParams { return TestingBuildParams{ config: b.config, BuildParams: bparams, RuleParams: b.provider.RuleParamsForTests()[bparams.Rule], } Loading Loading @@ -665,9 +764,9 @@ type TestingModule struct { module Module } func newTestingModule(module Module) TestingModule { func newTestingModule(config Config, module Module) TestingModule { return TestingModule{ newBaseTestingComponent(module), newBaseTestingComponent(config, module), module, } } Loading Loading
android/namespace_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -697,7 +697,7 @@ func findModuleById(ctx *TestContext, id string) (module TestingModule) { testModule, ok := candidate.(*testModule) if ok { if testModule.properties.Id == id { module = newTestingModule(testModule) module = newTestingModule(ctx.config, testModule) } } } Loading
android/rule_builder_test.go +11 −13 Original line number Diff line number Diff line Loading @@ -562,46 +562,44 @@ func TestRuleBuilder_Build(t *testing.T) { AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat) wantImplicits := append([]string{"bar"}, extraImplicits...) AssertArrayString(t, "Implicits", wantImplicits, params.Implicits.Strings()) AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits) AssertStringEquals(t, "Output", wantOutput, params.Output.String()) AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output) if len(params.ImplicitOutputs) != 0 { t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings()) } AssertStringEquals(t, "Depfile", wantDepfile, params.Depfile.String()) AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile) 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, result.ModuleForTests("foo", "").Rule("rule"), outFile := "out/soong/.intermediates/foo/gen/foo" check(t, result.ModuleForTests("foo", "").Rule("rule").RelativeToTop(), "cp bar "+outFile, outFile, outFile+".d", true, nil, nil) }) t.Run("sbox", func(t *testing.T) { outDir := filepath.Join(buildDir, ".intermediates", "foo_sbox") outDir := "out/soong/.intermediates/foo_sbox" 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", result.Config.PrebuiltOS(), "bin/sbox") sandboxPath := shared.TempDirForOutDir(buildDir) sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox") sandboxPath := shared.TempDirForOutDir("out/soong") cmd := `rm -rf ` + outDir + `/gen && ` + sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox"), check(t, result.ModuleForTests("foo_sbox", "").Output("gen/foo_sbox").RelativeToTop(), cmd, outFile, depFile, false, []string{manifest}, []string{sbox}) }) t.Run("singleton", func(t *testing.T) { outFile := filepath.Join(buildDir, "singleton/gen/baz") check(t, result.SingletonForTests("rule_builder_test").Rule("rule"), outFile := filepath.Join("out/soong/singleton/gen/baz") check(t, result.SingletonForTests("rule_builder_test").Rule("rule").RelativeToTop(), "cp bar "+outFile, outFile, outFile+".d", true, nil, nil) }) } Loading
android/testing.go +105 −6 Original line number Diff line number Diff line Loading @@ -479,7 +479,7 @@ func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule { } } return newTestingModule(module) return newTestingModule(ctx.config, module) } func (ctx *TestContext) ModuleVariantsForTests(name string) []string { Loading @@ -499,7 +499,7 @@ func (ctx *TestContext) SingletonForTests(name string) TestingSingleton { n := ctx.SingletonName(s) if n == name { return TestingSingleton{ baseTestingComponent: newBaseTestingComponent(s.(testBuildProvider)), baseTestingComponent: newBaseTestingComponent(ctx.config, s.(testBuildProvider)), singleton: s.(*singletonAdaptor).Singleton, } } Loading @@ -522,19 +522,118 @@ type testBuildProvider interface { type TestingBuildParams struct { BuildParams RuleParams blueprint.RuleParams config Config } // RelativeToTop creates a new instance of this which has had any usages of the current test's // temporary and test specific build directory replaced with a path relative to the notional top. // // The parts of this structure which are changed are: // * BuildParams // * Args // * Path instances are intentionally not modified, use AssertPathRelativeToTopEquals or // AssertPathsRelativeToTopEquals instead which do something similar. // // * RuleParams // * Command // * Depfile // * Rspfile // * RspfileContent // * SymlinkOutputs // * CommandDeps // * CommandOrderOnly // // See PathRelativeToTop for more details. func (p TestingBuildParams) RelativeToTop() TestingBuildParams { // If this is not a valid params then just return it back. That will make it easy to use with the // Maybe...() methods. if p.Rule == nil { return p } if p.config.config == nil { panic("cannot call RelativeToTop() on a TestingBuildParams previously returned by RelativeToTop()") } // Take a copy of the build params and replace any args that contains test specific temporary // paths with paths relative to the top. bparams := p.BuildParams bparams.Args = normalizeStringMapRelativeToTop(p.config, bparams.Args) // Ditto for any fields in the RuleParams. rparams := p.RuleParams rparams.Command = normalizeStringRelativeToTop(p.config, rparams.Command) rparams.Depfile = normalizeStringRelativeToTop(p.config, rparams.Depfile) rparams.Rspfile = normalizeStringRelativeToTop(p.config, rparams.Rspfile) rparams.RspfileContent = normalizeStringRelativeToTop(p.config, rparams.RspfileContent) rparams.SymlinkOutputs = normalizeStringArrayRelativeToTop(p.config, rparams.SymlinkOutputs) rparams.CommandDeps = normalizeStringArrayRelativeToTop(p.config, rparams.CommandDeps) rparams.CommandOrderOnly = normalizeStringArrayRelativeToTop(p.config, rparams.CommandOrderOnly) return TestingBuildParams{ BuildParams: bparams, RuleParams: rparams, } } // baseTestingComponent provides functionality common to both TestingModule and TestingSingleton. type baseTestingComponent struct { config Config provider testBuildProvider } func newBaseTestingComponent(provider testBuildProvider) baseTestingComponent { return baseTestingComponent{provider} func newBaseTestingComponent(config Config, provider testBuildProvider) baseTestingComponent { return baseTestingComponent{config, provider} } // A function that will normalize a string containing paths, e.g. ninja command, by replacing // any references to the test specific temporary build directory that changes with each run to a // fixed path relative to a notional top directory. // // This is similar to StringPathRelativeToTop except that assumes the string is a single path // containing at most one instance of the temporary build directory at the start of the path while // this assumes that there can be any number at any position. func normalizeStringRelativeToTop(config Config, s string) string { // The buildDir usually looks something like: /tmp/testFoo2345/001 // // Replace any usage of the buildDir with out/soong, e.g. replace "/tmp/testFoo2345/001" with // "out/soong". outSoongDir := filepath.Clean(config.buildDir) re := regexp.MustCompile(`\Q` + outSoongDir + `\E\b`) s = re.ReplaceAllString(s, "out/soong") // Replace any usage of the buildDir/.. with out, e.g. replace "/tmp/testFoo2345" with // "out". This must come after the previous replacement otherwise this would replace // "/tmp/testFoo2345/001" with "out/001" instead of "out/soong". outDir := filepath.Dir(outSoongDir) re = regexp.MustCompile(`\Q` + outDir + `\E\b`) s = re.ReplaceAllString(s, "out") return s } // normalizeStringArrayRelativeToTop creates a new slice constructed by applying // normalizeStringRelativeToTop to each item in the slice. func normalizeStringArrayRelativeToTop(config Config, slice []string) []string { newSlice := make([]string, len(slice)) for i, s := range slice { newSlice[i] = normalizeStringRelativeToTop(config, s) } return newSlice } // normalizeStringMapRelativeToTop creates a new map constructed by applying // normalizeStringRelativeToTop to each value in the map. func normalizeStringMapRelativeToTop(config Config, m map[string]string) map[string]string { newMap := map[string]string{} for k, v := range m { newMap[k] = normalizeStringRelativeToTop(config, v) } return newMap } func (b baseTestingComponent) newTestingBuildParams(bparams BuildParams) TestingBuildParams { return TestingBuildParams{ config: b.config, BuildParams: bparams, RuleParams: b.provider.RuleParamsForTests()[bparams.Rule], } Loading Loading @@ -665,9 +764,9 @@ type TestingModule struct { module Module } func newTestingModule(module Module) TestingModule { func newTestingModule(config Config, module Module) TestingModule { return TestingModule{ newBaseTestingComponent(module), newBaseTestingComponent(config, module), module, } } Loading