diff options
71 files changed, 1381 insertions, 1694 deletions
diff --git a/android/android_test.go b/android/android_test.go index 2a697fb85..fb82e3765 100644 --- a/android/android_test.go +++ b/android/android_test.go @@ -22,5 +22,3 @@ import ( func TestMain(m *testing.M) { os.Exit(m.Run()) } - -var emptyTestFixtureFactory = NewFixtureFactory(nil) diff --git a/android/androidmk_test.go b/android/androidmk_test.go index 230b1ec0b..8eda9b247 100644 --- a/android/androidmk_test.go +++ b/android/androidmk_test.go @@ -141,14 +141,14 @@ 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() - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( // Enable androidmk Singleton PrepareForTestWithAndroidMk, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("custom", customModuleFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) module := result.ModuleForTests("foo", "").Module().(*customModule) return result.TestContext, module diff --git a/android/apex.go b/android/apex.go index 0d5cac812..a5ff44264 100644 --- a/android/apex.go +++ b/android/apex.go @@ -140,9 +140,24 @@ type DepIsInSameApex interface { // DepIsInSameApex tests if the other module 'dep' is considered as part of the same APEX as // this module. For example, a static lib dependency usually returns true here, while a // shared lib dependency to a stub library returns false. + // + // This method must not be called directly without first ignoring dependencies whose tags + // implement ExcludeFromApexContentsTag. Calls from within the func passed to WalkPayloadDeps() + // are fine as WalkPayloadDeps() will ignore those dependencies automatically. Otherwise, use + // IsDepInSameApex instead. DepIsInSameApex(ctx BaseModuleContext, dep Module) bool } +func IsDepInSameApex(ctx BaseModuleContext, module, dep Module) bool { + depTag := ctx.OtherModuleDependencyTag(dep) + if _, ok := depTag.(ExcludeFromApexContentsTag); ok { + // The tag defines a dependency that never requires the child module to be part of the same + // apex as the parent. + return false + } + return module.(DepIsInSameApex).DepIsInSameApex(ctx, dep) +} + // ApexModule is the interface that a module type is expected to implement if the module has to be // built differently depending on whether the module is destined for an APEX or not (i.e., installed // to one of the regular partitions). @@ -260,6 +275,10 @@ type ApexProperties struct { // // Unless the tag also implements the AlwaysRequireApexVariantTag this will prevent an apex variant // from being created for the module. +// +// At the moment the sdk.sdkRequirementsMutator relies on the fact that the existing tags which +// implement this interface do not define dependencies onto members of an sdk_snapshot. If that +// changes then sdk.sdkRequirementsMutator will need fixing. type ExcludeFromApexContentsTag interface { blueprint.DependencyTag diff --git a/android/arch_test.go b/android/arch_test.go index 09cb52370..633ddaa99 100644 --- a/android/arch_test.go +++ b/android/arch_test.go @@ -358,12 +358,12 @@ func TestArchMutator(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForArchTest, // Test specific preparer OptionalFixturePreparer(tt.preparer), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) ctx := result.TestContext if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) { @@ -441,7 +441,7 @@ func TestArchMutatorNativeBridge(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForArchTest, // Test specific preparer OptionalFixturePreparer(tt.preparer), @@ -455,7 +455,7 @@ func TestArchMutatorNativeBridge(t *testing.T) { } }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) ctx := result.TestContext diff --git a/android/config.go b/android/config.go index 19706f542..0de8928a0 100644 --- a/android/config.go +++ b/android/config.go @@ -1389,7 +1389,10 @@ func (c *deviceConfig) PlatformSepolicyVersion() string { } func (c *deviceConfig) BoardSepolicyVers() string { - return String(c.config.productVariables.BoardSepolicyVers) + if ver := String(c.config.productVariables.BoardSepolicyVers); ver != "" { + return ver + } + return c.PlatformSepolicyVersion() } func (c *deviceConfig) BoardReqdMaskPolicy() []string { diff --git a/android/csuite_config_test.go b/android/csuite_config_test.go index d30ff6926..b8a176eb3 100644 --- a/android/csuite_config_test.go +++ b/android/csuite_config_test.go @@ -19,14 +19,14 @@ import ( ) func TestCSuiteConfig(t *testing.T) { - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( PrepareForTestWithArchMutator, FixtureRegisterWithContext(registerCSuiteBuildComponents), FixtureWithRootAndroidBp(` csuite_config { name: "plain"} csuite_config { name: "with_manifest", test_config: "manifest.xml" } `), - ) + ).RunTest(t) variants := result.ModuleVariantsForTests("plain") if len(variants) > 1 { diff --git a/android/defaults_test.go b/android/defaults_test.go index b33cb527c..a7542abb3 100644 --- a/android/defaults_test.go +++ b/android/defaults_test.go @@ -83,10 +83,10 @@ func TestDefaults(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForDefaultsTest, FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) foo := result.Module("foo", "").(*defaultsTestModule) @@ -114,11 +114,11 @@ func TestDefaultsAllowMissingDependencies(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForDefaultsTest, PrepareForTestWithAllowMissingDependencies, FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) missingDefaults := result.ModuleForTests("missing_defaults", "").Output("out") missingTransitiveDefaults := result.ModuleForTests("missing_transitive_defaults", "").Output("out") diff --git a/android/deptag_test.go b/android/deptag_test.go index 7f5589659..eb4fa89a6 100644 --- a/android/deptag_test.go +++ b/android/deptag_test.go @@ -80,13 +80,13 @@ func TestInstallDependencyTag(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( PrepareForTestWithArchMutator, FixtureWithRootAndroidBp(bp), FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test_module", testInstallDependencyTagModuleFactory) }), - ) + ).RunTest(t) config := result.Config diff --git a/android/fixture.go b/android/fixture.go index f213d66d4..6c9ea6b62 100644 --- a/android/fixture.go +++ b/android/fixture.go @@ -16,6 +16,7 @@ package android import ( "fmt" + "strings" "testing" ) @@ -29,8 +30,8 @@ import ( // first creating a base Fixture (which is essentially empty) and then applying FixturePreparer // instances to it to modify the environment. // -// FixtureFactory -// ============== +// FixtureFactory (deprecated) +// =========================== // These are responsible for creating fixtures. Factories are immutable and are intended to be // initialized once and reused to create multiple fixtures. Each factory has a list of fixture // preparers that prepare a fixture for running a test. Factories can also be used to create other @@ -42,7 +43,9 @@ import ( // intended to be immutable and able to prepare multiple Fixture objects simultaneously without // them sharing any data. // -// FixturePreparers are only ever invoked once per test fixture. Prior to invocation the list of +// They provide the basic capabilities for running tests too. +// +// FixturePreparers are only ever applied once per test fixture. Prior to application the list of // FixturePreparers are flattened and deduped while preserving the order they first appear in the // list. This makes it easy to reuse, group and combine FixturePreparers together. // @@ -118,14 +121,58 @@ import ( // Some files to use in tests in the java package. // // var javaMockFS = android.MockFS{ -// "api/current.txt": nil, -// "api/removed.txt": nil, +// "api/current.txt": nil, +// "api/removed.txt": nil, // ... // } // -// A package private factory for use for testing java within the java package. +// A package private preparer for use for testing java within the java package. // -// var javaFixtureFactory = NewFixtureFactory( +// var prepareForJavaTest = android.GroupFixturePreparers( +// PrepareForIntegrationTestWithJava, +// FixtureRegisterWithContext(func(ctx android.RegistrationContext) { +// ctx.RegisterModuleType("test_module", testModule) +// }), +// javaMockFS.AddToFixture(), +// ... +// } +// +// func TestJavaStuff(t *testing.T) { +// result := android.GroupFixturePreparers(t, +// prepareForJavaTest, +// android.FixtureWithRootAndroidBp(`java_library {....}`), +// android.MockFS{...}.AddToFixture(), +// ).RunTest(t) +// ... test result ... +// } +// +// package cc +// var PrepareForTestWithCC = android.GroupFixturePreparers( +// android.PrepareForArchMutator, +// android.prepareForPrebuilts, +// FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest), +// ... +// ) +// +// package apex +// +// var PrepareForApex = GroupFixturePreparers( +// ... +// ) +// +// Use modules and mutators from java, cc and apex. Any duplicate preparers (like +// android.PrepareForArchMutator) will be automatically deduped. +// +// var prepareForApexTest = android.GroupFixturePreparers( +// PrepareForJava, +// PrepareForCC, +// PrepareForApex, +// ) +// +// // FixtureFactory instances have been deprecated, this remains for informational purposes to +// // help explain some of the existing code but will be removed along with FixtureFactory. +// +// var javaFixtureFactory = android.NewFixtureFactory( // PrepareForIntegrationTestWithJava, // FixtureRegisterWithContext(func(ctx android.RegistrationContext) { // ctx.RegisterModuleType("test_module", testModule) @@ -145,7 +192,7 @@ import ( // package cc // var PrepareForTestWithCC = GroupFixturePreparers( // android.PrepareForArchMutator, -// android.prepareForPrebuilts, +// android.prepareForPrebuilts, // FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest), // ... // ) @@ -169,52 +216,10 @@ import ( // // This is configured with a set of FixturePreparer objects that are used to // initialize each Fixture instance this creates. +// +// deprecated: Use FixturePreparer instead. type FixtureFactory interface { - - // Creates a copy of this instance and adds some additional preparers. - // - // Before the preparers are used they are combined with the preparers provided when the factory - // was created, any groups of preparers are flattened, and the list is deduped so that each - // preparer is only used once. See the file documentation in android/fixture.go for more details. - Extend(preparers ...FixturePreparer) FixtureFactory - - // Create a Fixture. - Fixture(t *testing.T, preparers ...FixturePreparer) Fixture - - // ExtendWithErrorHandler creates a new FixtureFactory that will use the supplied error handler - // to check the errors (may be 0) reported by the test. - // - // The default handlers is FixtureExpectsNoErrors which will fail the go test immediately if any - // errors are reported. - ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixtureFactory - - // Run the test, checking any errors reported and returning a TestResult instance. - // - // Shorthand for Fixture(t, preparers...).RunTest() - RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult - - // Run the test with the supplied Android.bp file. - // - // Shorthand for RunTest(t, android.FixtureWithRootAndroidBp(bp)) - RunTestWithBp(t *testing.T, bp string) *TestResult - - // RunTestWithConfig is a temporary method added to help ease the migration of existing tests to - // the test fixture. - // - // In order to allow the Config object to be customized separately to the TestContext a lot of - // existing test code has `test...WithConfig` funcs that allow the Config object to be supplied - // from the test and then have the TestContext created and configured automatically. e.g. - // testCcWithConfig, testCcErrorWithConfig, testJavaWithConfig, etc. - // - // This method allows those methods to be migrated to use the test fixture pattern without - // requiring that every test that uses those methods be migrated at the same time. That allows - // those tests to benefit from correctness in the order of registration quickly. - // - // This method discards the config (along with its mock file system, product variables, - // environment, etc.) that may have been set up by FixturePreparers. - // - // deprecated - RunTestWithConfig(t *testing.T, config Config) *TestResult + FixturePreparer } // Create a new FixtureFactory that will apply the supplied preparers. @@ -223,14 +228,17 @@ type FixtureFactory interface { // the package level setUp method. It has to be a pointer to the variable as the variable will not // have been initialized at the time the factory is created. If it is nil then a test specific // temporary directory will be created instead. +// +// deprecated: The functionality provided by FixtureFactory will be merged into FixturePreparer func NewFixtureFactory(buildDirSupplier *string, preparers ...FixturePreparer) FixtureFactory { - return &fixtureFactory{ + f := &fixtureFactory{ buildDirSupplier: buildDirSupplier, - preparers: dedupAndFlattenPreparers(nil, preparers), - - // Set the default error handler. - errorHandler: FixtureExpectsNoErrors, + compositeFixturePreparer: compositeFixturePreparer{ + preparers: dedupAndFlattenPreparers(nil, preparers), + }, } + f.initBaseFixturePreparer(f) + return f } // A set of mock files to add to the mock file system. @@ -241,6 +249,7 @@ type MockFS map[string][]byte // Fails if the supplied map files with the same paths are present in both of them. func (fs MockFS) Merge(extra map[string][]byte) { for p, c := range extra { + validateFixtureMockFSPath(p) if _, ok := fs[p]; ok { panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists", p)) } @@ -248,6 +257,27 @@ func (fs MockFS) Merge(extra map[string][]byte) { } } +// Ensure that tests cannot add paths into the mock file system which would not be allowed in the +// runtime, e.g. absolute paths, paths relative to the 'out/' directory. +func validateFixtureMockFSPath(path string) { + // This uses validateSafePath rather than validatePath because the latter prevents adding files + // that include a $ but there are tests that allow files with a $ to be used, albeit only by + // globbing. + validatedPath, err := validateSafePath(path) + if err != nil { + panic(err) + } + + // Make sure that the path is canonical. + if validatedPath != path { + panic(fmt.Errorf("path %q is not a canonical path, use %q instead", path, validatedPath)) + } + + if path == "out" || strings.HasPrefix(path, "out/") { + panic(fmt.Errorf("cannot add output path %q to the mock file system", path)) + } +} + func (fs MockFS) AddToFixture() FixturePreparer { return FixtureMergeMockFs(fs) } @@ -290,6 +320,11 @@ func FixtureRegisterWithContext(registeringFunc func(ctx RegistrationContext)) F func FixtureModifyMockFS(mutator func(fs MockFS)) FixturePreparer { return newSimpleFixturePreparer(func(f *fixture) { mutator(f.mockFS) + + // Make sure that invalid paths were not added to the mock filesystem. + for p, _ := range f.mockFS { + validateFixtureMockFSPath(p) + } }) } @@ -307,6 +342,7 @@ func FixtureMergeMockFs(mockFS MockFS) FixturePreparer { // Fail if the filesystem already contains a file with that path, use FixtureOverrideFile instead. func FixtureAddFile(path string, contents []byte) FixturePreparer { return FixtureModifyMockFS(func(fs MockFS) { + validateFixtureMockFSPath(path) if _, ok := fs[path]; ok { panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists, use FixtureOverride*File instead", path)) } @@ -387,7 +423,8 @@ func FixtureModifyProductVariables(mutator func(variables FixtureProductVariable // Before preparing the fixture the list of preparers is flattened by replacing each // instance of GroupFixturePreparers with its contents. func GroupFixturePreparers(preparers ...FixturePreparer) FixturePreparer { - return &compositeFixturePreparer{dedupAndFlattenPreparers(nil, preparers)} + all := dedupAndFlattenPreparers(nil, preparers) + return newFixturePreparer(all) } // NullFixturePreparer is a preparer that does nothing. @@ -403,20 +440,57 @@ func OptionalFixturePreparer(preparer FixturePreparer) FixturePreparer { } } -type simpleFixturePreparerVisitor func(preparer *simpleFixturePreparer) - -// FixturePreparer is an opaque interface that can change a fixture. +// FixturePreparer provides the ability to create, modify and then run tests within a fixture. type FixturePreparer interface { - // visit calls the supplied visitor with each *simpleFixturePreparer instances in this preparer, - visit(simpleFixturePreparerVisitor) -} + // Return the flattened and deduped list of simpleFixturePreparer pointers. + list() []*simpleFixturePreparer + + // Creates a copy of this instance and adds some additional preparers. + // + // Before the preparers are used they are combined with the preparers provided when the factory + // was created, any groups of preparers are flattened, and the list is deduped so that each + // preparer is only used once. See the file documentation in android/fixture.go for more details. + // + // deprecated: Use GroupFixturePreparers() instead. + Extend(preparers ...FixturePreparer) FixturePreparer -type fixturePreparers []FixturePreparer + // Create a Fixture. + Fixture(t *testing.T, preparers ...FixturePreparer) Fixture -func (f fixturePreparers) visit(visitor simpleFixturePreparerVisitor) { - for _, p := range f { - p.visit(visitor) - } + // ExtendWithErrorHandler creates a new FixturePreparer that will use the supplied error handler + // to check the errors (may be 0) reported by the test. + // + // The default handlers is FixtureExpectsNoErrors which will fail the go test immediately if any + // errors are reported. + ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixturePreparer + + // Run the test, checking any errors reported and returning a TestResult instance. + // + // Shorthand for Fixture(t, preparers...).RunTest() + RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult + + // Run the test with the supplied Android.bp file. + // + // Shorthand for RunTest(t, android.FixtureWithRootAndroidBp(bp)) + RunTestWithBp(t *testing.T, bp string) *TestResult + + // RunTestWithConfig is a temporary method added to help ease the migration of existing tests to + // the test fixture. + // + // In order to allow the Config object to be customized separately to the TestContext a lot of + // existing test code has `test...WithConfig` funcs that allow the Config object to be supplied + // from the test and then have the TestContext created and configured automatically. e.g. + // testCcWithConfig, testCcErrorWithConfig, testJavaWithConfig, etc. + // + // This method allows those methods to be migrated to use the test fixture pattern without + // requiring that every test that uses those methods be migrated at the same time. That allows + // those tests to benefit from correctness in the order of registration quickly. + // + // This method discards the config (along with its mock file system, product variables, + // environment, etc.) that may have been set up by FixturePreparers. + // + // deprecated + RunTestWithConfig(t *testing.T, config Config) *TestResult } // dedupAndFlattenPreparers removes any duplicates and flattens any composite FixturePreparer @@ -429,48 +503,73 @@ func (f fixturePreparers) visit(visitor simpleFixturePreparerVisitor) { // preparers - a list of additional unflattened, undeduped preparers that will be applied after the // base preparers. // -// Returns a deduped and flattened list of the preparers minus any that exist in the base preparers. -func dedupAndFlattenPreparers(base []*simpleFixturePreparer, preparers fixturePreparers) []*simpleFixturePreparer { - var list []*simpleFixturePreparer +// Returns a deduped and flattened list of the preparers starting with the ones in base with any +// additional ones from the preparers list added afterwards. +func dedupAndFlattenPreparers(base []*simpleFixturePreparer, preparers []FixturePreparer) []*simpleFixturePreparer { + if len(preparers) == 0 { + return base + } + + list := make([]*simpleFixturePreparer, len(base)) visited := make(map[*simpleFixturePreparer]struct{}) // Mark the already flattened and deduped preparers, if any, as having been seen so that - // duplicates of these in the additional preparers will be discarded. - for _, s := range base { + // duplicates of these in the additional preparers will be discarded. Add them to the output + // list. + for i, s := range base { visited[s] = struct{}{} + list[i] = s } - preparers.visit(func(preparer *simpleFixturePreparer) { - if _, seen := visited[preparer]; !seen { - visited[preparer] = struct{}{} - list = append(list, preparer) + for _, p := range preparers { + for _, s := range p.list() { + if _, seen := visited[s]; !seen { + visited[s] = struct{}{} + list = append(list, s) + } } - }) + } + return list } // compositeFixturePreparer is a FixturePreparer created from a list of fixture preparers. type compositeFixturePreparer struct { + baseFixturePreparer + // The flattened and deduped list of simpleFixturePreparer pointers encapsulated within this + // composite preparer. preparers []*simpleFixturePreparer } -func (c *compositeFixturePreparer) visit(visitor simpleFixturePreparerVisitor) { - for _, p := range c.preparers { - p.visit(visitor) +func (c *compositeFixturePreparer) list() []*simpleFixturePreparer { + return c.preparers +} + +func newFixturePreparer(preparers []*simpleFixturePreparer) FixturePreparer { + if len(preparers) == 1 { + return preparers[0] } + p := &compositeFixturePreparer{ + preparers: preparers, + } + p.initBaseFixturePreparer(p) + return p } // simpleFixturePreparer is a FixturePreparer that applies a function to a fixture. type simpleFixturePreparer struct { + baseFixturePreparer function func(fixture *fixture) } -func (s *simpleFixturePreparer) visit(visitor simpleFixturePreparerVisitor) { - visitor(s) +func (s *simpleFixturePreparer) list() []*simpleFixturePreparer { + return []*simpleFixturePreparer{s} } func newSimpleFixturePreparer(preparer func(fixture *fixture)) FixturePreparer { - return &simpleFixturePreparer{function: preparer} + p := &simpleFixturePreparer{function: preparer} + p.initBaseFixturePreparer(p) + return p } // FixtureErrorHandler determines how to respond to errors reported by the code under test. @@ -606,82 +705,66 @@ type TestResult struct { NinjaDeps []string } -var _ FixtureFactory = (*fixtureFactory)(nil) - -type fixtureFactory struct { - buildDirSupplier *string - preparers []*simpleFixturePreparer - errorHandler FixtureErrorHandler -} - -func (f *fixtureFactory) Extend(preparers ...FixturePreparer) FixtureFactory { - // Create a new slice to avoid accidentally sharing the preparers slice from this factory with - // the extending factories. - var all []*simpleFixturePreparer - all = append(all, f.preparers...) - all = append(all, dedupAndFlattenPreparers(f.preparers, preparers)...) - // Copy the existing factory. - extendedFactory := &fixtureFactory{} - *extendedFactory = *f - // Use the extended list of preparers. - extendedFactory.preparers = all - return extendedFactory -} +func createFixture(t *testing.T, buildDir string, base []*simpleFixturePreparer, extra []FixturePreparer) Fixture { + all := dedupAndFlattenPreparers(base, extra) -func (f *fixtureFactory) Fixture(t *testing.T, preparers ...FixturePreparer) Fixture { - var buildDir string - if f.buildDirSupplier == nil { - // Create a new temporary directory for this run. It will be automatically cleaned up when the - // test finishes. - buildDir = t.TempDir() - } else { - // Retrieve the buildDir from the supplier. - buildDir = *f.buildDirSupplier - } config := TestConfig(buildDir, nil, "", nil) ctx := NewTestContext(config) fixture := &fixture{ - factory: f, - t: t, - config: config, - ctx: ctx, - mockFS: make(MockFS), - errorHandler: f.errorHandler, - } - - for _, preparer := range f.preparers { - preparer.function(fixture) + preparers: all, + t: t, + config: config, + ctx: ctx, + mockFS: make(MockFS), + // Set the default error handler. + errorHandler: FixtureExpectsNoErrors, } - for _, preparer := range dedupAndFlattenPreparers(f.preparers, preparers) { + for _, preparer := range all { preparer.function(fixture) } return fixture } -func (f *fixtureFactory) ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixtureFactory { - newFactory := &fixtureFactory{} - *newFactory = *f - newFactory.errorHandler = errorHandler - return newFactory +type baseFixturePreparer struct { + self FixturePreparer } -func (f *fixtureFactory) RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult { +func (b *baseFixturePreparer) initBaseFixturePreparer(self FixturePreparer) { + b.self = self +} + +func (b *baseFixturePreparer) Extend(preparers ...FixturePreparer) FixturePreparer { + all := dedupAndFlattenPreparers(b.self.list(), preparers) + return newFixturePreparer(all) +} + +func (b *baseFixturePreparer) Fixture(t *testing.T, preparers ...FixturePreparer) Fixture { + return createFixture(t, t.TempDir(), b.self.list(), preparers) +} + +func (b *baseFixturePreparer) ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixturePreparer { + return b.self.Extend(newSimpleFixturePreparer(func(fixture *fixture) { + fixture.errorHandler = errorHandler + })) +} + +func (b *baseFixturePreparer) RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult { t.Helper() - fixture := f.Fixture(t, preparers...) + fixture := b.self.Fixture(t, preparers...) return fixture.RunTest() } -func (f *fixtureFactory) RunTestWithBp(t *testing.T, bp string) *TestResult { +func (b *baseFixturePreparer) RunTestWithBp(t *testing.T, bp string) *TestResult { t.Helper() - return f.RunTest(t, FixtureWithRootAndroidBp(bp)) + return b.RunTest(t, FixtureWithRootAndroidBp(bp)) } -func (f *fixtureFactory) RunTestWithConfig(t *testing.T, config Config) *TestResult { +func (b *baseFixturePreparer) RunTestWithConfig(t *testing.T, config Config) *TestResult { t.Helper() // Create the fixture as normal. - fixture := f.Fixture(t).(*fixture) + fixture := b.self.Fixture(t).(*fixture) // Discard the mock filesystem as otherwise that will override the one in the config. fixture.mockFS = nil @@ -700,9 +783,49 @@ func (f *fixtureFactory) RunTestWithConfig(t *testing.T, config Config) *TestRes return fixture.RunTest() } +var _ FixtureFactory = (*fixtureFactory)(nil) + +type fixtureFactory struct { + compositeFixturePreparer + + buildDirSupplier *string +} + +// Override to preserve the buildDirSupplier. +func (f *fixtureFactory) Extend(preparers ...FixturePreparer) FixturePreparer { + // If there is no buildDirSupplier then just use the default implementation. + if f.buildDirSupplier == nil { + return f.baseFixturePreparer.Extend(preparers...) + } + + all := dedupAndFlattenPreparers(f.preparers, preparers) + + // Create a new factory which uses the same buildDirSupplier as the previous one. + extendedFactory := &fixtureFactory{ + buildDirSupplier: f.buildDirSupplier, + compositeFixturePreparer: compositeFixturePreparer{ + preparers: all, + }, + } + extendedFactory.initBaseFixturePreparer(extendedFactory) + return extendedFactory +} + +func (f *fixtureFactory) Fixture(t *testing.T, preparers ...FixturePreparer) Fixture { + // If there is no buildDirSupplier then just use the default implementation. + if f.buildDirSupplier == nil { + return f.baseFixturePreparer.Fixture(t, preparers...) + } + + // Retrieve the buildDir from the supplier. + buildDir := *f.buildDirSupplier + + return createFixture(t, buildDir, f.preparers, preparers) +} + type fixture struct { - // The factory used to create this fixture. - factory *fixtureFactory + // The preparers used to create this fixture. + preparers []*simpleFixturePreparer // The gotest state of the go test within which this was created. t *testing.T @@ -810,6 +933,21 @@ func (r *TestResult) NormalizePathsForTesting(paths Paths) []string { return result } +// Preparer will return a FixturePreparer encapsulating all the preparers used to create the fixture +// that produced this result. +// +// e.g. assuming that this result was created by running: +// factory.Extend(preparer1, preparer2).RunTest(t, preparer3, preparer4) +// +// Then this method will be equivalent to running: +// GroupFixturePreparers(preparer1, preparer2, preparer3, preparer4) +// +// This is intended for use by tests whose output is Android.bp files to verify that those files +// are valid, e.g. tests of the snapshots produced by the sdk module type. +func (r *TestResult) Preparer() FixturePreparer { + return newFixturePreparer(r.fixture.preparers) +} + // Module returns the module with the specific name and of the specified variant. func (r *TestResult) Module(name string, variant string) Module { return r.ModuleForTests(name, variant).Module() diff --git a/android/fixture_test.go b/android/fixture_test.go index 0042e5b16..681a03427 100644 --- a/android/fixture_test.go +++ b/android/fixture_test.go @@ -14,7 +14,9 @@ package android -import "testing" +import ( + "testing" +) // Make sure that FixturePreparer instances are only called once per fixture and in the order in // which they were added. @@ -37,13 +39,47 @@ func TestFixtureDedup(t *testing.T) { preparer2Then1 := GroupFixturePreparers(preparer2, preparer1) - buildDir := "build" - factory := NewFixtureFactory(&buildDir, preparer1, preparer2, preparer1, preparer1Then2) + group := GroupFixturePreparers(preparer1, preparer2, preparer1, preparer1Then2) - extension := factory.Extend(preparer4, preparer2) + extension := group.Extend(preparer4, preparer2) extension.Fixture(t, preparer1, preparer2, preparer2Then1, preparer3) AssertDeepEquals(t, "preparers called in wrong order", []string{"preparer1", "preparer2", "preparer4", "preparer3"}, list) } + +func TestFixtureValidateMockFS(t *testing.T) { + buildDir := "<unused>" + factory := NewFixtureFactory(&buildDir) + + t.Run("absolute path", func(t *testing.T) { + AssertPanicMessageContains(t, "source path validation failed", "Path is outside directory: /abs/path/Android.bp", func() { + factory.Fixture(t, FixtureAddFile("/abs/path/Android.bp", nil)) + }) + }) + t.Run("not canonical", func(t *testing.T) { + AssertPanicMessageContains(t, "source path validation failed", `path "path/with/../in/it/Android.bp" is not a canonical path, use "path/in/it/Android.bp" instead`, func() { + factory.Fixture(t, FixtureAddFile("path/with/../in/it/Android.bp", nil)) + }) + }) + t.Run("FixtureAddFile", func(t *testing.T) { + AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { + factory.Fixture(t, FixtureAddFile("out/Android.bp", nil)) + }) + }) + t.Run("FixtureMergeMockFs", func(t *testing.T) { + AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { + factory.Fixture(t, FixtureMergeMockFs(MockFS{ + "out/Android.bp": nil, + })) + }) + }) + t.Run("FixtureModifyMockFS", func(t *testing.T) { + AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { + factory.Fixture(t, FixtureModifyMockFS(func(fs MockFS) { + fs["out/Android.bp"] = nil + })) + }) + }) +} diff --git a/android/license_kind_test.go b/android/license_kind_test.go index 83e83cef8..1f09568db 100644 --- a/android/license_kind_test.go +++ b/android/license_kind_test.go @@ -97,13 +97,14 @@ var licenseKindTests = []struct { func TestLicenseKind(t *testing.T) { for _, test := range licenseKindTests { t.Run(test.name, func(t *testing.T) { - licenseTestFixtureFactory. - Extend( - FixtureRegisterWithContext(func(ctx RegistrationContext) { - ctx.RegisterModuleType("mock_license", newMockLicenseModule) - }), - test.fs.AddToFixture(), - ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)). + GroupFixturePreparers( + prepareForLicenseTest, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("mock_license", newMockLicenseModule) + }), + test.fs.AddToFixture(), + ). + ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)). RunTest(t) }) } diff --git a/android/license_test.go b/android/license_test.go index a564827e6..2b09a4f69 100644 --- a/android/license_test.go +++ b/android/license_test.go @@ -5,7 +5,7 @@ import ( ) // Common test set up for license tests. -var licenseTestFixtureFactory = emptyTestFixtureFactory.Extend( +var prepareForLicenseTest = GroupFixturePreparers( // General preparers in alphabetical order. PrepareForTestWithDefaults, prepareForTestWithLicenses, @@ -179,7 +179,8 @@ func TestLicense(t *testing.T) { for _, test := range licenseTests { t.Run(test.name, func(t *testing.T) { // Customize the common license text fixture factory. - licenseTestFixtureFactory.Extend( + GroupFixturePreparers( + prepareForLicenseTest, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("rule", newMockRuleModule) }), diff --git a/android/licenses_test.go b/android/licenses_test.go index a581932bd..913dc8842 100644 --- a/android/licenses_test.go +++ b/android/licenses_test.go @@ -470,7 +470,8 @@ func TestLicenses(t *testing.T) { for _, test := range licensesTests { t.Run(test.name, func(t *testing.T) { // Customize the common license text fixture factory. - result := licenseTestFixtureFactory.Extend( + result := GroupFixturePreparers( + prepareForLicenseTest, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule) ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule) diff --git a/android/module_test.go b/android/module_test.go index 99bf30afc..9ac929179 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -179,11 +179,9 @@ func TestErrorDependsOnDisabledModule(t *testing.T) { } ` - emptyTestFixtureFactory. + prepareForModuleTests. ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": depends on disabled module "bar"`)). - RunTest(t, - prepareForModuleTests, - FixtureWithRootAndroidBp(bp)) + RunTestWithBp(t, bp) } func TestValidateCorrectBuildParams(t *testing.T) { @@ -268,9 +266,7 @@ func TestDistErrorChecking(t *testing.T) { "\\QAndroid.bp:18:17: module \"foo\": dists[1].suffix: Suffix may not contain a '/' character.\\E", } - emptyTestFixtureFactory. + prepareForModuleTests. ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)). - RunTest(t, - prepareForModuleTests, - FixtureWithRootAndroidBp(bp)) + RunTestWithBp(t, bp) } diff --git a/android/mutator_test.go b/android/mutator_test.go index 46d26d1be..21eebd2c8 100644 --- a/android/mutator_test.go +++ b/android/mutator_test.go @@ -65,7 +65,7 @@ func TestMutatorAddMissingDependencies(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( PrepareForTestWithAllowMissingDependencies, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", mutatorTestModuleFactory) @@ -74,7 +74,7 @@ func TestMutatorAddMissingDependencies(t *testing.T) { }) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) foo := result.ModuleForTests("foo", "").Module().(*mutatorTestModule) @@ -90,7 +90,7 @@ func TestModuleString(t *testing.T) { var moduleStrings []string - emptyTestFixtureFactory.RunTest(t, + GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.PreArchMutators(func(ctx RegisterMutatorsContext) { @@ -128,7 +128,7 @@ func TestModuleString(t *testing.T) { ctx.RegisterModuleType("test", mutatorTestModuleFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) want := []string{ // Initial name. @@ -187,7 +187,7 @@ func TestFinalDepsPhase(t *testing.T) { finalGot := map[string]int{} - emptyTestFixtureFactory.RunTest(t, + GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { dep1Tag := struct { blueprint.BaseDependencyTag @@ -224,7 +224,7 @@ func TestFinalDepsPhase(t *testing.T) { ctx.RegisterModuleType("test", mutatorTestModuleFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) finalWant := map[string]int{ "common_dep_1{variant:a}": 1, @@ -249,7 +249,7 @@ func TestNoCreateVariationsInFinalDeps(t *testing.T) { } } - emptyTestFixtureFactory.RunTest(t, + GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) { @@ -265,5 +265,5 @@ func TestNoCreateVariationsInFinalDeps(t *testing.T) { ctx.RegisterModuleType("test", mutatorTestModuleFactory) }), FixtureWithRootAndroidBp(`test {name: "foo"}`), - ) + ).RunTest(t) } diff --git a/android/namespace_test.go b/android/namespace_test.go index 1caf5a87f..08e221a65 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -633,21 +633,21 @@ func mockFiles(bps map[string]string) (files map[string][]byte) { } func setupTestFromFiles(t *testing.T, bps MockFS) (ctx *TestContext, errs []error) { - result := emptyTestFixtureFactory. + result := GroupFixturePreparers( + 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(), + ). // 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(), - ) + RunTest(t) return result.TestContext, result.Errs } @@ -697,7 +697,7 @@ func findModuleById(ctx *TestContext, id string) (module TestingModule) { testModule, ok := candidate.(*testModule) if ok { if testModule.properties.Id == id { - module = TestingModule{testModule} + module = newTestingModule(ctx.config, testModule) } } } diff --git a/android/neverallow_test.go b/android/neverallow_test.go index 5ac97e775..b8ef0f5f2 100644 --- a/android/neverallow_test.go +++ b/android/neverallow_test.go @@ -299,18 +299,17 @@ var prepareForNeverAllowTest = GroupFixturePreparers( func TestNeverallow(t *testing.T) { for _, test := range neverallowTests { t.Run(test.name, func(t *testing.T) { - emptyTestFixtureFactory. - ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)). - RunTest(t, - prepareForNeverAllowTest, - FixtureModifyConfig(func(config Config) { - // If the test has its own rules then use them instead of the default ones. - if test.rules != nil { - SetTestNeverallowRules(config, test.rules) - } - }), - test.fs.AddToFixture(), - ) + GroupFixturePreparers( + prepareForNeverAllowTest, + FixtureModifyConfig(func(config Config) { + // If the test has its own rules then use them instead of the default ones. + if test.rules != nil { + SetTestNeverallowRules(config, test.rules) + } + }), + test.fs.AddToFixture(), + ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)). + RunTest(t) }) } } diff --git a/android/ninja_deps_test.go b/android/ninja_deps_test.go index 7e5864d5b..947c25726 100644 --- a/android/ninja_deps_test.go +++ b/android/ninja_deps_test.go @@ -57,13 +57,13 @@ func TestNinjaDeps(t *testing.T) { "test_ninja_deps/exists": nil, } - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterSingletonType("test_ninja_deps_singleton", testNinjaDepsSingletonFactory) ctx.RegisterSingletonType("ninja_deps_singleton", ninjaDepsSingletonFactory) }), fs.AddToFixture(), - ) + ).RunTest(t) // Verify that the ninja file has a dependency on the test_ninja_deps directory. if g, w := result.NinjaDeps, "test_ninja_deps"; !InList(w, g) { diff --git a/android/package_test.go b/android/package_test.go index d5b4db4a8..3bd30cc93 100644 --- a/android/package_test.go +++ b/android/package_test.go @@ -61,13 +61,13 @@ var packageTests = []struct { func TestPackage(t *testing.T) { for _, test := range packageTests { t.Run(test.name, func(t *testing.T) { - emptyTestFixtureFactory. + GroupFixturePreparers( + PrepareForTestWithArchMutator, + PrepareForTestWithPackageModule, + test.fs.AddToFixture(), + ). ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)). - RunTest(t, - PrepareForTestWithArchMutator, - PrepareForTestWithPackageModule, - test.fs.AddToFixture(), - ) + RunTest(t) }) } } diff --git a/android/packaging.go b/android/packaging.go index 9b901ce28..72c0c1777 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -59,7 +59,8 @@ type PackageModule interface { packagingBase() *PackagingBase // AddDeps adds dependencies to the `deps` modules. This should be called in DepsMutator. - // When adding the dependencies, depTag is used as the tag. + // When adding the dependencies, depTag is used as the tag. If `deps` modules are meant to + // be copied to a zip in CopyDepsToZip, `depTag` should implement PackagingItem marker interface. AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) // CopyDepsToZip zips the built artifacts of the dependencies into the given zip file and @@ -167,6 +168,24 @@ func (p *PackagingBase) getSupportedTargets(ctx BaseModuleContext) []Target { return ret } +// PackagingItem is a marker interface for dependency tags. +// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip(). +type PackagingItem interface { + // IsPackagingItem returns true if the dep is to be packaged + IsPackagingItem() bool +} + +// DepTag provides default implementation of PackagingItem interface. +// PackagingBase-derived modules can define their own dependency tag by embedding this, which +// can be passed to AddDeps() or AddDependencies(). +type PackagingItemAlwaysDepTag struct { +} + +// IsPackagingItem returns true if the dep is to be packaged +func (PackagingItemAlwaysDepTag) IsPackagingItem() bool { + return true +} + // See PackageModule.AddDeps func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) { for _, t := range p.getSupportedTargets(ctx) { @@ -182,16 +201,15 @@ func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.Dep // See PackageModule.CopyDepsToZip func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) { m := make(map[string]PackagingSpec) - ctx.WalkDeps(func(child Module, parent Module) bool { - if !IsInstallDepNeeded(ctx.OtherModuleDependencyTag(child)) { - return false + ctx.VisitDirectDeps(func(child Module) { + if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() { + return } - for _, ps := range child.PackagingSpecs() { + for _, ps := range child.TransitivePackagingSpecs() { if _, ok := m[ps.relPathInPackage]; !ok { m[ps.relPathInPackage] = ps } } - return true }) builder := NewRuleBuilder(pctx, ctx) diff --git a/android/packaging_test.go b/android/packaging_test.go index eb7f26fb8..f91dc5dc6 100644 --- a/android/packaging_test.go +++ b/android/packaging_test.go @@ -56,7 +56,9 @@ func (m *componentTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { type packageTestModule struct { ModuleBase PackagingBase - + properties struct { + Install_deps []string `android:` + } entries []string } @@ -64,6 +66,7 @@ func packageMultiTargetTestModuleFactory() Module { module := &packageTestModule{} InitPackageModule(module) InitAndroidMultiTargetsArchModule(module, DeviceSupported, MultilibCommon) + module.AddProperties(&module.properties) return module } @@ -71,11 +74,18 @@ func packageTestModuleFactory() Module { module := &packageTestModule{} InitPackageModule(module) InitAndroidArchModule(module, DeviceSupported, MultilibBoth) + module.AddProperties(&module.properties) return module } +type packagingDepTag struct { + blueprint.BaseDependencyTag + PackagingItemAlwaysDepTag +} + func (m *packageTestModule) DepsMutator(ctx BottomUpMutatorContext) { - m.AddDeps(ctx, installDepTag{}) + m.AddDeps(ctx, packagingDepTag{}) + ctx.AddDependency(ctx.Module(), installDepTag{}, m.properties.Install_deps...) } func (m *packageTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { @@ -96,14 +106,14 @@ func runPackagingTest(t *testing.T, multitarget bool, bp string, expected []stri moduleFactory = packageTestModuleFactory } - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( PrepareForTestWithArchMutator, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("component", componentTestModuleFactory) ctx.RegisterModuleType("package_module", moduleFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) p := result.Module("package", archVariant).(*packageTestModule) actual := p.entries @@ -337,4 +347,21 @@ func TestPackagingBaseSingleTarget(t *testing.T) { }, } `, []string{"lib64/foo", "lib64/bar"}) + + runPackagingTest(t, multiTarget, + ` + component { + name: "foo", + } + + component { + name: "bar", + } + + package_module { + name: "package", + deps: ["foo"], + install_deps: ["bar"], + } + `, []string{"lib64/foo"}) } diff --git a/android/path_properties_test.go b/android/path_properties_test.go index 8726ea77f..568f8682b 100644 --- a/android/path_properties_test.go +++ b/android/path_properties_test.go @@ -157,14 +157,14 @@ func TestPathDepsMutator(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( PrepareForTestWithArchMutator, PrepareForTestWithFilegroup, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", pathDepsMutatorTestModuleFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) m := result.Module("foo", "android_arm64_armv8-a").(*pathDepsMutatorTestModule) diff --git a/android/paths_test.go b/android/paths_test.go index c5fc10ebb..465ea3b55 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -1005,14 +1005,14 @@ func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) { "foo/src_special/$": nil, } - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory) ctx.RegisterModuleType("filegroup", FileGroupFactory) }), mockFS.AddToFixture(), - ) + ).RunTest(t) m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) @@ -1203,13 +1203,13 @@ func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( PrepareForTestWithAllowMissingDependencies, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) foo := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 32af5df4b..ced37fe64 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -284,7 +284,7 @@ func TestPrebuilts(t *testing.T) { t.Errorf("windows is assumed to be disabled by default") } - result := emptyTestFixtureFactory.Extend( + result := GroupFixturePreparers( PrepareForTestWithArchMutator, PrepareForTestWithPrebuilts, PrepareForTestWithOverrides, diff --git a/android/register.go b/android/register.go index c9e66e966..900edfa51 100644 --- a/android/register.go +++ b/android/register.go @@ -263,8 +263,9 @@ type RegistrationContext interface { // ctx := android.NewTestContext(config) // RegisterBuildComponents(ctx) var InitRegistrationContext RegistrationContext = &initRegistrationContext{ - moduleTypes: make(map[string]ModuleFactory), - singletonTypes: make(map[string]SingletonFactory), + moduleTypes: make(map[string]ModuleFactory), + singletonTypes: make(map[string]SingletonFactory), + preSingletonTypes: make(map[string]SingletonFactory), } // Make sure the TestContext implements RegistrationContext. diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go index 3415aed1f..9cd60a2a9 100644 --- a/android/rule_builder_test.go +++ b/android/rule_builder_test.go @@ -542,11 +542,11 @@ func TestRuleBuilder_Build(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForRuleBuilderTest, FixtureWithRootAndroidBp(bp), fs.AddToFixture(), - ) + ).RunTest(t) check := func(t *testing.T, params TestingBuildParams, wantCommand, wantOutput, wantDepfile string, wantRestat bool, extraImplicits, extraCmdDeps []string) { t.Helper() @@ -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) }) } @@ -651,10 +649,10 @@ func TestRuleBuilderHashInputs(t *testing.T) { }, } - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForRuleBuilderTest, FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) for _, test := range testcases { t.Run(test.name, func(t *testing.T) { diff --git a/android/singleton_module_test.go b/android/singleton_module_test.go index 41dd4bb48..eb5554c01 100644 --- a/android/singleton_module_test.go +++ b/android/singleton_module_test.go @@ -56,11 +56,10 @@ func TestSingletonModule(t *testing.T) { name: "test_singleton_module", } ` - result := emptyTestFixtureFactory. - RunTest(t, - prepareForSingletonModuleTest, - FixtureWithRootAndroidBp(bp), - ) + result := GroupFixturePreparers( + prepareForSingletonModuleTest, + FixtureWithRootAndroidBp(bp), + ).RunTest(t) ops := result.ModuleForTests("test_singleton_module", "").Module().(*testSingletonModule).ops wantOps := []string{"GenerateAndroidBuildActions", "GenerateSingletonBuildActions", "MakeVars"} @@ -78,19 +77,16 @@ func TestDuplicateSingletonModule(t *testing.T) { } ` - emptyTestFixtureFactory. + prepareForSingletonModuleTest. ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{ `\QDuplicate SingletonModule "test_singleton_module", previously used in\E`, - })).RunTest(t, - prepareForSingletonModuleTest, - FixtureWithRootAndroidBp(bp), - ) + })).RunTestWithBp(t, bp) } func TestUnusedSingletonModule(t *testing.T) { - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( prepareForSingletonModuleTest, - ) + ).RunTest(t) singleton := result.SingletonForTests("test_singleton_module").Singleton() sm := singleton.(*singletonModuleSingletonAdaptor).sm @@ -113,17 +109,16 @@ func TestVariantSingletonModule(t *testing.T) { } ` - emptyTestFixtureFactory. + GroupFixturePreparers( + prepareForSingletonModuleTest, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { + ctx.BottomUp("test_singleton_module_mutator", testVariantSingletonModuleMutator) + }) + }), + ). ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{ `\QGenerateAndroidBuildActions already called for variant\E`, })). - RunTest(t, - prepareForSingletonModuleTest, - FixtureRegisterWithContext(func(ctx RegistrationContext) { - ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { - ctx.BottomUp("test_singleton_module_mutator", testVariantSingletonModuleMutator) - }) - }), - FixtureWithRootAndroidBp(bp), - ) + RunTestWithBp(t, bp) } diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go index a72b160c0..8f252d944 100644 --- a/android/soong_config_modules_test.go +++ b/android/soong_config_modules_test.go @@ -278,7 +278,7 @@ func TestSoongConfigModule(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( tc.preparer, PrepareForTestWithDefaults, FixtureRegisterWithContext(func(ctx RegistrationContext) { @@ -291,7 +291,7 @@ func TestSoongConfigModule(t *testing.T) { }), fs.AddToFixture(), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) foo := result.ModuleForTests("foo", "").Module().(*soongConfigTestModule) AssertDeepEquals(t, "foo cflags", tc.fooExpectedFlags, foo.props.Cflags) diff --git a/android/test_asserts.go b/android/test_asserts.go index 4b5e9343e..bfb88ab17 100644 --- a/android/test_asserts.go +++ b/android/test_asserts.go @@ -15,6 +15,7 @@ package android import ( + "fmt" "reflect" "strings" "testing" @@ -162,19 +163,24 @@ func AssertDeepEquals(t *testing.T, message string, expected interface{}, actual } } -// AssertPanic checks that the supplied function panics as expected. -func AssertPanic(t *testing.T, message string, funcThatShouldPanic func()) { +// AssertPanicMessageContains checks that the supplied function panics as expected and the message +// obtained by formatting the recovered value as a string contains the expected contents. +func AssertPanicMessageContains(t *testing.T, message, expectedMessageContents string, funcThatShouldPanic func()) { t.Helper() panicked := false + var recovered interface{} func() { defer func() { - if x := recover(); x != nil { + if recovered = recover(); recovered != nil { panicked = true } }() funcThatShouldPanic() }() if !panicked { - t.Error(message) + t.Errorf("%s: did not panic", message) } + + panicMessage := fmt.Sprintf("%s", recovered) + AssertStringDoesContain(t, fmt.Sprintf("%s: panic message", message), panicMessage, expectedMessageContents) } diff --git a/android/testing.go b/android/testing.go index af360fac9..f17de31ed 100644 --- a/android/testing.go +++ b/android/testing.go @@ -479,7 +479,7 @@ func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule { } } - return TestingModule{module} + return newTestingModule(ctx.config, module) } func (ctx *TestContext) ModuleVariantsForTests(name string) []string { @@ -499,8 +499,8 @@ func (ctx *TestContext) SingletonForTests(name string) TestingSingleton { n := ctx.SingletonName(s) if n == name { return TestingSingleton{ - singleton: s.(*singletonAdaptor).Singleton, - provider: s.(testBuildProvider), + baseTestingComponent: newBaseTestingComponent(ctx.config, s.(testBuildProvider)), + singleton: s.(*singletonAdaptor).Singleton, } } allSingletonNames = append(allSingletonNames, n) @@ -522,62 +522,170 @@ type testBuildProvider interface { type TestingBuildParams struct { BuildParams RuleParams blueprint.RuleParams + + config Config } -func newTestingBuildParams(provider testBuildProvider, bparams BuildParams) TestingBuildParams { +// 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: provider.RuleParamsForTests()[bparams.Rule], + RuleParams: rparams, + } +} + +// baseTestingComponent provides functionality common to both TestingModule and TestingSingleton. +type baseTestingComponent struct { + config Config + provider testBuildProvider +} + +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 } -func maybeBuildParamsFromRule(provider testBuildProvider, rule string) (TestingBuildParams, []string) { +// 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], + } +} + +func (b baseTestingComponent) maybeBuildParamsFromRule(rule string) (TestingBuildParams, []string) { var searchedRules []string - for _, p := range provider.BuildParamsForTests() { + for _, p := range b.provider.BuildParamsForTests() { searchedRules = append(searchedRules, p.Rule.String()) if strings.Contains(p.Rule.String(), rule) { - return newTestingBuildParams(provider, p), searchedRules + return b.newTestingBuildParams(p), searchedRules } } return TestingBuildParams{}, searchedRules } -func buildParamsFromRule(provider testBuildProvider, rule string) TestingBuildParams { - p, searchRules := maybeBuildParamsFromRule(provider, rule) +func (b baseTestingComponent) buildParamsFromRule(rule string) TestingBuildParams { + p, searchRules := b.maybeBuildParamsFromRule(rule) if p.Rule == nil { panic(fmt.Errorf("couldn't find rule %q.\nall rules: %v", rule, searchRules)) } return p } -func maybeBuildParamsFromDescription(provider testBuildProvider, desc string) TestingBuildParams { - for _, p := range provider.BuildParamsForTests() { +func (b baseTestingComponent) maybeBuildParamsFromDescription(desc string) TestingBuildParams { + for _, p := range b.provider.BuildParamsForTests() { if strings.Contains(p.Description, desc) { - return newTestingBuildParams(provider, p) + return b.newTestingBuildParams(p) } } return TestingBuildParams{} } -func buildParamsFromDescription(provider testBuildProvider, desc string) TestingBuildParams { - p := maybeBuildParamsFromDescription(provider, desc) +func (b baseTestingComponent) buildParamsFromDescription(desc string) TestingBuildParams { + p := b.maybeBuildParamsFromDescription(desc) if p.Rule == nil { panic(fmt.Errorf("couldn't find description %q", desc)) } return p } -func maybeBuildParamsFromOutput(provider testBuildProvider, file string) (TestingBuildParams, []string) { +func (b baseTestingComponent) maybeBuildParamsFromOutput(file string) (TestingBuildParams, []string) { var searchedOutputs []string - for _, p := range provider.BuildParamsForTests() { + for _, p := range b.provider.BuildParamsForTests() { outputs := append(WritablePaths(nil), p.Outputs...) outputs = append(outputs, p.ImplicitOutputs...) if p.Output != nil { outputs = append(outputs, p.Output) } for _, f := range outputs { - if f.String() == file || f.Rel() == file { - return newTestingBuildParams(provider, p), nil + if f.String() == file || f.Rel() == file || PathRelativeToTop(f) == file { + return b.newTestingBuildParams(p), nil } searchedOutputs = append(searchedOutputs, f.Rel()) } @@ -585,18 +693,18 @@ func maybeBuildParamsFromOutput(provider testBuildProvider, file string) (Testin return TestingBuildParams{}, searchedOutputs } -func buildParamsFromOutput(provider testBuildProvider, file string) TestingBuildParams { - p, searchedOutputs := maybeBuildParamsFromOutput(provider, file) +func (b baseTestingComponent) buildParamsFromOutput(file string) TestingBuildParams { + p, searchedOutputs := b.maybeBuildParamsFromOutput(file) if p.Rule == nil { - panic(fmt.Errorf("couldn't find output %q.\nall outputs: %v", - file, searchedOutputs)) + panic(fmt.Errorf("couldn't find output %q.\nall outputs:\n %s\n", + file, strings.Join(searchedOutputs, "\n "))) } return p } -func allOutputs(provider testBuildProvider) []string { +func (b baseTestingComponent) allOutputs() []string { var outputFullPaths []string - for _, p := range provider.BuildParamsForTests() { + for _, p := range b.provider.BuildParamsForTests() { outputs := append(WritablePaths(nil), p.Outputs...) outputs = append(outputs, p.ImplicitOutputs...) if p.Output != nil { @@ -607,111 +715,83 @@ func allOutputs(provider testBuildProvider) []string { return outputFullPaths } -// TestingModule is wrapper around an android.Module that provides methods to find information about individual -// ctx.Build parameters for verification in tests. -type TestingModule struct { - module Module -} - -// Module returns the Module wrapped by the TestingModule. -func (m TestingModule) Module() Module { - return m.module -} - // MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Returns an empty // BuildParams if no rule is found. -func (m TestingModule) MaybeRule(rule string) TestingBuildParams { - r, _ := maybeBuildParamsFromRule(m.module, rule) +func (b baseTestingComponent) MaybeRule(rule string) TestingBuildParams { + r, _ := b.maybeBuildParamsFromRule(rule) return r } // Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Panics if no rule is found. -func (m TestingModule) Rule(rule string) TestingBuildParams { - return buildParamsFromRule(m.module, rule) +func (b baseTestingComponent) Rule(rule string) TestingBuildParams { + return b.buildParamsFromRule(rule) } // MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string. Returns an empty // BuildParams if no rule is found. -func (m TestingModule) MaybeDescription(desc string) TestingBuildParams { - return maybeBuildParamsFromDescription(m.module, desc) +func (b baseTestingComponent) MaybeDescription(desc string) TestingBuildParams { + return b.maybeBuildParamsFromDescription(desc) } // Description finds a call to ctx.Build with BuildParams.Description set to a the given string. Panics if no rule is // found. -func (m TestingModule) Description(desc string) TestingBuildParams { - return buildParamsFromDescription(m.module, desc) +func (b baseTestingComponent) Description(desc string) TestingBuildParams { + return b.buildParamsFromDescription(desc) } // MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel() // value matches the provided string. Returns an empty BuildParams if no rule is found. -func (m TestingModule) MaybeOutput(file string) TestingBuildParams { - p, _ := maybeBuildParamsFromOutput(m.module, file) +func (b baseTestingComponent) MaybeOutput(file string) TestingBuildParams { + p, _ := b.maybeBuildParamsFromOutput(file) return p } // Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel() // value matches the provided string. Panics if no rule is found. -func (m TestingModule) Output(file string) TestingBuildParams { - return buildParamsFromOutput(m.module, file) +func (b baseTestingComponent) Output(file string) TestingBuildParams { + return b.buildParamsFromOutput(file) } // AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms. -func (m TestingModule) AllOutputs() []string { - return allOutputs(m.module) +func (b baseTestingComponent) AllOutputs() []string { + return b.allOutputs() } -// TestingSingleton is wrapper around an android.Singleton that provides methods to find information about individual +// TestingModule is wrapper around an android.Module that provides methods to find information about individual // ctx.Build parameters for verification in tests. -type TestingSingleton struct { - singleton Singleton - provider testBuildProvider -} - -// Singleton returns the Singleton wrapped by the TestingSingleton. -func (s TestingSingleton) Singleton() Singleton { - return s.singleton -} - -// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Returns an empty -// BuildParams if no rule is found. -func (s TestingSingleton) MaybeRule(rule string) TestingBuildParams { - r, _ := maybeBuildParamsFromRule(s.provider, rule) - return r -} - -// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name. Panics if no rule is found. -func (s TestingSingleton) Rule(rule string) TestingBuildParams { - return buildParamsFromRule(s.provider, rule) +type TestingModule struct { + baseTestingComponent + module Module } -// MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string. Returns an empty -// BuildParams if no rule is found. -func (s TestingSingleton) MaybeDescription(desc string) TestingBuildParams { - return maybeBuildParamsFromDescription(s.provider, desc) +func newTestingModule(config Config, module Module) TestingModule { + return TestingModule{ + newBaseTestingComponent(config, module), + module, + } } -// Description finds a call to ctx.Build with BuildParams.Description set to a the given string. Panics if no rule is -// found. -func (s TestingSingleton) Description(desc string) TestingBuildParams { - return buildParamsFromDescription(s.provider, desc) +// Module returns the Module wrapped by the TestingModule. +func (m TestingModule) Module() Module { + return m.module } -// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel() -// value matches the provided string. Returns an empty BuildParams if no rule is found. -func (s TestingSingleton) MaybeOutput(file string) TestingBuildParams { - p, _ := maybeBuildParamsFromOutput(s.provider, file) - return p +// VariablesForTestsRelativeToTop returns a copy of the Module.VariablesForTests() with every value +// having any temporary build dir usages replaced with paths relative to a notional top. +func (m TestingModule) VariablesForTestsRelativeToTop() map[string]string { + return normalizeStringMapRelativeToTop(m.config, m.module.VariablesForTests()) } -// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel() -// value matches the provided string. Panics if no rule is found. -func (s TestingSingleton) Output(file string) TestingBuildParams { - return buildParamsFromOutput(s.provider, file) +// TestingSingleton is wrapper around an android.Singleton that provides methods to find information about individual +// ctx.Build parameters for verification in tests. +type TestingSingleton struct { + baseTestingComponent + singleton Singleton } -// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms. -func (s TestingSingleton) AllOutputs() []string { - return allOutputs(s.provider) +// Singleton returns the Singleton wrapped by the TestingSingleton. +func (s TestingSingleton) Singleton() Singleton { + return s.singleton } func FailIfErrored(t *testing.T, errs []error) { diff --git a/android/variable_test.go b/android/variable_test.go index d16e45880..928bca609 100644 --- a/android/variable_test.go +++ b/android/variable_test.go @@ -182,7 +182,7 @@ func TestProductVariables(t *testing.T) { } ` - emptyTestFixtureFactory.RunTest(t, + GroupFixturePreparers( FixtureModifyProductVariables(func(variables FixtureProductVariables) { variables.Eng = proptools.BoolPtr(true) }), @@ -204,7 +204,7 @@ func TestProductVariables(t *testing.T) { }) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) } var testProductVariableDefaultsProperties = struct { @@ -288,7 +288,7 @@ func TestProductVariablesDefaults(t *testing.T) { } ` - result := emptyTestFixtureFactory.RunTest(t, + result := GroupFixturePreparers( FixtureModifyProductVariables(func(variables FixtureProductVariables) { variables.Eng = boolPtr(true) }), @@ -299,7 +299,7 @@ func TestProductVariablesDefaults(t *testing.T) { ctx.RegisterModuleType("defaults", productVariablesDefaultsTestDefaultsFactory) }), FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) foo := result.ModuleForTests("foo", "").Module().(*productVariablesDefaultsTestModule) diff --git a/android/visibility_test.go b/android/visibility_test.go index fdf18ce00..ffd79093e 100644 --- a/android/visibility_test.go +++ b/android/visibility_test.go @@ -1142,7 +1142,7 @@ var visibilityTests = []struct { func TestVisibility(t *testing.T) { for _, test := range visibilityTests { t.Run(test.name, func(t *testing.T) { - result := emptyTestFixtureFactory.Extend( + result := GroupFixturePreparers( // General preparers in alphabetical order as test infrastructure will enforce correct // registration order. PrepareForTestWithArchMutator, diff --git a/apex/OWNERS b/apex/OWNERS index fee739b56..8e4ba5cd5 100644 --- a/apex/OWNERS +++ b/apex/OWNERS @@ -1,4 +1 @@ per-file * = jiyong@google.com - -per-file allowed_deps.txt = set noparent -per-file allowed_deps.txt = dariofreni@google.com,hansson@google.com,harpin@google.com,jiyong@google.com,narayan@google.com,jham@google.com diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt deleted file mode 100644 index 154b9aa67..000000000 --- a/apex/allowed_deps.txt +++ /dev/null @@ -1,652 +0,0 @@ -# A list of allowed dependencies for all updatable modules. -# -# The list tracks all direct and transitive dependencies that end up within any -# of the updatable binaries; specifically excluding external dependencies -# required to compile those binaries. This prevents potential regressions in -# case a new dependency is not aware of the different functional and -# non-functional requirements being part of an updatable module, for example -# setting correct min_sdk_version. -# -# To update the list, run: -# repo-root$ build/soong/scripts/update-apex-allowed-deps.sh -# -# See go/apex-allowed-deps-error for more details. -# TODO(b/157465465): introduce automated quality signals and remove this list. - -adbd(minSdkVersion:(no version)) -android.hardware.cas.native@1.0(minSdkVersion:29) -android.hardware.cas@1.0(minSdkVersion:29) -android.hardware.common-ndk_platform(minSdkVersion:29) -android.hardware.common-unstable-ndk_platform(minSdkVersion:29) -android.hardware.common-V2-ndk_platform(minSdkVersion:29) -android.hardware.graphics.allocator@2.0(minSdkVersion:29) -android.hardware.graphics.allocator@3.0(minSdkVersion:29) -android.hardware.graphics.allocator@4.0(minSdkVersion:29) -android.hardware.graphics.bufferqueue@1.0(minSdkVersion:29) -android.hardware.graphics.bufferqueue@2.0(minSdkVersion:29) -android.hardware.graphics.common-ndk_platform(minSdkVersion:29) -android.hardware.graphics.common-unstable-ndk_platform(minSdkVersion:29) -android.hardware.graphics.common-V2-ndk_platform(minSdkVersion:29) -android.hardware.graphics.common@1.0(minSdkVersion:29) -android.hardware.graphics.common@1.1(minSdkVersion:29) -android.hardware.graphics.common@1.2(minSdkVersion:29) -android.hardware.graphics.mapper@2.0(minSdkVersion:29) -android.hardware.graphics.mapper@2.1(minSdkVersion:29) -android.hardware.graphics.mapper@3.0(minSdkVersion:29) -android.hardware.graphics.mapper@4.0(minSdkVersion:29) -android.hardware.media.bufferpool@2.0(minSdkVersion:29) -android.hardware.media.c2@1.0(minSdkVersion:29) -android.hardware.media.c2@1.1(minSdkVersion:29) -android.hardware.media.omx@1.0(minSdkVersion:29) -android.hardware.media@1.0(minSdkVersion:29) -android.hardware.neuralnetworks-V1-ndk_platform(minSdkVersion:30) -android.hardware.neuralnetworks@1.0(minSdkVersion:30) -android.hardware.neuralnetworks@1.1(minSdkVersion:30) -android.hardware.neuralnetworks@1.2(minSdkVersion:30) -android.hardware.neuralnetworks@1.3(minSdkVersion:30) -android.hardware.tetheroffload.config-V1.0-java(minSdkVersion:current) -android.hardware.tetheroffload.control-V1.0-java(minSdkVersion:current) -android.hidl.allocator@1.0(minSdkVersion:29) -android.hidl.base-V1.0-java(minSdkVersion:current) -android.hidl.memory.token@1.0(minSdkVersion:29) -android.hidl.memory@1.0(minSdkVersion:29) -android.hidl.safe_union@1.0(minSdkVersion:29) -android.hidl.token@1.0(minSdkVersion:29) -android.hidl.token@1.0-utils(minSdkVersion:29) -android.net.ipsec.ike(minSdkVersion:30) -android.net.ipsec.ike(minSdkVersion:current) -android.net.ipsec.ike.xml(minSdkVersion:(no version)) -androidx-constraintlayout_constraintlayout(minSdkVersion:14) -androidx-constraintlayout_constraintlayout-solver(minSdkVersion:24) -androidx.activity_activity(minSdkVersion:14) -androidx.activity_activity-ktx(minSdkVersion:14) -androidx.annotation_annotation(minSdkVersion:24) -androidx.annotation_annotation(minSdkVersion:current) -androidx.appcompat_appcompat(minSdkVersion:14) -androidx.appcompat_appcompat-resources(minSdkVersion:14) -androidx.arch.core_core-common(minSdkVersion:24) -androidx.arch.core_core-common(minSdkVersion:current) -androidx.arch.core_core-runtime(minSdkVersion:14) -androidx.asynclayoutinflater_asynclayoutinflater(minSdkVersion:14) -androidx.autofill_autofill(minSdkVersion:14) -androidx.cardview_cardview(minSdkVersion:14) -androidx.collection_collection(minSdkVersion:24) -androidx.collection_collection(minSdkVersion:current) -androidx.collection_collection-ktx(minSdkVersion:24) -androidx.coordinatorlayout_coordinatorlayout(minSdkVersion:14) -androidx.core_core(minSdkVersion:14) -androidx.core_core-ktx(minSdkVersion:14) -androidx.cursoradapter_cursoradapter(minSdkVersion:14) -androidx.customview_customview(minSdkVersion:14) -androidx.documentfile_documentfile(minSdkVersion:14) -androidx.drawerlayout_drawerlayout(minSdkVersion:14) -androidx.dynamicanimation_dynamicanimation(minSdkVersion:14) -androidx.fragment_fragment(minSdkVersion:14) -androidx.fragment_fragment-ktx(minSdkVersion:14) -androidx.interpolator_interpolator(minSdkVersion:14) -androidx.leanback_leanback(minSdkVersion:17) -androidx.leanback_leanback-preference(minSdkVersion:21) -androidx.legacy_legacy-preference-v14(minSdkVersion:14) -androidx.legacy_legacy-support-core-ui(minSdkVersion:14) -androidx.legacy_legacy-support-core-utils(minSdkVersion:14) -androidx.legacy_legacy-support-v13(minSdkVersion:14) -androidx.legacy_legacy-support-v4(minSdkVersion:14) -androidx.lifecycle_lifecycle-common(minSdkVersion:24) -androidx.lifecycle_lifecycle-common(minSdkVersion:current) -androidx.lifecycle_lifecycle-common-java8(minSdkVersion:24) -androidx.lifecycle_lifecycle-extensions(minSdkVersion:14) -androidx.lifecycle_lifecycle-livedata(minSdkVersion:14) -androidx.lifecycle_lifecycle-livedata-core(minSdkVersion:14) -androidx.lifecycle_lifecycle-livedata-core-ktx(minSdkVersion:14) -androidx.lifecycle_lifecycle-process(minSdkVersion:14) -androidx.lifecycle_lifecycle-runtime(minSdkVersion:14) -androidx.lifecycle_lifecycle-runtime-ktx(minSdkVersion:14) -androidx.lifecycle_lifecycle-service(minSdkVersion:14) -androidx.lifecycle_lifecycle-viewmodel(minSdkVersion:14) -androidx.lifecycle_lifecycle-viewmodel-ktx(minSdkVersion:14) -androidx.lifecycle_lifecycle-viewmodel-savedstate(minSdkVersion:14) -androidx.loader_loader(minSdkVersion:14) -androidx.localbroadcastmanager_localbroadcastmanager(minSdkVersion:14) -androidx.media_media(minSdkVersion:14) -androidx.navigation_navigation-common(minSdkVersion:14) -androidx.navigation_navigation-common-ktx(minSdkVersion:14) -androidx.navigation_navigation-fragment(minSdkVersion:14) -androidx.navigation_navigation-fragment-ktx(minSdkVersion:14) -androidx.navigation_navigation-runtime(minSdkVersion:14) -androidx.navigation_navigation-runtime-ktx(minSdkVersion:14) -androidx.navigation_navigation-ui(minSdkVersion:14) -androidx.navigation_navigation-ui-ktx(minSdkVersion:14) -androidx.preference_preference(minSdkVersion:14) -androidx.print_print(minSdkVersion:14) -androidx.recyclerview_recyclerview(minSdkVersion:14) -androidx.recyclerview_recyclerview-selection(minSdkVersion:14) -androidx.savedstate_savedstate(minSdkVersion:14) -androidx.slidingpanelayout_slidingpanelayout(minSdkVersion:14) -androidx.swiperefreshlayout_swiperefreshlayout(minSdkVersion:14) -androidx.transition_transition(minSdkVersion:14) -androidx.vectordrawable_vectordrawable(minSdkVersion:14) -androidx.vectordrawable_vectordrawable-animated(minSdkVersion:14) -androidx.versionedparcelable_versionedparcelable(minSdkVersion:14) -androidx.viewpager_viewpager(minSdkVersion:14) -apache-commons-compress(minSdkVersion:current) -art.module.public.api.stubs(minSdkVersion:(no version)) -bcm_object(minSdkVersion:29) -bionic_libc_platform_headers(minSdkVersion:29) -boringssl_self_test(minSdkVersion:29) -bouncycastle_ike_digests(minSdkVersion:current) -bpf_syscall_wrappers(minSdkVersion:30) -brotli-java(minSdkVersion:current) -captiveportal-lib(minSdkVersion:29) -car-ui-lib(minSdkVersion:28) -car-ui-lib-overlayable(minSdkVersion:28) -CellBroadcastApp(minSdkVersion:29) -CellBroadcastServiceModule(minSdkVersion:29) -codecs_g711dec(minSdkVersion:29) -com.google.android.material_material(minSdkVersion:14) -conscrypt(minSdkVersion:29) -conscrypt.module.platform.api.stubs(minSdkVersion:(no version)) -conscrypt.module.public.api.stubs(minSdkVersion:(no version)) -core-lambda-stubs(minSdkVersion:(no version)) -core.current.stubs(minSdkVersion:(no version)) -crtbegin_dynamic(minSdkVersion:16) -crtbegin_dynamic(minSdkVersion:apex_inherit) -crtbegin_dynamic1(minSdkVersion:16) -crtbegin_dynamic1(minSdkVersion:apex_inherit) -crtbegin_so(minSdkVersion:16) -crtbegin_so(minSdkVersion:apex_inherit) -crtbegin_so1(minSdkVersion:16) -crtbegin_so1(minSdkVersion:apex_inherit) -crtbrand(minSdkVersion:16) -crtbrand(minSdkVersion:apex_inherit) -crtend_android(minSdkVersion:16) -crtend_android(minSdkVersion:apex_inherit) -crtend_so(minSdkVersion:16) -crtend_so(minSdkVersion:apex_inherit) -datastallprotosnano(minSdkVersion:29) -derive_classpath(minSdkVersion:30) -derive_sdk(minSdkVersion:30) -derive_sdk(minSdkVersion:current) -derive_sdk_prefer32(minSdkVersion:30) -derive_sdk_prefer32(minSdkVersion:current) -dnsresolver_aidl_interface-lateststable-ndk_platform(minSdkVersion:29) -dnsresolver_aidl_interface-unstable-ndk_platform(minSdkVersion:29) -dnsresolver_aidl_interface-V7-ndk_platform(minSdkVersion:29) -dnsresolver_aidl_interface-V8-ndk_platform(minSdkVersion:29) -DocumentsUI-res-lib(minSdkVersion:29) -exoplayer2-extractor(minSdkVersion:16) -exoplayer2-extractor-annotation-stubs(minSdkVersion:16) -ExtServices(minSdkVersion:current) -ExtServices-core(minSdkVersion:current) -flatbuffer_headers(minSdkVersion:(no version)) -fmtlib(minSdkVersion:29) -fmtlib_ndk(minSdkVersion:29) -framework-mediaprovider(minSdkVersion:30) -framework-permission(minSdkVersion:30) -framework-permission(minSdkVersion:current) -framework-permission-s(minSdkVersion:30) -framework-permission-s-shared(minSdkVersion:30) -framework-sdkextensions(minSdkVersion:30) -framework-sdkextensions(minSdkVersion:current) -framework-statsd(minSdkVersion:30) -framework-statsd(minSdkVersion:current) -framework-tethering(minSdkVersion:30) -framework-tethering(minSdkVersion:current) -gemmlowp_headers(minSdkVersion:(no version)) -GoogleCellBroadcastApp(minSdkVersion:29) -GoogleCellBroadcastServiceModule(minSdkVersion:29) -GoogleExtServices(minSdkVersion:current) -GooglePermissionController(minSdkVersion:30) -guava(minSdkVersion:current) -gwp_asan_headers(minSdkVersion:(no version)) -i18n.module.public.api.stubs(minSdkVersion:(no version)) -iconloader(minSdkVersion:21) -ike-internals(minSdkVersion:current) -InProcessTethering(minSdkVersion:30) -InProcessTethering(minSdkVersion:current) -ipmemorystore-aidl-interfaces-java(minSdkVersion:29) -ipmemorystore-aidl-interfaces-unstable-java(minSdkVersion:29) -ipmemorystore-aidl-interfaces-V10-java(minSdkVersion:29) -ipmemorystore-aidl-interfaces-V11-java(minSdkVersion:29) -jni_headers(minSdkVersion:29) -jsr305(minSdkVersion:14) -kotlinx-coroutines-android(minSdkVersion:current) -kotlinx-coroutines-core(minSdkVersion:current) -legacy.art.module.platform.api.stubs(minSdkVersion:(no version)) -legacy.core.platform.api.stubs(minSdkVersion:(no version)) -legacy.i18n.module.platform.api.stubs(minSdkVersion:(no version)) -libaacextractor(minSdkVersion:29) -libadb_crypto(minSdkVersion:(no version)) -libadb_pairing_auth(minSdkVersion:(no version)) -libadb_pairing_connection(minSdkVersion:(no version)) -libadb_pairing_server(minSdkVersion:(no version)) -libadb_protos(minSdkVersion:(no version)) -libadb_sysdeps(minSdkVersion:apex_inherit) -libadb_tls_connection(minSdkVersion:(no version)) -libadbconnection_client(minSdkVersion:(no version)) -libadbconnection_server(minSdkVersion:(no version)) -libadbd(minSdkVersion:(no version)) -libadbd_core(minSdkVersion:(no version)) -libadbd_services(minSdkVersion:(no version)) -liballoc.rust_sysroot(minSdkVersion:29) -libamrextractor(minSdkVersion:29) -libapp_processes_protos_lite(minSdkVersion:(no version)) -libarect(minSdkVersion:29) -libasyncio(minSdkVersion:(no version)) -libatomic(minSdkVersion:(no version)) -libaudio_system_headers(minSdkVersion:29) -libaudioclient_headers(minSdkVersion:29) -libaudiofoundation_headers(minSdkVersion:29) -libaudioutils(minSdkVersion:29) -libaudioutils_fixedfft(minSdkVersion:29) -libavcdec(minSdkVersion:29) -libavcenc(minSdkVersion:29) -libavservices_minijail(minSdkVersion:29) -libbacktrace_headers(minSdkVersion:apex_inherit) -libbacktrace_rs.rust_sysroot(minSdkVersion:29) -libbacktrace_sys.rust_sysroot(minSdkVersion:29) -libbase(minSdkVersion:29) -libbase_headers(minSdkVersion:29) -libbase_ndk(minSdkVersion:29) -libbinder_headers(minSdkVersion:29) -libbinder_headers_platform_shared(minSdkVersion:29) -libbinderthreadstateutils(minSdkVersion:29) -libbluetooth-types-header(minSdkVersion:29) -libbrotli(minSdkVersion:(no version)) -libbuildversion(minSdkVersion:(no version)) -libc(minSdkVersion:(no version)) -libc++(minSdkVersion:apex_inherit) -libc++_static(minSdkVersion:apex_inherit) -libc++abi(minSdkVersion:apex_inherit) -libc++demangle(minSdkVersion:apex_inherit) -libc_headers(minSdkVersion:apex_inherit) -libc_headers_arch(minSdkVersion:apex_inherit) -libcap(minSdkVersion:29) -libcfg_if(minSdkVersion:29) -libcfg_if.rust_sysroot(minSdkVersion:29) -libclang_rt.hwasan-aarch64-android.llndk(minSdkVersion:(no version)) -libcodec2(minSdkVersion:29) -libcodec2_headers(minSdkVersion:29) -libcodec2_hidl@1.0(minSdkVersion:29) -libcodec2_hidl@1.1(minSdkVersion:29) -libcodec2_internal(minSdkVersion:29) -libcodec2_soft_aacdec(minSdkVersion:29) -libcodec2_soft_aacenc(minSdkVersion:29) -libcodec2_soft_amrnbdec(minSdkVersion:29) -libcodec2_soft_amrnbenc(minSdkVersion:29) -libcodec2_soft_amrwbdec(minSdkVersion:29) -libcodec2_soft_amrwbenc(minSdkVersion:29) -libcodec2_soft_av1dec_gav1(minSdkVersion:29) -libcodec2_soft_avcdec(minSdkVersion:29) -libcodec2_soft_avcenc(minSdkVersion:29) -libcodec2_soft_common(minSdkVersion:29) -libcodec2_soft_flacdec(minSdkVersion:29) -libcodec2_soft_flacenc(minSdkVersion:29) -libcodec2_soft_g711alawdec(minSdkVersion:29) -libcodec2_soft_g711mlawdec(minSdkVersion:29) -libcodec2_soft_gsmdec(minSdkVersion:29) -libcodec2_soft_h263dec(minSdkVersion:29) -libcodec2_soft_h263enc(minSdkVersion:29) -libcodec2_soft_hevcdec(minSdkVersion:29) -libcodec2_soft_hevcenc(minSdkVersion:29) -libcodec2_soft_mp3dec(minSdkVersion:29) -libcodec2_soft_mpeg2dec(minSdkVersion:29) -libcodec2_soft_mpeg4dec(minSdkVersion:29) -libcodec2_soft_mpeg4enc(minSdkVersion:29) -libcodec2_soft_opusdec(minSdkVersion:29) -libcodec2_soft_opusenc(minSdkVersion:29) -libcodec2_soft_rawdec(minSdkVersion:29) -libcodec2_soft_vorbisdec(minSdkVersion:29) -libcodec2_soft_vp8dec(minSdkVersion:29) -libcodec2_soft_vp8enc(minSdkVersion:29) -libcodec2_soft_vp9dec(minSdkVersion:29) -libcodec2_soft_vp9enc(minSdkVersion:29) -libcodec2_vndk(minSdkVersion:29) -libcompiler_builtins.rust_sysroot(minSdkVersion:29) -libcore.rust_sysroot(minSdkVersion:29) -libcrypto(minSdkVersion:29) -libcrypto_static(minSdkVersion:(no version)) -libcrypto_utils(minSdkVersion:(no version)) -libcutils(minSdkVersion:29) -libcutils_headers(minSdkVersion:29) -libcutils_sockets(minSdkVersion:29) -libderive_classpath(minSdkVersion:30) -libderive_sdk(minSdkVersion:30) -libdiagnose_usb(minSdkVersion:(no version)) -libdl(minSdkVersion:(no version)) -libdmabufheap(minSdkVersion:29) -libeigen(minSdkVersion:(no version)) -libfifo(minSdkVersion:29) -libFLAC(minSdkVersion:29) -libFLAC-config(minSdkVersion:29) -libFLAC-headers(minSdkVersion:29) -libflacextractor(minSdkVersion:29) -libfmq(minSdkVersion:29) -libfmq-base(minSdkVersion:29) -libFraunhoferAAC(minSdkVersion:29) -libfuse(minSdkVersion:30) -libfuse_jni(minSdkVersion:30) -libgav1(minSdkVersion:29) -libgcc(minSdkVersion:(no version)) -libgcc_stripped(minSdkVersion:(no version)) -libgetopts(minSdkVersion:29) -libgralloctypes(minSdkVersion:29) -libgrallocusage(minSdkVersion:29) -libgsm(minSdkVersion:apex_inherit) -libgtest_prod(minSdkVersion:apex_inherit) -libgui_bufferqueue_static(minSdkVersion:29) -libgui_headers(minSdkVersion:29) -libhardware(minSdkVersion:29) -libhardware_headers(minSdkVersion:29) -libhashbrown.rust_sysroot(minSdkVersion:29) -libhevcdec(minSdkVersion:29) -libhevcenc(minSdkVersion:29) -libhidlbase(minSdkVersion:29) -libhidlmemory(minSdkVersion:29) -libhwbinder-impl-internal(minSdkVersion:29) -libhwbinder_headers(minSdkVersion:29) -libion(minSdkVersion:29) -libjavacrypto(minSdkVersion:29) -libjsoncpp(minSdkVersion:29) -liblazy_static(minSdkVersion:29) -liblibc(minSdkVersion:29) -liblibc.rust_sysroot(minSdkVersion:29) -libLibGuiProperties(minSdkVersion:29) -liblibm(minSdkVersion:29) -liblog(minSdkVersion:(no version)) -liblog_headers(minSdkVersion:29) -liblog_rust(minSdkVersion:29) -liblua(minSdkVersion:(no version)) -liblz4(minSdkVersion:(no version)) -libm(minSdkVersion:(no version)) -libmath(minSdkVersion:29) -libmdnssd(minSdkVersion:(no version)) -libmedia_codecserviceregistrant(minSdkVersion:29) -libmedia_datasource_headers(minSdkVersion:29) -libmedia_headers(minSdkVersion:29) -libmedia_helper_headers(minSdkVersion:29) -libmedia_midiiowrapper(minSdkVersion:29) -libmediaparser-jni(minSdkVersion:29) -libmidiextractor(minSdkVersion:29) -libminijail(minSdkVersion:29) -libminijail_gen_constants(minSdkVersion:(no version)) -libminijail_gen_constants_obj(minSdkVersion:29) -libminijail_gen_syscall(minSdkVersion:(no version)) -libminijail_gen_syscall_obj(minSdkVersion:29) -libminijail_generated(minSdkVersion:29) -libmkvextractor(minSdkVersion:29) -libmodules-utils-build(minSdkVersion:29) -libmp3extractor(minSdkVersion:29) -libmp4extractor(minSdkVersion:29) -libmpeg2dec(minSdkVersion:29) -libmpeg2extractor(minSdkVersion:29) -libnativebase_headers(minSdkVersion:29) -libnativehelper_compat_libc++(minSdkVersion:(no version)) -libnativehelper_header_only(minSdkVersion:29) -libnativewindow_headers(minSdkVersion:29) -libnetd_resolv(minSdkVersion:29) -libnetdbinder_utils_headers(minSdkVersion:29) -libnetdutils(minSdkVersion:29) -libnetjniutils(minSdkVersion:29) -libnetworkstackutilsjni(minSdkVersion:29) -libneuralnetworks(minSdkVersion:(no version)) -libneuralnetworks_common(minSdkVersion:(no version)) -libneuralnetworks_headers(minSdkVersion:(no version)) -liboggextractor(minSdkVersion:29) -libonce_cell(minSdkVersion:29) -libopus(minSdkVersion:29) -libpanic_unwind.rust_sysroot(minSdkVersion:29) -libprocessgroup(minSdkVersion:29) -libprocessgroup_headers(minSdkVersion:29) -libprocpartition(minSdkVersion:(no version)) -libprofiler_builtins.rust_sysroot(minSdkVersion:29) -libprotobuf-cpp-lite(minSdkVersion:29) -libprotobuf-java-lite(minSdkVersion:current) -libprotobuf-java-nano(minSdkVersion:9) -libprotoutil(minSdkVersion:(no version)) -libqemu_pipe(minSdkVersion:(no version)) -libquiche_ffi(minSdkVersion:29) -libring(minSdkVersion:29) -libring-core(minSdkVersion:29) -librustc_demangle.rust_sysroot(minSdkVersion:29) -libruy_static(minSdkVersion:30) -libsdk_proto(minSdkVersion:30) -libsfplugin_ccodec_utils(minSdkVersion:29) -libsonivoxwithoutjet(minSdkVersion:29) -libspeexresampler(minSdkVersion:29) -libspin(minSdkVersion:29) -libssl(minSdkVersion:29) -libstagefright_amrnb_common(minSdkVersion:29) -libstagefright_amrnbdec(minSdkVersion:29) -libstagefright_amrnbenc(minSdkVersion:29) -libstagefright_amrwbdec(minSdkVersion:29) -libstagefright_amrwbenc(minSdkVersion:29) -libstagefright_bufferpool@2.0.1(minSdkVersion:29) -libstagefright_bufferqueue_helper(minSdkVersion:29) -libstagefright_enc_common(minSdkVersion:29) -libstagefright_esds(minSdkVersion:29) -libstagefright_flacdec(minSdkVersion:29) -libstagefright_foundation(minSdkVersion:29) -libstagefright_foundation_headers(minSdkVersion:29) -libstagefright_foundation_without_imemory(minSdkVersion:29) -libstagefright_headers(minSdkVersion:29) -libstagefright_id3(minSdkVersion:29) -libstagefright_m4vh263dec(minSdkVersion:29) -libstagefright_m4vh263enc(minSdkVersion:29) -libstagefright_metadatautils(minSdkVersion:29) -libstagefright_mp3dec(minSdkVersion:29) -libstagefright_mp3dec_headers(minSdkVersion:29) -libstagefright_mpeg2extractor(minSdkVersion:29) -libstagefright_mpeg2support_nocrypto(minSdkVersion:29) -libstats_jni(minSdkVersion:(no version)) -libstats_jni(minSdkVersion:30) -libstatslog_resolv(minSdkVersion:29) -libstatslog_statsd(minSdkVersion:(no version)) -libstatslog_statsd(minSdkVersion:30) -libstatspull(minSdkVersion:(no version)) -libstatspull(minSdkVersion:30) -libstatspush_compat(minSdkVersion:29) -libstatssocket(minSdkVersion:(no version)) -libstatssocket(minSdkVersion:30) -libstatssocket_headers(minSdkVersion:29) -libstd(minSdkVersion:29) -libsystem_headers(minSdkVersion:apex_inherit) -libsysutils(minSdkVersion:apex_inherit) -libterm(minSdkVersion:29) -libtest(minSdkVersion:29) -libtetherutilsjni(minSdkVersion:30) -libtetherutilsjni(minSdkVersion:current) -libtextclassifier(minSdkVersion:(no version)) -libtextclassifier-java(minSdkVersion:current) -libtextclassifier_hash_headers(minSdkVersion:(no version)) -libtextclassifier_hash_static(minSdkVersion:(no version)) -libtflite_kernel_utils(minSdkVersion:(no version)) -libtflite_static(minSdkVersion:(no version)) -libui(minSdkVersion:29) -libui_headers(minSdkVersion:29) -libunicode_width.rust_sysroot(minSdkVersion:29) -libuntrusted(minSdkVersion:29) -libunwind.rust_sysroot(minSdkVersion:29) -libunwind_llvm(minSdkVersion:apex_inherit) -libutf(minSdkVersion:(no version)) -libutils(minSdkVersion:apex_inherit) -libutils_headers(minSdkVersion:apex_inherit) -libvorbisidec(minSdkVersion:29) -libvpx(minSdkVersion:29) -libwatchdog(minSdkVersion:29) -libwavextractor(minSdkVersion:29) -libwebm(minSdkVersion:29) -libyuv(minSdkVersion:29) -libyuv_static(minSdkVersion:29) -libzstd(minSdkVersion:(no version)) -media_ndk_headers(minSdkVersion:29) -media_plugin_headers(minSdkVersion:29) -MediaProvider(minSdkVersion:30) -mediaswcodec(minSdkVersion:29) -metrics-constants-protos(minSdkVersion:29) -modules-annotation-minsdk(minSdkVersion:29) -modules-utils-build(minSdkVersion:29) -modules-utils-build_system(minSdkVersion:29) -modules-utils-os(minSdkVersion:30) -ndk_crtbegin_so.19(minSdkVersion:(no version)) -ndk_crtbegin_so.21(minSdkVersion:(no version)) -ndk_crtbegin_so.27(minSdkVersion:(no version)) -ndk_crtend_so.19(minSdkVersion:(no version)) -ndk_crtend_so.21(minSdkVersion:(no version)) -ndk_crtend_so.27(minSdkVersion:(no version)) -ndk_libc++_static(minSdkVersion:(no version)) -ndk_libc++_static(minSdkVersion:16) -ndk_libc++abi(minSdkVersion:(no version)) -ndk_libc++abi(minSdkVersion:16) -ndk_libunwind(minSdkVersion:16) -net-utils-device-common(minSdkVersion:29) -net-utils-framework-common(minSdkVersion:current) -netd-client(minSdkVersion:29) -netd_aidl_interface-java(minSdkVersion:29) -netd_aidl_interface-lateststable-java(minSdkVersion:29) -netd_aidl_interface-unstable-java(minSdkVersion:29) -netd_aidl_interface-V5-java(minSdkVersion:29) -netd_aidl_interface-V6-java(minSdkVersion:29) -netd_event_listener_interface-java(minSdkVersion:29) -netd_event_listener_interface-lateststable-ndk_platform(minSdkVersion:29) -netd_event_listener_interface-ndk_platform(minSdkVersion:29) -netd_event_listener_interface-unstable-ndk_platform(minSdkVersion:29) -netd_event_listener_interface-V1-ndk_platform(minSdkVersion:29) -netd_event_listener_interface-V2-ndk_platform(minSdkVersion:29) -netlink-client(minSdkVersion:29) -networkstack-aidl-interfaces-unstable-java(minSdkVersion:29) -networkstack-aidl-interfaces-V10-java(minSdkVersion:29) -networkstack-client(minSdkVersion:29) -NetworkStackApi29Shims(minSdkVersion:29) -NetworkStackApi30Shims(minSdkVersion:29) -NetworkStackApiStableDependencies(minSdkVersion:29) -NetworkStackApiStableLib(minSdkVersion:29) -NetworkStackApiStableShims(minSdkVersion:29) -networkstackprotos(minSdkVersion:29) -NetworkStackShimsCommon(minSdkVersion:29) -neuralnetworks_types(minSdkVersion:30) -neuralnetworks_utils_hal_1_0(minSdkVersion:30) -neuralnetworks_utils_hal_1_1(minSdkVersion:30) -neuralnetworks_utils_hal_1_2(minSdkVersion:30) -neuralnetworks_utils_hal_1_3(minSdkVersion:30) -neuralnetworks_utils_hal_aidl(minSdkVersion:30) -neuralnetworks_utils_hal_common(minSdkVersion:30) -neuralnetworks_utils_hal_service(minSdkVersion:30) -no_op(minSdkVersion:current) -note_memtag_heap_async(minSdkVersion:16) -note_memtag_heap_sync(minSdkVersion:16) -PermissionController(minSdkVersion:30) -permissioncontroller-statsd(minSdkVersion:current) -philox_random(minSdkVersion:(no version)) -philox_random_headers(minSdkVersion:(no version)) -prebuilt_androidx-constraintlayout_constraintlayout-nodeps(minSdkVersion:(no version)) -prebuilt_androidx-constraintlayout_constraintlayout-solver-nodeps(minSdkVersion:current) -prebuilt_androidx.activity_activity-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.activity_activity-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.annotation_annotation-nodeps(minSdkVersion:current) -prebuilt_androidx.appcompat_appcompat-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.appcompat_appcompat-resources-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.arch.core_core-common-nodeps(minSdkVersion:current) -prebuilt_androidx.arch.core_core-runtime-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.asynclayoutinflater_asynclayoutinflater-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.autofill_autofill-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.cardview_cardview-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.collection_collection-ktx-nodeps(minSdkVersion:current) -prebuilt_androidx.collection_collection-nodeps(minSdkVersion:current) -prebuilt_androidx.coordinatorlayout_coordinatorlayout-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.core_core-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.core_core-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.cursoradapter_cursoradapter-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.customview_customview-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.documentfile_documentfile-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.drawerlayout_drawerlayout-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.dynamicanimation_dynamicanimation-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.fragment_fragment-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.fragment_fragment-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.interpolator_interpolator-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.leanback_leanback-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.leanback_leanback-preference-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.legacy_legacy-support-core-ui-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.legacy_legacy-support-core-utils-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.legacy_legacy-support-v13-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-common-java8-nodeps(minSdkVersion:current) -prebuilt_androidx.lifecycle_lifecycle-common-nodeps(minSdkVersion:current) -prebuilt_androidx.lifecycle_lifecycle-extensions-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-livedata-core-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-livedata-core-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-livedata-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-process-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-runtime-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-runtime-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-service-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-viewmodel-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-viewmodel-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.lifecycle_lifecycle-viewmodel-savedstate-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.loader_loader-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.localbroadcastmanager_localbroadcastmanager-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.media_media-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-common-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-common-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-fragment-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-fragment-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-runtime-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-runtime-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-ui-ktx-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.navigation_navigation-ui-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.preference_preference-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.print_print-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.recyclerview_recyclerview-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.recyclerview_recyclerview-selection-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.savedstate_savedstate-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.slidingpanelayout_slidingpanelayout-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.swiperefreshlayout_swiperefreshlayout-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.transition_transition-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.vectordrawable_vectordrawable-animated-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.vectordrawable_vectordrawable-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.versionedparcelable_versionedparcelable-nodeps(minSdkVersion:(no version)) -prebuilt_androidx.viewpager_viewpager-nodeps(minSdkVersion:(no version)) -prebuilt_com.google.android.material_material-nodeps(minSdkVersion:(no version)) -prebuilt_error_prone_annotations(minSdkVersion:(no version)) -prebuilt_kotlin-stdlib(minSdkVersion:current) -prebuilt_kotlinx-coroutines-android-nodeps(minSdkVersion:(no version)) -prebuilt_kotlinx-coroutines-core-nodeps(minSdkVersion:(no version)) -prebuilt_libclang_rt.builtins-aarch64-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.builtins-arm-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.builtins-i686-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.builtins-x86_64-android(minSdkVersion:(no version)) -prebuilt_libunwind(minSdkVersion:(no version)) -prebuilt_test_framework-sdkextensions(minSdkVersion:(no version)) -server_configurable_flags(minSdkVersion:29) -service-media-s(minSdkVersion:29) -service-permission(minSdkVersion:30) -service-permission(minSdkVersion:current) -service-permission-shared(minSdkVersion:30) -service-statsd(minSdkVersion:30) -service-statsd(minSdkVersion:current) -SettingsLibActionBarShadow(minSdkVersion:21) -SettingsLibAppPreference(minSdkVersion:21) -SettingsLibBarChartPreference(minSdkVersion:21) -SettingsLibHelpUtils(minSdkVersion:21) -SettingsLibLayoutPreference(minSdkVersion:21) -SettingsLibProgressBar(minSdkVersion:21) -SettingsLibRestrictedLockUtils(minSdkVersion:21) -SettingsLibSearchWidget(minSdkVersion:21) -SettingsLibSettingsTheme(minSdkVersion:21) -SettingsLibUtils(minSdkVersion:21) -stats_proto(minSdkVersion:29) -statsd(minSdkVersion:(no version)) -statsd(minSdkVersion:30) -statsd-aidl-ndk_platform(minSdkVersion:(no version)) -statsd-aidl-ndk_platform(minSdkVersion:30) -statsprotos(minSdkVersion:29) -tensorflow_headers(minSdkVersion:(no version)) -Tethering(minSdkVersion:30) -Tethering(minSdkVersion:current) -TetheringApiCurrentLib(minSdkVersion:30) -TetheringApiCurrentLib(minSdkVersion:current) -TetheringGoogle(minSdkVersion:30) -TetheringGoogle(minSdkVersion:current) -textclassifier-statsd(minSdkVersion:current) -TextClassifierNotificationLibNoManifest(minSdkVersion:29) -TextClassifierServiceLibNoManifest(minSdkVersion:28) -updatable-media(minSdkVersion:29) -xz-java(minSdkVersion:current) diff --git a/apex/apex.go b/apex/apex.go index 429465d80..a67fe1ffb 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -854,12 +854,7 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { if required, ok := depTag.(android.AlwaysRequireApexVariantTag); ok && required.AlwaysRequireApexVariant() { return true } - if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { - // The tag defines a dependency that never requires the child module to be part of the same - // apex as the parent so it does not need an apex variant created. - return false - } - if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) { + if !android.IsDepInSameApex(mctx, parent, child) { return false } if excludeVndkLibs { @@ -1003,11 +998,7 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { // If any of the dep is not available to platform, this module is also considered as being // not available to platform even if it has "//apex_available:platform" mctx.VisitDirectDeps(func(child android.Module) { - depTag := mctx.OtherModuleDependencyTag(child) - if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok { - return - } - if !am.DepIsInSameApex(mctx, child) { + if !android.IsDepInSameApex(mctx, am, child) { // if the dependency crosses apex boundary, don't consider it return } @@ -1207,11 +1198,13 @@ func useVendorAllowList(config android.Config) []string { }).([]string) } -// setUseVendorAllowListForTest overrides useVendorAllowList and must be called before the first -// call to useVendorAllowList() -func setUseVendorAllowListForTest(config android.Config, allowList []string) { - config.Once(useVendorAllowListKey, func() interface{} { - return allowList +// setUseVendorAllowListForTest returns a FixturePreparer that overrides useVendorAllowList and +// must be called before the first call to useVendorAllowList() +func setUseVendorAllowListForTest(allowList []string) android.FixturePreparer { + return android.FixtureModifyConfig(func(config android.Config) { + config.Once(useVendorAllowListKey, func() interface{} { + return allowList + }) }) } @@ -1870,7 +1863,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // like to record requiredNativeLibs even when // DepIsInSameAPex is false. We also shouldn't do // this for host. - if !am.DepIsInSameApex(ctx, am) { + // + // TODO(jiyong): explain why the same module is passed in twice. + // Switching the first am to parent breaks lots of tests. + if !android.IsDepInSameApex(ctx, am, am) { return false } @@ -2193,6 +2189,8 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext // If `to` is not actually in the same APEX as `from` then it does not need // apex_available and neither do any of its dependencies. + // + // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps(). if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) { // As soon as the dependency graph crosses the APEX boundary, don't go further. return false @@ -2276,6 +2274,8 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { // If `to` is not actually in the same APEX as `from` then it does not need // apex_available and neither do any of its dependencies. + // + // It is ok to call DepIsInSameApex() directly from within WalkPayloadDeps(). if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) { // As soon as the dependency graph crosses the APEX boundary, don't go // further. diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index ee9fc8115..0ed94afdb 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -58,8 +58,8 @@ var ( echo "ERROR: go/apex-allowed-deps-error"; echo "******************************"; echo "Detected changes to allowed dependencies in updatable modules."; - echo "To fix and update build/soong/apex/allowed_deps.txt, please run:"; - echo "$$ (croot && build/soong/scripts/update-apex-allowed-deps.sh)"; + echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:"; + echo "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)"; echo "Members of mainline-modularization@google.com will review the changes."; echo -e "******************************\n"; exit 1; @@ -81,25 +81,35 @@ func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContex } }) - allowedDeps := android.ExistentPathForSource(ctx, "build/soong/apex/allowed_deps.txt").Path() - + allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt") newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt") - ctx.Build(pctx, android.BuildParams{ - Rule: generateApexDepsInfoFilesRule, - Inputs: append(updatableFlatLists, allowedDeps), - Output: newAllowedDeps, - }) - s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check") - ctx.Build(pctx, android.BuildParams{ - Rule: diffAllowedApexDepsInfoRule, - Input: newAllowedDeps, - Output: s.allowedApexDepsInfoCheckResult, - Args: map[string]string{ - "allowed_deps": allowedDeps.String(), - "new_allowed_deps": newAllowedDeps.String(), - }, - }) + + if !allowedDepsSource.Valid() { + // Unbundled projects may not have packages/modules/common/ checked out; ignore those. + ctx.Build(pctx, android.BuildParams{ + Rule: android.Touch, + Output: s.allowedApexDepsInfoCheckResult, + }) + } else { + allowedDeps := allowedDepsSource.Path() + + ctx.Build(pctx, android.BuildParams{ + Rule: generateApexDepsInfoFilesRule, + Inputs: append(updatableFlatLists, allowedDeps), + Output: newAllowedDeps, + }) + + ctx.Build(pctx, android.BuildParams{ + Rule: diffAllowedApexDepsInfoRule, + Input: newAllowedDeps, + Output: s.allowedApexDepsInfoCheckResult, + Args: map[string]string{ + "allowed_deps": allowedDeps.String(), + "new_allowed_deps": newAllowedDeps.String(), + }, + }) + } ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult) } diff --git a/apex/apex_test.go b/apex/apex_test.go index ac98b070a..b15966085 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -50,49 +50,33 @@ func names(s string) (ns []string) { return } -func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer) { +func testApexError(t *testing.T, pattern, bp string, preparers ...android.FixturePreparer) { t.Helper() - ctx, config := testApexContext(t, bp, handlers...) - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - if len(errs) > 0 { - android.FailIfNoMatchingErrors(t, pattern, errs) - return - } - _, errs = ctx.PrepareBuildActions(config) - if len(errs) > 0 { - android.FailIfNoMatchingErrors(t, pattern, errs) - return - } - - t.Fatalf("missing expected error %q (0 errors are returned)", pattern) + apexFixtureFactory.Extend(preparers...). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). + RunTestWithBp(t, bp) } -func testApex(t *testing.T, bp string, handlers ...testCustomizer) *android.TestContext { +func testApex(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext { t.Helper() - ctx, config := testApexContext(t, bp, handlers...) - _, errs := ctx.ParseBlueprintsFiles(".") - android.FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(config) - android.FailIfErrored(t, errs) - return ctx + factory := apexFixtureFactory.Extend(preparers...) + if bp != "" { + factory = factory.Extend(android.FixtureWithRootAndroidBp(bp)) + } + result := factory.RunTest(t) + return result.TestContext } -type testCustomizer func(fs map[string][]byte, config android.Config) - -func withFiles(files map[string][]byte) testCustomizer { - return func(fs map[string][]byte, config android.Config) { - for k, v := range files { - fs[k] = v - } - } +func withFiles(files android.MockFS) android.FixturePreparer { + return files.AddToFixture() } -func withTargets(targets map[android.OsType][]android.Target) testCustomizer { - return func(fs map[string][]byte, config android.Config) { +func withTargets(targets map[android.OsType][]android.Target) android.FixturePreparer { + return android.FixtureModifyConfig(func(config android.Config) { for k, v := range targets { config.Targets[k] = v } - } + }) } // withNativeBridgeTargets sets configuration with targets including: @@ -100,34 +84,38 @@ func withTargets(targets map[android.OsType][]android.Target) testCustomizer { // - X86 (secondary) // - Arm64 on X86_64 (native bridge) // - Arm on X86 (native bridge) -func withNativeBridgeEnabled(_ map[string][]byte, config android.Config) { - config.Targets[android.Android] = []android.Target{ - {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, - NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, - {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, - NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, - {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, - NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64"}, - {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, - NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm"}, - } -} - -func withManifestPackageNameOverrides(specs []string) testCustomizer { - return func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.ManifestPackageNameOverrides = specs - } -} +var withNativeBridgeEnabled = android.FixtureModifyConfig( + func(config android.Config) { + config.Targets[android.Android] = []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, + NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, + {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, + NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, + NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64"}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, + NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm"}, + } + }, +) -func withBinder32bit(_ map[string][]byte, config android.Config) { - config.TestProductVariables.Binder32bit = proptools.BoolPtr(true) +func withManifestPackageNameOverrides(specs []string) android.FixturePreparer { + return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.ManifestPackageNameOverrides = specs + }) } -func withUnbundledBuild(_ map[string][]byte, config android.Config) { - config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) -} +var withBinder32bit = android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.Binder32bit = proptools.BoolPtr(true) + }, +) -var emptyFixtureFactory = android.NewFixtureFactory(&buildDir) +var withUnbundledBuild = android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.Unbundled_build = proptools.BoolPtr(true) + }, +) var apexFixtureFactory = android.NewFixtureFactory( &buildDir, @@ -217,143 +205,6 @@ var apexFixtureFactory = android.NewFixtureFactory( }), ) -func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) { - bp = bp + ` - filegroup { - name: "myapex-file_contexts", - srcs: [ - "system/sepolicy/apex/myapex-file_contexts", - ], - } - ` - - bp = bp + cc.GatherRequiredDepsForTest(android.Android) - - bp = bp + rust.GatherRequiredDepsForTest() - - bp = bp + java.GatherRequiredDepsForTest() - - fs := map[string][]byte{ - "a.java": nil, - "PrebuiltAppFoo.apk": nil, - "PrebuiltAppFooPriv.apk": nil, - "build/make/target/product/security": nil, - "apex_manifest.json": nil, - "AndroidManifest.xml": nil, - "system/sepolicy/apex/myapex-file_contexts": nil, - "system/sepolicy/apex/myapex.updatable-file_contexts": nil, - "system/sepolicy/apex/myapex2-file_contexts": nil, - "system/sepolicy/apex/otherapex-file_contexts": nil, - "system/sepolicy/apex/com.android.vndk-file_contexts": nil, - "system/sepolicy/apex/com.android.vndk.current-file_contexts": nil, - "mylib.cpp": nil, - "mytest.cpp": nil, - "mytest1.cpp": nil, - "mytest2.cpp": nil, - "mytest3.cpp": nil, - "myprebuilt": nil, - "my_include": nil, - "foo/bar/MyClass.java": nil, - "prebuilt.jar": nil, - "prebuilt.so": nil, - "vendor/foo/devkeys/test.x509.pem": nil, - "vendor/foo/devkeys/test.pk8": nil, - "testkey.x509.pem": nil, - "testkey.pk8": nil, - "testkey.override.x509.pem": nil, - "testkey.override.pk8": nil, - "vendor/foo/devkeys/testkey.avbpubkey": nil, - "vendor/foo/devkeys/testkey.pem": nil, - "NOTICE": nil, - "custom_notice": nil, - "custom_notice_for_static_lib": nil, - "testkey2.avbpubkey": nil, - "testkey2.pem": nil, - "myapex-arm64.apex": nil, - "myapex-arm.apex": nil, - "myapex.apks": nil, - "frameworks/base/api/current.txt": nil, - "framework/aidl/a.aidl": nil, - "build/make/core/proguard.flags": nil, - "build/make/core/proguard_basic_keeps.flags": nil, - "dummy.txt": nil, - "baz": nil, - "bar/baz": nil, - "testdata/baz": nil, - "AppSet.apks": nil, - "foo.rs": nil, - "libfoo.jar": nil, - "libbar.jar": nil, - } - - cc.GatherRequiredFilesForTest(fs) - - for _, handler := range handlers { - // The fs now needs to be populated before creating the config, call handlers twice - // for now, once to get any fs changes, and later after the config was created to - // set product variables or targets. - tempConfig := android.TestArchConfig(buildDir, nil, bp, fs) - handler(fs, tempConfig) - } - - config := android.TestArchConfig(buildDir, nil, bp, fs) - config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current") - config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test") - config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"} - config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q") - config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false) - config.TestProductVariables.Platform_version_active_codenames = []string{"Q"} - config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER") - - for _, handler := range handlers { - // The fs now needs to be populated before creating the config, call handlers twice - // for now, earlier to get any fs changes, and now after the config was created to - // set product variables or targets. - tempFS := map[string][]byte{} - handler(tempFS, config) - } - - ctx := android.NewTestArchContext(config) - - // from android package - android.RegisterPackageBuildComponents(ctx) - ctx.PreArchMutators(android.RegisterVisibilityRuleChecker) - - registerApexBuildComponents(ctx) - registerApexKeyBuildComponents(ctx) - - ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) - ctx.PreArchMutators(android.RegisterComponentsMutator) - - android.RegisterPrebuiltMutators(ctx) - - // Register these after the prebuilt mutators have been registered to match what - // happens at runtime. - ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer) - ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer) - - // These must come after prebuilts and visibility rules to match runtime. - ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators) - - // These must come after override rules to match the runtime. - cc.RegisterRequiredBuildComponentsForTest(ctx) - rust.RegisterRequiredBuildComponentsForTest(ctx) - java.RegisterRequiredBuildComponentsForTest(ctx) - - ctx.RegisterModuleType("cc_test", cc.TestFactory) - ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory) - cc.RegisterVndkLibraryTxtTypes(ctx) - prebuilt_etc.RegisterPrebuiltEtcBuildComponents(ctx) - ctx.RegisterModuleType("platform_compat_config", java.PlatformCompatConfigFactory) - ctx.RegisterModuleType("sh_binary", sh.ShBinaryFactory) - ctx.RegisterModuleType("filegroup", android.FileGroupFactory) - ctx.RegisterModuleType("bpf", bpf.BpfFactory) - - ctx.Register() - - return ctx, config -} - func setUp() { var err error buildDir, err = ioutil.TempDir("", "soong_apex_test") @@ -1139,11 +990,13 @@ func TestApex_PlatformUsesLatestStubFromApex(t *testing.T) { srcs: ["mylib.cpp"], shared_libs: ["libstub"], } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Z") - config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false) - config.TestProductVariables.Platform_version_active_codenames = []string{"Z"} - }) + `, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_sdk_codename = proptools.StringPtr("Z") + variables.Platform_sdk_final = proptools.BoolPtr(false) + variables.Platform_version_active_codenames = []string{"Z"} + }), + ) // Ensure that mylib from myapex is built against the latest stub (current) mylibCflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] @@ -1333,7 +1186,7 @@ var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers( ) func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) { - result := emptyFixtureFactory.Extend(prepareForTestOfRuntimeApexWithHwasan).RunTestWithBp(t, ` + result := android.GroupFixturePreparers(prepareForTestOfRuntimeApexWithHwasan).RunTestWithBp(t, ` cc_library { name: "libc", no_libcrt: true, @@ -1379,7 +1232,7 @@ func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) { } func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) { - result := emptyFixtureFactory.Extend( + result := android.GroupFixturePreparers( prepareForTestOfRuntimeApexWithHwasan, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.SanitizeDevice = []string{"hwaddress"} @@ -1491,9 +1344,10 @@ func TestApexDependsOnLLNDKTransitively(t *testing.T) { name: "libbar.llndk", symbol_file: "", } - `, func(fs map[string][]byte, config android.Config) { - setUseVendorAllowListForTest(config, []string{"myapex"}) - }, withUnbundledBuild) + `, + setUseVendorAllowListForTest([]string{"myapex"}), + withUnbundledBuild, + ) // Ensure that LLNDK dep is not included ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ @@ -1727,9 +1581,11 @@ func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) { versions: ["29", "R"], }, } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.Platform_version_active_codenames = []string{"R"} - }) + `, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_version_active_codenames = []string{"R"} + }), + ) expectLink := func(from, from_variant, to, to_variant string) { ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] @@ -1838,6 +1694,12 @@ func TestPlatformUsesLatestStubsFromApexes(t *testing.T) { expectNoLink("libz", "shared", "libz", "shared") } +var prepareForTestWithSantitizeHwaddress = android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.SanitizeDevice = []string{"hwaddress"} + }, +) + func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) { ctx := testApex(t, ` apex { @@ -1866,9 +1728,9 @@ func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) { versions: ["29", "30"], }, } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.SanitizeDevice = []string{"hwaddress"} - }) + `, + prepareForTestWithSantitizeHwaddress, + ) expectLink := func(from, from_variant, to, to_variant string) { ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld") libFlags := ld.Args["libFlags"] @@ -2261,10 +2123,12 @@ func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion } func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) { - withSAsActiveCodeNames := func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("S") - config.TestProductVariables.Platform_version_active_codenames = []string{"S"} - } + withSAsActiveCodeNames := android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.Platform_sdk_codename = proptools.StringPtr("S") + variables.Platform_version_active_codenames = []string{"S"} + }, + ) testApexError(t, `libbar.*: should support min_sdk_version\(S\)`, ` apex { name: "myapex", @@ -2291,10 +2155,10 @@ func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) { } func TestApexMinSdkVersion_WorksWithActiveCodenames(t *testing.T) { - withSAsActiveCodeNames := func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("S") - config.TestProductVariables.Platform_version_active_codenames = []string{"S", "T"} - } + withSAsActiveCodeNames := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_sdk_codename = proptools.StringPtr("S") + variables.Platform_version_active_codenames = []string{"S", "T"} + }) ctx := testApex(t, ` apex { name: "myapex", @@ -2484,9 +2348,9 @@ func TestUseVendor(t *testing.T) { stl: "none", apex_available: [ "myapex" ], } - `, func(fs map[string][]byte, config android.Config) { - setUseVendorAllowListForTest(config, []string{"myapex"}) - }) + `, + setUseVendorAllowListForTest([]string{"myapex"}), + ) inputsList := []string{} for _, i := range ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().BuildParamsForTests() { @@ -2517,9 +2381,9 @@ func TestUseVendorNotAllowedForSystemApexes(t *testing.T) { public_key: "testkey.avbpubkey", private_key: "testkey.pem", } - `, func(fs map[string][]byte, config android.Config) { - setUseVendorAllowListForTest(config, []string{""}) - }) + `, + setUseVendorAllowListForTest([]string{""}), + ) // no error with allow list testApex(t, ` apex { @@ -2533,9 +2397,9 @@ func TestUseVendorNotAllowedForSystemApexes(t *testing.T) { public_key: "testkey.avbpubkey", private_key: "testkey.pem", } - `, func(fs map[string][]byte, config android.Config) { - setUseVendorAllowListForTest(config, []string{"myapex"}) - }) + `, + setUseVendorAllowListForTest([]string{"myapex"}), + ) } func TestUseVendorFailsIfNotVendorAvailable(t *testing.T) { @@ -2650,7 +2514,7 @@ func TestVendorApex_use_vndk_as_stable(t *testing.T) { libs := names(ldRule.Args["libFlags"]) // VNDK libs(libvndk/libc++) as they are ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so") - ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so") + ensureListContains(t, libs, buildDir+"/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"libc++/"+vendorVariant+"_shared/libc++.so") // non-stable Vendor libs as APEX variants ensureListContains(t, libs, buildDir+"/.intermediates/libvendor/"+vendorVariant+"_shared_apex10000/libvendor.so") @@ -2687,9 +2551,10 @@ func TestProductVariant(t *testing.T) { apex_available: ["myapex"], srcs: ["foo.cpp"], } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.ProductVndkVersion = proptools.StringPtr("current") - }) + `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.ProductVndkVersion = proptools.StringPtr("current") + }), + ) cflags := strings.Fields( ctx.ModuleForTests("foo", "android_product.VER_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"]) @@ -2757,9 +2622,9 @@ func TestAndroidMk_UseVendorRequired(t *testing.T) { vendor_available: true, apex_available: ["myapex"], } - `, func(fs map[string][]byte, config android.Config) { - setUseVendorAllowListForTest(config, []string{"myapex"}) - }) + `, + setUseVendorAllowListForTest([]string{"myapex"}), + ) apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) data := android.AndroidMkDataForTest(t, ctx, apexBundle) @@ -5053,9 +4918,11 @@ func TestInstallExtraFlattenedApexes(t *testing.T) { public_key: "testkey.avbpubkey", private_key: "testkey.pem", } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.InstallExtraFlattenedApexes = proptools.BoolPtr(true) - }) + `, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.InstallExtraFlattenedApexes = proptools.BoolPtr(true) + }), + ) ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle) ensureListContains(t, ab.requiredDeps, "myapex.flattened") mk := android.AndroidMkDataForTest(t, ctx, ab) @@ -5746,7 +5613,7 @@ func TestLegacyAndroid10Support(t *testing.T) { } } -var filesForSdkLibrary = map[string][]byte{ +var filesForSdkLibrary = android.MockFS{ "api/current.txt": nil, "api/removed.txt": nil, "api/system-current.txt": nil, @@ -6368,10 +6235,12 @@ func TestApexMutatorsDontRunIfDisabled(t *testing.T) { public_key: "testkey.avbpubkey", private_key: "testkey.pem", } - `, func(fs map[string][]byte, config android.Config) { - delete(config.Targets, android.Android) - config.AndroidCommonTarget = android.Target{} - }) + `, + android.FixtureModifyConfig(func(config android.Config) { + delete(config.Targets, android.Android) + config.AndroidCommonTarget = android.Target{} + }), + ) if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) { t.Errorf("Expected variants: %v, but got: %v", expected, got) @@ -6443,7 +6312,7 @@ func TestAppSetBundle(t *testing.T) { } func TestAppSetBundlePrebuilt(t *testing.T) { - ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) { + ctx := testApex(t, "", android.FixtureModifyMockFS(func(fs android.MockFS) { bp := ` apex_set { name: "myapex", @@ -6454,9 +6323,9 @@ func TestAppSetBundlePrebuilt(t *testing.T) { }, }` fs["Android.bp"] = []byte(bp) - - config.TestProductVariables.SanitizeDevice = []string{"hwaddress"} - }) + }), + prepareForTestWithSantitizeHwaddress, + ) m := ctx.ModuleForTests("myapex", "android_common") extractedApex := m.Output(buildDir + "/.intermediates/myapex/android_common/foo_v2.apex") @@ -7021,13 +6890,17 @@ func TestApexSet(t *testing.T) { filename: "foo_v2.apex", overrides: ["foo"], } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.Platform_sdk_version = intPtr(30) - config.Targets[android.Android] = []android.Target{ - {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}}, - {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}}, - } - }) + `, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_sdk_version = intPtr(30) + }), + android.FixtureModifyConfig(func(config android.Config) { + config.Targets[android.Android] = []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}}, + } + }), + ) m := ctx.ModuleForTests("myapex", "android_common") @@ -7235,9 +7108,11 @@ func TestCompressedApex(t *testing.T) { public_key: "testkey.avbpubkey", private_key: "testkey.pem", } - `, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.CompressedApex = proptools.BoolPtr(true) - }) + `, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.CompressedApex = proptools.BoolPtr(true) + }), + ) compressRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("compressRule") ensureContains(t, compressRule.Output.String(), "myapex.capex.unsigned") diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go index 2e6ed824e..7e37e4229 100644 --- a/apex/boot_image_test.go +++ b/apex/boot_image_test.go @@ -15,7 +15,6 @@ package apex import ( - "reflect" "strings" "testing" @@ -28,7 +27,18 @@ import ( // modules from the ART apex. func TestBootImages(t *testing.T) { - ctx := testApex(t, ` + result := apexFixtureFactory.Extend( + // Configure some libraries in the art and framework boot images. + dexpreopt.FixtureSetArtBootJars("com.android.art:baz", "com.android.art:quuz"), + dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar"), + filesForSdkLibrary.AddToFixture(), + // Some additional files needed for the art apex. + android.FixtureMergeMockFs(android.MockFS{ + "com.android.art.avbpubkey": nil, + "com.android.art.pem": nil, + "system/sepolicy/apex/com.android.art-file_contexts": nil, + }), + ).RunTestWithBp(t, ` java_sdk_library { name: "foo", srcs: ["b.java"], @@ -83,20 +93,10 @@ func TestBootImages(t *testing.T) { image_name: "boot", } `, - // Configure some libraries in the art and framework boot images. - withArtBootImageJars("com.android.art:baz", "com.android.art:quuz"), - withFrameworkBootImageJars("platform:foo", "platform:bar"), - withFiles(filesForSdkLibrary), - // Some additional files needed for the art apex. - withFiles(map[string][]byte{ - "com.android.art.avbpubkey": nil, - "com.android.art.pem": nil, - "system/sepolicy/apex/com.android.art-file_contexts": nil, - }), ) // Make sure that the framework-boot-image is using the correct configuration. - checkBootImage(t, ctx, "framework-boot-image", "platform:foo,platform:bar", ` + checkBootImage(t, result, "framework-boot-image", "platform:foo,platform:bar", ` test_device/dex_bootjars/android/system/framework/arm/boot-foo.art test_device/dex_bootjars/android/system/framework/arm/boot-foo.oat test_device/dex_bootjars/android/system/framework/arm/boot-foo.vdex @@ -112,7 +112,7 @@ test_device/dex_bootjars/android/system/framework/arm64/boot-bar.vdex `) // Make sure that the art-boot-image is using the correct configuration. - checkBootImage(t, ctx, "art-boot-image", "com.android.art:baz,com.android.art:quuz", ` + checkBootImage(t, result, "art-boot-image", "com.android.art:baz,com.android.art:quuz", ` test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex @@ -128,16 +128,14 @@ test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-quuz.vde `) } -func checkBootImage(t *testing.T, ctx *android.TestContext, moduleName string, expectedConfiguredModules string, expectedBootImageFiles string) { +func checkBootImage(t *testing.T, result *android.TestResult, moduleName string, expectedConfiguredModules string, expectedBootImageFiles string) { t.Helper() - bootImage := ctx.ModuleForTests(moduleName, "android_common").Module().(*java.BootImageModule) + bootImage := result.ModuleForTests(moduleName, "android_common").Module().(*java.BootImageModule) - bootImageInfo := ctx.ModuleProvider(bootImage, java.BootImageInfoProvider).(java.BootImageInfo) + bootImageInfo := result.ModuleProvider(bootImage, java.BootImageInfoProvider).(java.BootImageInfo) modules := bootImageInfo.Modules() - if actual := modules.String(); actual != expectedConfiguredModules { - t.Errorf("invalid modules for %s: expected %q, actual %q", moduleName, expectedConfiguredModules, actual) - } + android.AssertStringEquals(t, "invalid modules for "+moduleName, expectedConfiguredModules, modules.String()) // Get a list of all the paths in the boot image sorted by arch type. allPaths := []string{} @@ -149,39 +147,15 @@ func checkBootImage(t *testing.T, ctx *android.TestContext, moduleName string, e } } } - if expected, actual := strings.TrimSpace(expectedBootImageFiles), strings.TrimSpace(strings.Join(allPaths, "\n")); !reflect.DeepEqual(expected, actual) { - t.Errorf("invalid paths for %s: expected \n%s, actual \n%s", moduleName, expected, actual) - } -} -func modifyDexpreoptConfig(configModifier func(dexpreoptConfig *dexpreopt.GlobalConfig)) func(fs map[string][]byte, config android.Config) { - return func(fs map[string][]byte, config android.Config) { - // Initialize the dexpreopt GlobalConfig to an empty structure. This has no effect if it has - // already been set. - pathCtx := android.PathContextForTesting(config) - dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx) - dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig) - - // Retrieve the existing configuration and modify it. - dexpreoptConfig = dexpreopt.GetGlobalConfig(pathCtx) - configModifier(dexpreoptConfig) - } -} - -func withArtBootImageJars(bootJars ...string) func(fs map[string][]byte, config android.Config) { - return modifyDexpreoptConfig(func(dexpreoptConfig *dexpreopt.GlobalConfig) { - dexpreoptConfig.ArtApexJars = android.CreateTestConfiguredJarList(bootJars) - }) -} - -func withFrameworkBootImageJars(bootJars ...string) func(fs map[string][]byte, config android.Config) { - return modifyDexpreoptConfig(func(dexpreoptConfig *dexpreopt.GlobalConfig) { - dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList(bootJars) - }) + android.AssertTrimmedStringEquals(t, "invalid paths for "+moduleName, expectedBootImageFiles, strings.Join(allPaths, "\n")) } func TestBootImageInApex(t *testing.T) { - ctx := testApex(t, ` + result := apexFixtureFactory.Extend( + // Configure some libraries in the framework boot image. + dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar"), + ).RunTestWithBp(t, ` apex { name: "myapex", key: "myapex.key", @@ -216,12 +190,9 @@ func TestBootImageInApex(t *testing.T) { "myapex", ], } -`, - // Configure some libraries in the framework boot image. - withFrameworkBootImageJars("platform:foo", "platform:bar"), - ) + `) - ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ + ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{ "javalib/arm/boot-bar.art", "javalib/arm/boot-bar.oat", "javalib/arm/boot-bar.vdex", diff --git a/apex/vndk_test.go b/apex/vndk_test.go index 34b940896..015283dee 100644 --- a/apex/vndk_test.go +++ b/apex/vndk_test.go @@ -48,9 +48,11 @@ func TestVndkApexForVndkLite(t *testing.T) { stl: "none", apex_available: [ "com.android.vndk.current" ], } - `+vndkLibrariesTxtFiles("current"), func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("") - }) + `+vndkLibrariesTxtFiles("current"), + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.DeviceVndkVersion = proptools.StringPtr("") + }), + ) // VNDK-Lite contains only core variants of VNDK-Sp libraries ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{ "lib/libvndksp.so", @@ -113,20 +115,24 @@ func TestVndkApexUsesVendorVariant(t *testing.T) { }) t.Run("VNDK APEX gathers only vendor variants even if product variants are available", func(t *testing.T) { - ctx := testApex(t, bp, func(fs map[string][]byte, config android.Config) { - // Now product variant is available - config.TestProductVariables.ProductVndkVersion = proptools.StringPtr("current") - }) + ctx := testApex(t, bp, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + // Now product variant is available + variables.ProductVndkVersion = proptools.StringPtr("current") + }), + ) files := getFiles(t, ctx, "com.android.vndk.current", "android_common_image") ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.VER_arm_armv7-a-neon_shared/libfoo.so") }) t.Run("VNDK APEX supports coverage variants", func(t *testing.T) { - ctx := testApex(t, bp, func(fs map[string][]byte, config android.Config) { - config.TestProductVariables.GcovCoverage = proptools.BoolPtr(true) - config.TestProductVariables.Native_coverage = proptools.BoolPtr(true) - }) + ctx := testApex(t, bp, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.GcovCoverage = proptools.BoolPtr(true) + variables.Native_coverage = proptools.BoolPtr(true) + }), + ) files := getFiles(t, ctx, "com.android.vndk.current", "android_common_image") ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.VER_arm_armv7-a-neon_shared/libfoo.so") diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go index 1d4e32221..1c058ba3e 100644 --- a/bp2build/cc_object_conversion_test.go +++ b/bp2build/cc_object_conversion_test.go @@ -70,6 +70,7 @@ func TestCcObjectBp2Build(t *testing.T) { ], local_include_dirs = [ "include", + ".", ], srcs = [ "a/b/bar.h", @@ -120,6 +121,7 @@ cc_defaults { ], local_include_dirs = [ "include", + ".", ], srcs = [ "a/b/c.c", @@ -156,6 +158,9 @@ cc_object { copts = [ "-fno-addrsig", ], + local_include_dirs = [ + ".", + ], srcs = [ "x/y/z.c", ], @@ -167,6 +172,37 @@ cc_object { deps = [ ":bar", ], + local_include_dirs = [ + ".", + ], + srcs = [ + "a/b/c.c", + ], +)`, + }, + }, + { + description: "cc_object with include_build_dir: false", + moduleTypeUnderTest: "cc_object", + moduleTypeUnderTestFactory: cc.ObjectFactory, + moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build, + filesystem: map[string]string{ + "a/b/c.c": "", + "x/y/z.c": "", + }, + blueprint: `cc_object { + name: "foo", + srcs: ["a/b/c.c"], + include_build_directory: false, + + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTargets: []string{`cc_object( + name = "foo", + copts = [ + "-fno-addrsig", + ], srcs = [ "a/b/c.c", ], @@ -262,6 +298,9 @@ func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) { "//conditions:default": [ ], }), + local_include_dirs = [ + ".", + ], )`, }, }, @@ -310,6 +349,9 @@ func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) { "//conditions:default": [ ], }), + local_include_dirs = [ + ".", + ], )`, }, }, diff --git a/bpf/bpf_test.go b/bpf/bpf_test.go index 0bf15db75..51fbc15e1 100644 --- a/bpf/bpf_test.go +++ b/bpf/bpf_test.go @@ -26,8 +26,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -var bpfFactory = android.NewFixtureFactory( - nil, +var prepareForBpfTest = android.GroupFixturePreparers( cc.PrepareForTestWithCcDefaultModules, android.FixtureMergeMockFs( map[string][]byte{ @@ -53,7 +52,7 @@ func TestBpfDataDependency(t *testing.T) { } ` - bpfFactory.RunTestWithBp(t, bp) + prepareForBpfTest.RunTestWithBp(t, bp) // We only verify the above BP configuration is processed successfully since the data property // value is not available for testing from this package. diff --git a/cc/compiler.go b/cc/compiler.go index bcad1ad2e..b09b58e78 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -256,6 +256,10 @@ func (compiler *baseCompiler) compilerProps() []interface{} { return []interface{}{&compiler.Properties, &compiler.Proto} } +func (compiler *baseCompiler) includeBuildDirectory() bool { + return proptools.BoolDefault(compiler.Properties.Include_build_directory, true) +} + func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {} func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { @@ -332,8 +336,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps flags.Local.YasmFlags = append(flags.Local.YasmFlags, f) } - if compiler.Properties.Include_build_directory == nil || - *compiler.Properties.Include_build_directory { + if compiler.includeBuildDirectory() { flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+modulePath) flags.Local.YasmFlags = append(flags.Local.YasmFlags, "-I"+modulePath) } diff --git a/cc/config/global.go b/cc/config/global.go index cb7d17da4..7e809000a 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -144,8 +144,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r412851" - ClangDefaultShortVersion = "12.0.3" + ClangDefaultVersion = "clang-r416183" + ClangDefaultShortVersion = "12.0.4" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/object.go b/cc/object.go index f9e6d2df6..6bea28b5a 100644 --- a/cc/object.go +++ b/cc/object.go @@ -160,6 +160,10 @@ func ObjectBp2Build(ctx android.TopDownMutatorContext) { } } + if c, ok := m.compiler.(*baseCompiler); ok && c.includeBuildDirectory() { + localIncludeDirs = append(localIncludeDirs, ".") + } + var deps bazel.LabelList for _, props := range m.linker.linkerProps() { if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok { diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go index f800c48f2..9c3db3bfb 100644 --- a/etc/prebuilt_etc_test.go +++ b/etc/prebuilt_etc_test.go @@ -26,8 +26,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -var prebuiltEtcFixtureFactory = android.NewFixtureFactory( - nil, +var prepareForPrebuiltEtcTest = android.GroupFixturePreparers( android.PrepareForTestWithArchMutator, PrepareForTestWithPrebuiltEtc, android.FixtureMergeMockFs(android.MockFS{ @@ -38,7 +37,7 @@ var prebuiltEtcFixtureFactory = android.NewFixtureFactory( ) func TestPrebuiltEtcVariants(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc { name: "foo.conf", src: "foo.conf", @@ -72,7 +71,7 @@ func TestPrebuiltEtcVariants(t *testing.T) { } func TestPrebuiltEtcOutputPath(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc { name: "foo.conf", src: "foo.conf", @@ -85,7 +84,7 @@ func TestPrebuiltEtcOutputPath(t *testing.T) { } func TestPrebuiltEtcGlob(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc { name: "my_foo", src: "foo.*", @@ -105,7 +104,7 @@ func TestPrebuiltEtcGlob(t *testing.T) { } func TestPrebuiltEtcAndroidMk(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc { name: "foo", src: "foo.conf", @@ -139,7 +138,7 @@ func TestPrebuiltEtcAndroidMk(t *testing.T) { } func TestPrebuiltEtcRelativeInstallPathInstallDirPath(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc { name: "foo.conf", src: "foo.conf", @@ -153,7 +152,7 @@ func TestPrebuiltEtcRelativeInstallPathInstallDirPath(t *testing.T) { } func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) { - prebuiltEtcFixtureFactory. + prepareForPrebuiltEtcTest. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("relative_install_path is set. Cannot set sub_dir")). RunTestWithBp(t, ` prebuilt_etc { @@ -166,7 +165,7 @@ func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) { } func TestPrebuiltEtcHost(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_etc_host { name: "foo.conf", src: "foo.conf", @@ -181,7 +180,7 @@ func TestPrebuiltEtcHost(t *testing.T) { } func TestPrebuiltUserShareInstallDirPath(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_usr_share { name: "foo.conf", src: "foo.conf", @@ -195,7 +194,7 @@ func TestPrebuiltUserShareInstallDirPath(t *testing.T) { } func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_usr_share_host { name: "foo.conf", src: "foo.conf", @@ -210,7 +209,7 @@ func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) { } func TestPrebuiltFontInstallDirPath(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, ` + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, ` prebuilt_font { name: "foo.conf", src: "foo.conf", @@ -249,7 +248,7 @@ func TestPrebuiltFirmwareDirPath(t *testing.T) { }} for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, tt.config) + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config) p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc) android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath) }) @@ -283,7 +282,7 @@ func TestPrebuiltDSPDirPath(t *testing.T) { }} for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { - result := prebuiltEtcFixtureFactory.RunTestWithBp(t, tt.config) + result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config) p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc) android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath) }) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 8974eba4f..b2bd6bddf 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -91,7 +91,7 @@ func filesystemFactory() android.Module { var dependencyTag = struct { blueprint.BaseDependencyTag - android.InstallAlwaysNeededDependencyTag + android.PackagingItemAlwaysDepTag }{} func (f *filesystem) DepsMutator(ctx android.BottomUpMutatorContext) { diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go index 199a7df7b..bb17e8e05 100644 --- a/genrule/genrule_test.go +++ b/genrule/genrule_test.go @@ -28,8 +28,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -var genruleFixtureFactory = android.NewFixtureFactory( - nil, +var prepareForGenRuleTest = android.GroupFixturePreparers( android.PrepareForTestWithArchMutator, android.PrepareForTestWithDefaults, @@ -447,7 +446,8 @@ func TestGenruleCmd(t *testing.T) { expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err)) } - result := genruleFixtureFactory.Extend( + result := android.GroupFixturePreparers( + prepareForGenRuleTest, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.Allow_missing_dependencies = proptools.BoolPtr(test.allowMissingDependencies) }), @@ -523,7 +523,7 @@ func TestGenruleHashInputs(t *testing.T) { }, } - result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp) + result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp) for _, test := range testcases { t.Run(test.name, func(t *testing.T) { @@ -605,7 +605,7 @@ func TestGenSrcs(t *testing.T) { expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err)) } - result := genruleFixtureFactory. + result := prepareForGenRuleTest. ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)). RunTestWithBp(t, testGenruleBp()+bp) @@ -642,7 +642,7 @@ func TestGenruleDefaults(t *testing.T) { } ` - result := genruleFixtureFactory.RunTestWithBp(t, testGenruleBp()+bp) + result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp) gen := result.Module("gen", "").(*Module) @@ -662,11 +662,12 @@ func TestGenruleWithBazel(t *testing.T) { } ` - result := genruleFixtureFactory.Extend(android.FixtureModifyConfig(func(config android.Config) { - config.BazelContext = android.MockBazelContext{ - AllFiles: map[string][]string{ - "//foo/bar:bar": []string{"bazelone.txt", "bazeltwo.txt"}}} - })).RunTestWithBp(t, testGenruleBp()+bp) + result := android.GroupFixturePreparers( + prepareForGenRuleTest, android.FixtureModifyConfig(func(config android.Config) { + config.BazelContext = android.MockBazelContext{ + AllFiles: map[string][]string{ + "//foo/bar:bar": []string{"bazelone.txt", "bazeltwo.txt"}}} + })).RunTestWithBp(t, testGenruleBp()+bp) gen := result.Module("foo", "").(*Module) diff --git a/java/aar.go b/java/aar.go index 554ea670b..67b9ef019 100644 --- a/java/aar.go +++ b/java/aar.go @@ -40,15 +40,14 @@ type AndroidLibraryDependency interface { func init() { RegisterAARBuildComponents(android.InitRegistrationContext) - - android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel() - }) } func RegisterAARBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_library_import", AARImportFactory) ctx.RegisterModuleType("android_library", AndroidLibraryFactory) + ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel() + }) } // diff --git a/java/android_resources.go b/java/android_resources.go index 4d420cfed..6864ebb90 100644 --- a/java/android_resources.go +++ b/java/android_resources.go @@ -22,8 +22,11 @@ import ( ) func init() { - android.RegisterPreSingletonType("overlay", OverlaySingletonFactory) + registerOverlayBuildComponents(android.InitRegistrationContext) +} +func registerOverlayBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterPreSingletonType("overlay", OverlaySingletonFactory) } var androidResourceIgnoreFilenames = []string{ diff --git a/java/java_test.go b/java/java_test.go index 99a96e121..d27a73d30 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -48,20 +48,34 @@ func tearDown() { os.RemoveAll(buildDir) } -var emptyFixtureFactory = android.NewFixtureFactory(&buildDir) +// Legacy factory to use to create fixtures for tests in this package. +// +// deprecated: See prepareForJavaTest +var javaFixtureFactory = android.NewFixtureFactory( + &buildDir, + prepareForJavaTest, +) -// Factory to use to create fixtures for tests in this package. -var javaFixtureFactory = emptyFixtureFactory.Extend( +// Legacy preparer used for running tests within the java package. +// +// This includes everything that was needed to run any test in the java package prior to the +// introduction of the test fixtures. Tests that are being converted to use fixtures directly +// rather than through the testJava...() methods should avoid using this and instead use the +// various preparers directly, using android.GroupFixturePreparers(...) to group them when +// necessary. +// +// deprecated +var prepareForJavaTest = android.GroupFixturePreparers( genrule.PrepareForTestWithGenRuleBuildComponents, // Get the CC build components but not default modules. cc.PrepareForTestWithCcBuildComponents, // Include all the default java modules. PrepareForTestWithJavaDefaultModules, + PrepareForTestWithOverlayBuildComponents, python.PrepareForTestWithPythonBuildComponents, android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { ctx.RegisterModuleType("java_plugin", PluginFactory) - ctx.RegisterPreSingletonType("overlay", OverlaySingletonFactory) ctx.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory) }), dexpreopt.PrepareForTestWithDexpreopt, @@ -112,10 +126,6 @@ func testContext(config android.Config) *android.TestContext { // Register module types and mutators from cc needed for JNI testing cc.RegisterRequiredBuildComponentsForTest(ctx) - ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel() - }) - return ctx } diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 3c43a8e55..03e82c2a8 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -15,12 +15,23 @@ package java import ( + "path/filepath" + "android/soong/android" + "github.com/google/blueprint" + "fmt" ) func init() { registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext) + + android.RegisterSdkMemberType(&compatConfigMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "compat_configs", + SupportsSdk: true, + }, + }) } func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) { @@ -42,6 +53,7 @@ type platformCompatConfigProperties struct { type platformCompatConfig struct { android.ModuleBase + android.SdkBase properties platformCompatConfigProperties installDirPath android.InstallPath @@ -113,10 +125,54 @@ func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries { func PlatformCompatConfigFactory() android.Module { module := &platformCompatConfig{} module.AddProperties(&module.properties) + android.InitSdkAwareModule(module) android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) return module } +type compatConfigMemberType struct { + android.SdkMemberTypeBase +} + +func (b *compatConfigMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { + mctx.AddVariationDependencies(nil, dependencyTag, names...) +} + +func (b *compatConfigMemberType) IsInstance(module android.Module) bool { + _, ok := module.(*platformCompatConfig) + return ok +} + +func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { + return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_platform_compat_config") +} + +func (b *compatConfigMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { + return &compatConfigSdkMemberProperties{} +} + +type compatConfigSdkMemberProperties struct { + android.SdkMemberPropertiesBase + + Metadata android.Path +} + +func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { + module := variant.(*platformCompatConfig) + b.Metadata = module.metadataFile +} + +func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { + builder := ctx.SnapshotBuilder() + if b.Metadata != nil { + snapshotRelativePath := filepath.Join("compat_configs", ctx.Name(), b.Metadata.Base()) + builder.CopyToSnapshot(b.Metadata, snapshotRelativePath) + propertySet.AddProperty("metadata", snapshotRelativePath) + } +} + +var _ android.SdkMemberType = (*compatConfigMemberType)(nil) + // A prebuilt version of the platform compat config module. type prebuiltCompatConfigModule struct { android.ModuleBase diff --git a/java/platform_compat_config_test.go b/java/platform_compat_config_test.go index 0c5d001ac..80d991c49 100644 --- a/java/platform_compat_config_test.go +++ b/java/platform_compat_config_test.go @@ -21,7 +21,7 @@ import ( ) func TestPlatformCompatConfig(t *testing.T) { - result := emptyFixtureFactory.RunTest(t, + result := android.GroupFixturePreparers( PrepareForTestWithPlatformCompatConfig, android.FixtureWithRootAndroidBp(` platform_compat_config { @@ -34,20 +34,11 @@ func TestPlatformCompatConfig(t *testing.T) { name: "myconfig3", } `), - ) + ).RunTest(t) - checkMergedCompatConfigInputs(t, result, "myconfig", + CheckMergedCompatConfigInputs(t, result, "myconfig", "out/soong/.intermediates/myconfig1/myconfig1_meta.xml", "out/soong/.intermediates/myconfig2/myconfig2_meta.xml", "out/soong/.intermediates/myconfig3/myconfig3_meta.xml", ) } - -// Check that the merged file create by platform_compat_config_singleton has the correct inputs. -func checkMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) { - sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton") - allOutputs := sourceGlobalCompatConfig.AllOutputs() - android.AssertIntEquals(t, message+": output len", 1, len(allOutputs)) - output := sourceGlobalCompatConfig.Output(allOutputs[0]) - android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits) -} diff --git a/java/testing.go b/java/testing.go index 4b8b84924..b0290dc3d 100644 --- a/java/testing.go +++ b/java/testing.go @@ -54,6 +54,8 @@ var PrepareForTestWithJavaDefaultModules = android.GroupFixturePreparers( android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", GatherRequiredDepsForTest()), ) +var PrepareForTestWithOverlayBuildComponents = android.FixtureRegisterWithContext(registerOverlayBuildComponents) + // Prepare a fixture to use all java module types, mutators and singletons fully. // // This should only be used by tests that want to run with as much of the build enabled as possible. @@ -319,3 +321,12 @@ func CheckHiddenAPIRuleInputs(t *testing.T, expected string, hiddenAPIRule andro t.Errorf("Expected hiddenapi rule inputs:\n%s\nactual inputs:\n%s", expected, actual) } } + +// Check that the merged file create by platform_compat_config_singleton has the correct inputs. +func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) { + sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton") + allOutputs := sourceGlobalCompatConfig.AllOutputs() + android.AssertIntEquals(t, message+": output len", 1, len(allOutputs)) + output := sourceGlobalCompatConfig.Output(allOutputs[0]) + android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits) +} diff --git a/python/python_test.go b/python/python_test.go index 6263c8a25..f57f504d7 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -335,13 +335,12 @@ func TestPythonModule(t *testing.T) { } t.Run(d.desc, func(t *testing.T) { - result := emptyFixtureFactory. - ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(errorPatterns)). - RunTest(t, - android.PrepareForTestWithDefaults, - PrepareForTestWithPythonBuildComponents, - d.mockFiles.AddToFixture(), - ) + result := android.GroupFixturePreparers( + android.PrepareForTestWithDefaults, + PrepareForTestWithPythonBuildComponents, + d.mockFiles.AddToFixture(), + ).ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(errorPatterns)). + RunTest(t) if len(result.Errs) > 0 { return @@ -376,8 +375,6 @@ func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expecte android.AssertPathsRelativeToTopEquals(t, "depsSrcsZips", expectedDepsSrcsZips, base.depsSrcsZips) } -var emptyFixtureFactory = android.NewFixtureFactory(nil) - func TestMain(m *testing.M) { os.Exit(m.Run()) } diff --git a/rust/clippy_test.go b/rust/clippy_test.go index e24f666df..e90564f63 100644 --- a/rust/clippy_test.go +++ b/rust/clippy_test.go @@ -66,7 +66,7 @@ func TestClippy(t *testing.T) { for _, tc := range clippyLintTests { t.Run("path="+tc.modulePath, func(t *testing.T) { - config := android.TestArchConfig(buildDir, nil, bp, fs) + config := android.TestArchConfig(t.TempDir(), nil, bp, fs) ctx := CreateTestContext(config) ctx.Register() _, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"}) diff --git a/rust/compiler_test.go b/rust/compiler_test.go index 2b40727e7..3ed086f20 100644 --- a/rust/compiler_test.go +++ b/rust/compiler_test.go @@ -153,7 +153,7 @@ func TestLints(t *testing.T) { for _, tc := range lintTests { t.Run("path="+tc.modulePath, func(t *testing.T) { - config := android.TestArchConfig(buildDir, nil, bp, fs) + config := android.TestArchConfig(t.TempDir(), nil, bp, fs) ctx := CreateTestContext(config) ctx.Register() _, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"}) diff --git a/rust/project_json_test.go b/rust/project_json_test.go index 289bcb81d..8f64f56e2 100644 --- a/rust/project_json_test.go +++ b/rust/project_json_test.go @@ -27,15 +27,14 @@ import ( // testProjectJson run the generation of rust-project.json. It returns the raw // content of the generated file. func testProjectJson(t *testing.T, bp string) []byte { - tctx := newTestRustCtx(t, bp) - tctx.env = map[string]string{"SOONG_GEN_RUST_PROJECT": "1"} - tctx.generateConfig() - tctx.parse(t) + result := prepareForRustTest. + Extend(android.FixtureMergeEnv(map[string]string{"SOONG_GEN_RUST_PROJECT": "1"})). + RunTestWithBp(t, bp) // The JSON file is generated via WriteFileToOutputDir. Therefore, it // won't appear in the Output of the TestingSingleton. Manually verify // it exists. - content, err := ioutil.ReadFile(filepath.Join(buildDir, rustProjectJsonFileName)) + content, err := ioutil.ReadFile(filepath.Join(result.Config.BuildDir(), rustProjectJsonFileName)) if err != nil { t.Errorf("rust-project.json has not been generated") } diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go index 1ac66f388..f0f5ec0e9 100644 --- a/rust/protobuf_test.go +++ b/rust/protobuf_test.go @@ -101,7 +101,7 @@ func TestRustGrpc(t *testing.T) { } // Check that we're including the exported directory from libprotobuf-cpp-full - if w := "-Ilibprotobuf-cpp-full-includes"; !strings.Contains(cmd, w) { + if w := "-I" + rustDefaultsDir + "libprotobuf-cpp-full-includes"; !strings.Contains(cmd, w) { t.Errorf("expected %q in %q", w, cmd) } diff --git a/rust/rust_test.go b/rust/rust_test.go index a0ed5345f..bed28ec8f 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -15,7 +15,6 @@ package rust import ( - "io/ioutil" "os" "runtime" "strings" @@ -24,72 +23,94 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" - "android/soong/cc" + "android/soong/genrule" ) -var ( - buildDir string -) - -func setUp() { - var err error - buildDir, err = ioutil.TempDir("", "soong_rust_test") - if err != nil { - panic(err) - } +func TestMain(m *testing.M) { + os.Exit(m.Run()) } -func tearDown() { - os.RemoveAll(buildDir) -} +var prepareForRustTest = android.GroupFixturePreparers( + android.PrepareForTestWithArchMutator, + android.PrepareForTestWithDefaults, + android.PrepareForTestWithPrebuilts, -func TestMain(m *testing.M) { - run := func() int { - setUp() - defer tearDown() + genrule.PrepareForTestWithGenRuleBuildComponents, - return m.Run() - } + PrepareForIntegrationTestWithRust, +) - os.Exit(run()) +var rustMockedFiles = android.MockFS{ + "foo.rs": nil, + "foo.c": nil, + "src/bar.rs": nil, + "src/any.h": nil, + "proto.proto": nil, + "proto/buf.proto": nil, + "buf.proto": nil, + "foo.proto": nil, + "liby.so": nil, + "libz.so": nil, + "data.txt": nil, } // testRust returns a TestContext in which a basic environment has been setup. -// This environment contains a few mocked files. See testRustCtx.useMockedFs -// for the list of these files. +// This environment contains a few mocked files. See rustMockedFiles for the list of these files. func testRust(t *testing.T, bp string) *android.TestContext { - tctx := newTestRustCtx(t, bp) - tctx.useMockedFs() - tctx.generateConfig() - return tctx.parse(t) + skipTestIfOsNotSupported(t) + result := android.GroupFixturePreparers( + prepareForRustTest, + rustMockedFiles.AddToFixture(), + ). + RunTestWithBp(t, bp) + return result.TestContext } func testRustVndk(t *testing.T, bp string) *android.TestContext { - tctx := newTestRustCtx(t, bp) - tctx.useMockedFs() - tctx.generateConfig() - tctx.setVndk(t) - return tctx.parse(t) + skipTestIfOsNotSupported(t) + result := android.GroupFixturePreparers( + prepareForRustTest, + rustMockedFiles.AddToFixture(), + android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.DeviceVndkVersion = StringPtr("current") + variables.ProductVndkVersion = StringPtr("current") + variables.Platform_vndk_version = StringPtr("VER") + }, + ), + ).RunTestWithBp(t, bp) + return result.TestContext } // testRustCov returns a TestContext in which a basic environment has been // setup. This environment explicitly enables coverage. func testRustCov(t *testing.T, bp string) *android.TestContext { - tctx := newTestRustCtx(t, bp) - tctx.useMockedFs() - tctx.generateConfig() - tctx.enableCoverage(t) - return tctx.parse(t) + skipTestIfOsNotSupported(t) + result := android.GroupFixturePreparers( + prepareForRustTest, + rustMockedFiles.AddToFixture(), + android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.ClangCoverage = proptools.BoolPtr(true) + variables.Native_coverage = proptools.BoolPtr(true) + variables.NativeCoveragePaths = []string{"*"} + }, + ), + ).RunTestWithBp(t, bp) + return result.TestContext } // testRustError ensures that at least one error was raised and its value // matches the pattern provided. The error can be either in the parsing of the // Blueprint or when generating the build actions. func testRustError(t *testing.T, pattern string, bp string) { - tctx := newTestRustCtx(t, bp) - tctx.useMockedFs() - tctx.generateConfig() - tctx.parseError(t, pattern) + skipTestIfOsNotSupported(t) + android.GroupFixturePreparers( + prepareForRustTest, + rustMockedFiles.AddToFixture(), + ). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). + RunTestWithBp(t, bp) } // testRustCtx is used to build a particular test environment. Unless your @@ -102,99 +123,11 @@ type testRustCtx struct { config *android.Config } -// newTestRustCtx returns a new testRustCtx for the Blueprint definition argument. -func newTestRustCtx(t *testing.T, bp string) *testRustCtx { +func skipTestIfOsNotSupported(t *testing.T) { // TODO (b/140435149) if runtime.GOOS != "linux" { t.Skip("Rust Soong tests can only be run on Linux hosts currently") } - return &testRustCtx{bp: bp} -} - -// useMockedFs setup a default mocked filesystem for the test environment. -func (tctx *testRustCtx) useMockedFs() { - tctx.fs = map[string][]byte{ - "foo.rs": nil, - "foo.c": nil, - "src/bar.rs": nil, - "src/any.h": nil, - "proto.proto": nil, - "proto/buf.proto": nil, - "buf.proto": nil, - "foo.proto": nil, - "liby.so": nil, - "libz.so": nil, - "data.txt": nil, - } -} - -// generateConfig creates the android.Config based on the bp, fs and env -// attributes of the testRustCtx. -func (tctx *testRustCtx) generateConfig() { - tctx.bp = tctx.bp + GatherRequiredDepsForTest() - tctx.bp = tctx.bp + cc.GatherRequiredDepsForTest(android.NoOsType) - cc.GatherRequiredFilesForTest(tctx.fs) - config := android.TestArchConfig(buildDir, tctx.env, tctx.bp, tctx.fs) - tctx.config = &config -} - -// enableCoverage configures the test to enable coverage. -func (tctx *testRustCtx) enableCoverage(t *testing.T) { - if tctx.config == nil { - t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.") - } - tctx.config.TestProductVariables.ClangCoverage = proptools.BoolPtr(true) - tctx.config.TestProductVariables.Native_coverage = proptools.BoolPtr(true) - tctx.config.TestProductVariables.NativeCoveragePaths = []string{"*"} -} - -func (tctx *testRustCtx) setVndk(t *testing.T) { - if tctx.config == nil { - t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.") - } - tctx.config.TestProductVariables.DeviceVndkVersion = StringPtr("current") - tctx.config.TestProductVariables.ProductVndkVersion = StringPtr("current") - tctx.config.TestProductVariables.Platform_vndk_version = StringPtr("VER") -} - -// parse validates the configuration and parses the Blueprint file. It returns -// a TestContext which can be used to retrieve the generated modules via -// ModuleForTests. -func (tctx testRustCtx) parse(t *testing.T) *android.TestContext { - if tctx.config == nil { - t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.") - } - ctx := CreateTestContext(*tctx.config) - ctx.Register() - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - android.FailIfErrored(t, errs) - _, errs = ctx.PrepareBuildActions(*tctx.config) - android.FailIfErrored(t, errs) - return ctx -} - -// parseError parses the Blueprint file and ensure that at least one error -// matching the provided pattern is observed. -func (tctx testRustCtx) parseError(t *testing.T, pattern string) { - if tctx.config == nil { - t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.") - } - ctx := CreateTestContext(*tctx.config) - ctx.Register() - - _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - if len(errs) > 0 { - android.FailIfNoMatchingErrors(t, pattern, errs) - return - } - - _, errs = ctx.PrepareBuildActions(*tctx.config) - if len(errs) > 0 { - android.FailIfNoMatchingErrors(t, pattern, errs) - return - } - - t.Fatalf("missing expected error %q (0 errors are returned)", pattern) } // Test that we can extract the link path from a lib path. diff --git a/scripts/strip.sh b/scripts/strip.sh index 5b7a6da7e..43e6cbf39 100755 --- a/scripts/strip.sh +++ b/scripts/strip.sh @@ -87,7 +87,7 @@ do_strip_keep_mini_debug_info() { comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols" echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty. "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo" - "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo" + "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --remove-section .rustc --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo" "${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo" "${XZ}" --block-size=64k --threads=0 "${outfile}.mini_debuginfo" diff --git a/scripts/update-apex-allowed-deps.sh b/scripts/update-apex-allowed-deps.sh deleted file mode 100755 index 872d74670..000000000 --- a/scripts/update-apex-allowed-deps.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -e -# -# The script to run locally to re-generate global allowed list of dependencies -# for updatable modules. - -if [ ! -e "build/envsetup.sh" ]; then - echo "ERROR: $0 must be run from the top of the tree" - exit 1 -fi - -source build/envsetup.sh > /dev/null || exit 1 - -readonly OUT_DIR=$(get_build_var OUT_DIR) - -readonly ALLOWED_DEPS_FILE="build/soong/apex/allowed_deps.txt" -readonly NEW_ALLOWED_DEPS_FILE="${OUT_DIR}/soong/apex/depsinfo/new-allowed-deps.txt" - -# If the script is run after droidcore failure, ${NEW_ALLOWED_DEPS_FILE} -# should already be built. If running the script manually, make sure it exists. -m "${NEW_ALLOWED_DEPS_FILE}" -j - -cat > "${ALLOWED_DEPS_FILE}" << EndOfFileComment -# A list of allowed dependencies for all updatable modules. -# -# The list tracks all direct and transitive dependencies that end up within any -# of the updatable binaries; specifically excluding external dependencies -# required to compile those binaries. This prevents potential regressions in -# case a new dependency is not aware of the different functional and -# non-functional requirements being part of an updatable module, for example -# setting correct min_sdk_version. -# -# To update the list, run: -# repo-root$ build/soong/scripts/update-apex-allowed-deps.sh -# -# See go/apex-allowed-deps-error for more details. -# TODO(b/157465465): introduce automated quality signals and remove this list. -EndOfFileComment - -cat "${NEW_ALLOWED_DEPS_FILE}" >> "${ALLOWED_DEPS_FILE}" diff --git a/sdk/Android.bp b/sdk/Android.bp index 6e49c6d5e..7b034e6de 100644 --- a/sdk/Android.bp +++ b/sdk/Android.bp @@ -23,6 +23,7 @@ bootstrap_go_package { "boot_image_sdk_test.go", "bp_test.go", "cc_sdk_test.go", + "compat_config_sdk_test.go", "exports_test.go", "java_sdk_test.go", "sdk_test.go", diff --git a/sdk/boot_image_sdk_test.go b/sdk/boot_image_sdk_test.go index 9805a6a90..5a03e346e 100644 --- a/sdk/boot_image_sdk_test.go +++ b/sdk/boot_image_sdk_test.go @@ -14,20 +14,27 @@ package sdk -import "testing" +import ( + "testing" + + "android/soong/android" +) func TestSnapshotWithBootImage(t *testing.T) { - result := testSdkWithJava(t, ` - sdk { - name: "mysdk", - boot_images: ["mybootimage"], - } + result := android.GroupFixturePreparers( + prepareForSdkTestWithJava, + android.FixtureWithRootAndroidBp(` + sdk { + name: "mysdk", + boot_images: ["mybootimage"], + } - boot_image { - name: "mybootimage", - image_name: "art", - } - `) + boot_image { + name: "mybootimage", + image_name: "art", + } + `), + ).RunTest(t) CheckSnapshot(t, result, "mysdk", "", checkUnversionedAndroidBpContents(` @@ -60,3 +67,39 @@ sdk_snapshot { `), checkAllCopyRules("")) } + +// Test that boot_image works with sdk. +func TestBasicSdkWithBootImage(t *testing.T) { + android.GroupFixturePreparers( + prepareForSdkTestWithApex, + prepareForSdkTestWithJava, + android.FixtureWithRootAndroidBp(` + sdk { + name: "mysdk", + boot_images: ["mybootimage"], + } + + boot_image { + name: "mybootimage", + image_name: "art", + apex_available: ["myapex"], + } + + sdk_snapshot { + name: "mysdk@1", + boot_images: ["mybootimage_mysdk_1"], + } + + prebuilt_boot_image { + name: "mybootimage_mysdk_1", + sdk_member_name: "mybootimage", + prefer: false, + visibility: ["//visibility:public"], + apex_available: [ + "myapex", + ], + image_name: "art", + } + `), + ).RunTest(t) +} diff --git a/sdk/bp_test.go b/sdk/bp_test.go index 2bd8a4307..c620ac2b8 100644 --- a/sdk/bp_test.go +++ b/sdk/bp_test.go @@ -84,9 +84,9 @@ func TestAddPropertySimple(t *testing.T) { set.AddProperty(name, val) android.AssertDeepEquals(t, "wrong value", val, set.getValue(name)) } - android.AssertPanic(t, "adding x again should panic", + android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`, func() { set.AddProperty("x", "taxi") }) - android.AssertPanic(t, "adding arr again should panic", + android.AssertPanicMessageContains(t, "adding arr again should panic", `Property "arr" already exists in property set`, func() { set.AddProperty("arr", []string{"d"}) }) } @@ -124,14 +124,14 @@ func TestAddPropertySubset(t *testing.T) { t.Run("add conflicting subset", func(t *testing.T) { set := propertySetFixture().(*bpPropertySet) - android.AssertPanic(t, "adding x again should panic", + android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`, func() { set.AddProperty("x", propertySetFixture()) }) }) t.Run("add non-pointer struct", func(t *testing.T) { set := propertySetFixture().(*bpPropertySet) str := propertyStructFixture().(*propertyStruct) - android.AssertPanic(t, "adding a non-pointer struct should panic", + android.AssertPanicMessageContains(t, "adding a non-pointer struct should panic", "Value is a struct, not a pointer to one:", func() { set.AddProperty("new", *str) }) }) } diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go index a2539c9a0..9626a047e 100644 --- a/sdk/cc_sdk_test.go +++ b/sdk/cc_sdk_test.go @@ -808,7 +808,8 @@ module_exports_snapshot { } func TestSnapshotWithSingleHostOsType(t *testing.T) { - result := sdkFixtureFactory.Extend( + result := android.GroupFixturePreparers( + prepareForSdkTest, ccTestFs.AddToFixture(), cc.PrepareForTestOnLinuxBionic, android.FixtureModifyConfig(func(config android.Config) { diff --git a/sdk/compat_config_sdk_test.go b/sdk/compat_config_sdk_test.go new file mode 100644 index 000000000..dffc02ade --- /dev/null +++ b/sdk/compat_config_sdk_test.go @@ -0,0 +1,70 @@ +// Copyright 2021 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 sdk + +import ( + "testing" + + "android/soong/android" + "android/soong/java" +) + +func TestSnapshotWithCompatConfig(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForSdkTestWithJava, + java.PrepareForTestWithPlatformCompatConfig, + ).RunTestWithBp(t, ` + sdk { + name: "mysdk", + compat_configs: ["myconfig"], + } + + platform_compat_config { + name: "myconfig", + } + `) + + CheckSnapshot(t, result, "mysdk", "", + checkVersionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +prebuilt_platform_compat_config { + name: "mysdk_myconfig@current", + sdk_member_name: "myconfig", + visibility: ["//visibility:public"], + metadata: "compat_configs/myconfig/myconfig_meta.xml", +} + +sdk_snapshot { + name: "mysdk@current", + visibility: ["//visibility:public"], + compat_configs: ["mysdk_myconfig@current"], +} +`), + checkUnversionedAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +prebuilt_platform_compat_config { + name: "myconfig", + prefer: false, + visibility: ["//visibility:public"], + metadata: "compat_configs/myconfig/myconfig_meta.xml", +} +`), + checkAllCopyRules(` +.intermediates/myconfig/android_common/myconfig_meta.xml -> compat_configs/myconfig/myconfig_meta.xml +`), + ) +} diff --git a/sdk/sdk.go b/sdk/sdk.go index 6ca851217..e561529b8 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -445,20 +445,26 @@ func memberInterVersionMutator(mctx android.BottomUpMutatorContext) { } } +// An interface that encapsulates all the functionality needed to manage the sdk dependencies. +// +// It is a mixture of apex and sdk module functionality. +type sdkAndApexModule interface { + android.Module + android.DepIsInSameApex + android.RequiredSdks +} + // Step 4: transitively ripple down the SDK requirements from the root modules like APEX to its // descendants func sdkDepsMutator(mctx android.TopDownMutatorContext) { - if parent, ok := mctx.Module().(interface { - android.DepIsInSameApex - android.RequiredSdks - }); ok { + if parent, ok := mctx.Module().(sdkAndApexModule); ok { // Module types for Mainline modules (e.g. APEX) are expected to implement RequiredSdks() // by reading its own properties like `uses_sdks`. requiredSdks := parent.RequiredSdks() if len(requiredSdks) > 0 { mctx.VisitDirectDeps(func(m android.Module) { // Only propagate required sdks from the apex onto its contents. - if dep, ok := m.(android.SdkAware); ok && parent.DepIsInSameApex(mctx, dep) { + if dep, ok := m.(android.SdkAware); ok && android.IsDepInSameApex(mctx, parent, dep) { dep.BuildWithSdks(requiredSdks) } }) @@ -497,10 +503,7 @@ func sdkDepsReplaceMutator(mctx android.BottomUpMutatorContext) { // Step 6: ensure that the dependencies outside of the APEX are all from the required SDKs func sdkRequirementsMutator(mctx android.TopDownMutatorContext) { - if m, ok := mctx.Module().(interface { - android.DepIsInSameApex - android.RequiredSdks - }); ok { + if m, ok := mctx.Module().(sdkAndApexModule); ok { requiredSdks := m.RequiredSdks() if len(requiredSdks) == 0 { return @@ -519,9 +522,18 @@ func sdkRequirementsMutator(mctx android.TopDownMutatorContext) { return } - // If the dep is outside of the APEX, but is not in any of the - // required SDKs, we know that the dep is a violation. + // If the dep is outside of the APEX, but is not in any of the required SDKs, we know that the + // dep is a violation. if sa, ok := dep.(android.SdkAware); ok { + // It is not an error if a dependency that is excluded from the apex due to the tag is not + // in one of the required SDKs. That is because all of the existing tags that implement it + // do not depend on modules which can or should belong to an sdk_snapshot. + if _, ok := tag.(android.ExcludeFromApexContentsTag); ok { + // The tag defines a dependency that never requires the child module to be part of the + // same apex. + return + } + if !m.DepIsInSameApex(mctx, dep) && !requiredSdks.Contains(sa.ContainingSdk()) { mctx.ModuleErrorf("depends on %q (in SDK %q) that isn't part of the required SDKs: %v", sa.Name(), sa.ContainingSdk(), requiredSdks) diff --git a/sdk/testing.go b/sdk/testing.go index 6df402cff..d21f425ab 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -27,14 +27,9 @@ import ( "android/soong/java" ) -var sdkFixtureFactory = android.NewFixtureFactory( - nil, +// Prepare for running an sdk test with an apex. +var prepareForSdkTestWithApex = android.GroupFixturePreparers( apex.PrepareForTestWithApexBuildComponents, - cc.PrepareForTestWithCcDefaultModules, - genrule.PrepareForTestWithGenRuleBuildComponents, - java.PrepareForTestWithJavaBuildComponents, - PrepareForTestWithSdkBuildComponents, - android.FixtureAddTextFile("sdk/tests/Android.bp", ` apex_key { name: "myapex.key", @@ -59,6 +54,24 @@ var sdkFixtureFactory = android.NewFixtureFactory( "myapex.x509.pem": nil, "myapex.pk8": nil, }), +) + +// Legacy preparer used for running tests within the sdk package. +// +// This includes everything that was needed to run any test in the sdk package prior to the +// introduction of the test fixtures. Tests that are being converted to use fixtures directly +// rather than through the testSdkError() and testSdkWithFs() methods should avoid using this and +// instead should use the various preparers directly using android.GroupFixturePreparers(...) to +// group them when necessary. +// +// deprecated +var prepareForSdkTest = android.GroupFixturePreparers( + cc.PrepareForTestWithCcDefaultModules, + genrule.PrepareForTestWithGenRuleBuildComponents, + java.PrepareForTestWithJavaBuildComponents, + PrepareForTestWithSdkBuildComponents, + + prepareForSdkTestWithApex, cc.PrepareForTestOnWindows, android.FixtureModifyConfig(func(config android.Config) { @@ -77,12 +90,12 @@ var PrepareForTestWithSdkBuildComponents = android.GroupFixturePreparers( func testSdkWithFs(t *testing.T, bp string, fs android.MockFS) *android.TestResult { t.Helper() - return sdkFixtureFactory.RunTest(t, fs.AddToFixture(), android.FixtureWithRootAndroidBp(bp)) + return prepareForSdkTest.RunTest(t, fs.AddToFixture(), android.FixtureWithRootAndroidBp(bp)) } func testSdkError(t *testing.T, pattern, bp string) { t.Helper() - sdkFixtureFactory. + prepareForSdkTest. ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). RunTestWithBp(t, bp) } @@ -201,13 +214,33 @@ func CheckSnapshot(t *testing.T, result *android.TestResult, name string, dir st // Populate a mock filesystem with the files that would have been copied by // the rules. - fs := make(map[string][]byte) + fs := android.MockFS{} + snapshotSubDir := "snapshot" for _, dest := range snapshotBuildInfo.snapshotContents { - fs[dest] = nil + fs[filepath.Join(snapshotSubDir, dest)] = nil } - - // Process the generated bp file to make sure it is valid. - testSdkWithFs(t, snapshotBuildInfo.androidBpContents, fs) + fs[filepath.Join(snapshotSubDir, "Android.bp")] = []byte(snapshotBuildInfo.androidBpContents) + + preparer := result.Preparer() + + // Process the generated bp file to make sure it is valid. Use the same preparer as was used to + // produce this result. + t.Run("snapshot without source", func(t *testing.T) { + android.GroupFixturePreparers( + preparer, + // TODO(b/183184375): Set Config.TestAllowNonExistentPaths = false to verify that all the + // files the snapshot needs are actually copied into the snapshot. + + // Add the files (including bp) created for this snapshot to the test fixture. + fs.AddToFixture(), + + // Remove the source Android.bp file to make sure it works without. + // TODO(b/183184375): Add a test with the source. + android.FixtureModifyMockFS(func(fs android.MockFS) { + delete(fs, "Android.bp") + }), + ).RunTest(t) + }) } type snapshotBuildInfoChecker func(info *snapshotBuildInfo) diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go index 5887b56af..9e7e59462 100644 --- a/sh/sh_binary_test.go +++ b/sh/sh_binary_test.go @@ -13,8 +13,7 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -var shFixtureFactory = android.NewFixtureFactory( - nil, +var prepareForShTest = android.GroupFixturePreparers( cc.PrepareForTestWithCcBuildComponents, PrepareForTestWithShBuildComponents, android.FixtureMergeMockFs(android.MockFS{ @@ -24,19 +23,19 @@ var shFixtureFactory = android.NewFixtureFactory( }), ) -// testShBinary runs tests using the shFixtureFactory +// testShBinary runs tests using the prepareForShTest // -// Do not add any new usages of this, instead use the shFixtureFactory directly as it makes it much +// Do not add any new usages of this, instead use the prepareForShTest directly as it makes it much // easier to customize the test behavior. // // If it is necessary to customize the behavior of an existing test that uses this then please first -// convert the test to using shFixtureFactory first and then in a following change add the +// convert the test to using prepareForShTest first and then in a following change add the // appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify // that it did not change the test behavior unexpectedly. // // deprecated func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) { - result := shFixtureFactory.RunTestWithBp(t, bp) + result := prepareForShTest.RunTestWithBp(t, bp) return result.TestContext, result.Config } diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go index cb1e36230..e9d905186 100644 --- a/sysprop/sysprop_test.go +++ b/sysprop/sysprop_test.go @@ -30,8 +30,6 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -var emptyFixtureFactory = android.NewFixtureFactory(nil) - func test(t *testing.T, bp string) *android.TestResult { t.Helper() @@ -124,7 +122,7 @@ func test(t *testing.T, bp string) *android.TestResult { "com/android2/OdmProperties.sysprop": nil, } - result := emptyFixtureFactory.RunTest(t, + result := android.GroupFixturePreparers( cc.PrepareForTestWithCcDefaultModules, java.PrepareForTestWithJavaDefaultModules, PrepareForTestWithSyspropBuildComponents, @@ -135,7 +133,7 @@ func test(t *testing.T, bp string) *android.TestResult { }), mockFS.AddToFixture(), android.FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) return result } diff --git a/xml/xml_test.go b/xml/xml_test.go index 83ae51c4a..a59a29318 100644 --- a/xml/xml_test.go +++ b/xml/xml_test.go @@ -26,8 +26,6 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -var emptyFixtureFactory = android.NewFixtureFactory(nil) - func testXml(t *testing.T, bp string) *android.TestResult { fs := android.MockFS{ "foo.xml": nil, @@ -37,13 +35,13 @@ func testXml(t *testing.T, bp string) *android.TestResult { "baz.xml": nil, } - return emptyFixtureFactory.RunTest(t, + return android.GroupFixturePreparers( android.PrepareForTestWithArchMutator, etc.PrepareForTestWithPrebuiltEtc, PreparerForTestWithXmlBuildComponents, fs.AddToFixture(), android.FixtureWithRootAndroidBp(bp), - ) + ).RunTest(t) } // Minimal test |