From 3f7bf9fa0ddb4c8da9996464e1472b46d53d6ad8 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 8 Nov 2022 12:21:15 +0000 Subject: [PATCH] Allow namespace config to be tested properly Previously, the NewTextContext created a context that always called NewNameResolver with a export filter that always returned true. This change fixes that by: 1. Changing NewNameResolver to take a Config parameter instead of a filter parameter and pushing the code to create the filter from the Config from newNameResolver() in cmd/soong_build/main.go into the NewNameResolver function. 2. Extracting a newTestContextForFixture that does not create a NameResolver or set it on the context. That avoids creating a NameResolver before the test has prepared the config. 3. Modify the fixture to create and set the NameResolver in the Context after the config has been prepared by the test. 4. Added test to verify that it all works. Bug: 234825639 Test: m nothing Change-Id: Ie4b13f18093dc01a0ab65a9ecfd143585d843b55 --- android/fixture.go | 12 +++++++++++- android/namespace.go | 22 +++++++++++++++++++++- android/namespace_test.go | 30 ++++++++++++++++++++++++++++++ android/testing.go | 22 ++++++++++++---------- cmd/soong_build/main.go | 14 +------------- 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/android/fixture.go b/android/fixture.go index f33e7189d..3f01f5a0d 100644 --- a/android/fixture.go +++ b/android/fixture.go @@ -658,7 +658,7 @@ func (t *TestPathContext) AddNinjaFileDeps(deps ...string) { func createFixture(t *testing.T, buildDir string, preparers []*simpleFixturePreparer) Fixture { config := TestConfig(buildDir, nil, "", nil) - ctx := NewTestContext(config) + ctx := newTestContextForFixture(config) fixture := &fixture{ preparers: preparers, t: t, @@ -790,6 +790,16 @@ func (f *fixture) RunTest() *TestResult { } } + // Create and set the Context's NameInterface. It needs to be created here as it depends on the + // configuration that has been prepared for this fixture. + resolver := NewNameResolver(ctx.config) + + // Set the NameInterface in the main Context. + ctx.SetNameInterface(resolver) + + // Set the NameResolver in the TestContext. + ctx.NameResolver = resolver + ctx.Register() var ninjaDeps []string extraNinjaDeps, errs := ctx.ParseBlueprintsFiles("ignored") diff --git a/android/namespace.go b/android/namespace.go index a3ff76125..b43ffdf19 100644 --- a/android/namespace.go +++ b/android/namespace.go @@ -91,7 +91,27 @@ type NameResolver struct { namespaceExportFilter func(*Namespace) bool } -func NewNameResolver(namespaceExportFilter func(*Namespace) bool) *NameResolver { +// NameResolverConfig provides the subset of the Config interface needed by the +// NewNameResolver function. +type NameResolverConfig interface { + // ExportedNamespaces is the list of namespaces that Soong must export to + // make. + ExportedNamespaces() []string +} + +func NewNameResolver(config NameResolverConfig) *NameResolver { + namespacePathsToExport := make(map[string]bool) + + for _, namespaceName := range config.ExportedNamespaces() { + namespacePathsToExport[namespaceName] = true + } + + namespacePathsToExport["."] = true // always export the root namespace + + namespaceExportFilter := func(namespace *Namespace) bool { + return namespacePathsToExport[namespace.Path] + } + r := &NameResolver{ namespacesByDir: sync.Map{}, namespaceExportFilter: namespaceExportFilter, diff --git a/android/namespace_test.go b/android/namespace_test.go index 87d13206b..7a387a0bd 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -602,6 +602,36 @@ func TestRename(t *testing.T) { // RunTest will report any errors } +func TestNamespace_Exports(t *testing.T) { + result := GroupFixturePreparers( + prepareForTestWithNamespace, + FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.NamespacesToExport = []string{"dir1"} + }), + dirBpToPreparer(map[string]string{ + "dir1": ` + soong_namespace { + } + test_module { + name: "a", + } + `, + "dir2": ` + soong_namespace { + } + test_module { + name: "b", + } + `, + }), + ).RunTest(t) + + aModule := result.Module("a", "") + AssertBoolEquals(t, "a exported", true, aModule.ExportedToMake()) + bModule := result.Module("b", "") + AssertBoolEquals(t, "b not exported", false, bModule.ExportedToMake()) +} + // some utils to support the tests var prepareForTestWithNamespace = GroupFixturePreparers( diff --git a/android/testing.go b/android/testing.go index 2256c96bc..8fcf4409b 100644 --- a/android/testing.go +++ b/android/testing.go @@ -30,19 +30,11 @@ import ( "github.com/google/blueprint/proptools" ) -func NewTestContext(config Config) *TestContext { - namespaceExportFilter := func(namespace *Namespace) bool { - return true - } - - nameResolver := NewNameResolver(namespaceExportFilter) +func newTestContextForFixture(config Config) *TestContext { ctx := &TestContext{ - Context: &Context{blueprint.NewContext(), config}, - NameResolver: nameResolver, + Context: &Context{blueprint.NewContext(), config}, } - ctx.SetNameInterface(nameResolver) - ctx.postDeps = append(ctx.postDeps, registerPathDepsMutator) ctx.SetFs(ctx.config.fs) @@ -53,6 +45,16 @@ func NewTestContext(config Config) *TestContext { return ctx } +func NewTestContext(config Config) *TestContext { + ctx := newTestContextForFixture(config) + + nameResolver := NewNameResolver(config) + ctx.NameResolver = nameResolver + ctx.SetNameInterface(nameResolver) + + return ctx +} + var PrepareForTestWithArchMutator = GroupFixturePreparers( // Configure architecture targets in the fixture config. FixtureModifyConfig(modifyTestConfigToSupportArchMutator), diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 3fed1a172..028ca44d0 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -106,19 +106,7 @@ func init() { } func newNameResolver(config android.Config) *android.NameResolver { - namespacePathsToExport := make(map[string]bool) - - for _, namespaceName := range config.ExportedNamespaces() { - namespacePathsToExport[namespaceName] = true - } - - namespacePathsToExport["."] = true // always export the root namespace - - exportFilter := func(namespace *android.Namespace) bool { - return namespacePathsToExport[namespace.Path] - } - - return android.NewNameResolver(exportFilter) + return android.NewNameResolver(config) } func newContext(configuration android.Config) *android.Context {