aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-11-30 09:33:59 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-11-30 09:33:59 +0000
commitb97173ff0b8fc1c19229ded5fba9317329e51909 (patch)
tree7076364875be4ce36b86a2809f87291ee13bdeeb
parent501c89ff789fed9b9966a0b510e7d6274a80bd66 (diff)
parentc21336e7cd011ccb3bbe0f855f4a4471ffcca5c2 (diff)
downloadsoong-b97173ff0b8fc1c19229ded5fba9317329e51909.tar.gz
Snap for 9350704 from c21336e7cd011ccb3bbe0f855f4a4471ffcca5c2 to mainline-extservices-releaseaml_ext_331814220aml_ext_331412000
Change-Id: Ia24a843ee466d2a9292b63888957e6bb9a103b9d
-rw-r--r--android/fixture.go24
-rw-r--r--android/namespace.go22
-rw-r--r--android/namespace_test.go922
-rw-r--r--android/neverallow.go1
-rw-r--r--android/testing.go22
-rw-r--r--cmd/soong_build/main.go14
-rw-r--r--java/robolectric.go12
-rw-r--r--sdk/sdk_test.go54
-rw-r--r--sdk/update.go54
-rw-r--r--ui/build/dumpvars.go3
10 files changed, 527 insertions, 601 deletions
diff --git a/android/fixture.go b/android/fixture.go
index 3a15ad3a5..3f01f5a0d 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -588,6 +588,18 @@ func FixtureExpectsAllErrorsToMatchAPattern(patterns []string) FixtureErrorHandl
})
}
+// FixtureExpectsOneErrorPattern returns an error handler that will cause the test to fail
+// if there is more than one error or the error does not match the pattern.
+//
+// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
+// which the test is being run which means that the RunTest() method will not return.
+func FixtureExpectsOneErrorPattern(pattern string) FixtureErrorHandler {
+ return FixtureCustomErrorHandler(func(t *testing.T, result *TestResult) {
+ t.Helper()
+ CheckErrorsAgainstExpectations(t, result.Errs, []string{pattern})
+ })
+}
+
// FixtureCustomErrorHandler creates a custom error handler
func FixtureCustomErrorHandler(function func(t *testing.T, result *TestResult)) FixtureErrorHandler {
return simpleErrorHandler{
@@ -646,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,
@@ -778,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 fc7bc290f..1f821ff84 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 ea399da06..7a387a0bd 100644
--- a/android/namespace_test.go
+++ b/android/namespace_test.go
@@ -15,7 +15,6 @@
package android
import (
- "errors"
"path/filepath"
"reflect"
"testing"
@@ -24,577 +23,555 @@ import (
)
func TestDependingOnModuleInSameNamespace(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- a := getModule(ctx, "a")
- b := getModule(ctx, "b")
- if !dependsOn(ctx, b, a) {
+ a := getModule(result, "a")
+ b := getModule(result, "b")
+ if !dependsOn(result, b, a) {
t.Errorf("module b does not depend on module a in the same namespace")
}
}
func TestDependingOnModuleInRootNamespace(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
".": `
- test_module {
- name: "b",
- deps: ["a"],
- }
- test_module {
- name: "a",
- }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
+ test_module {
+ name: "a",
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- a := getModule(ctx, "a")
- b := getModule(ctx, "b")
- if !dependsOn(ctx, b, a) {
+ a := getModule(result, "a")
+ b := getModule(result, "b")
+ if !dependsOn(result, b, a) {
t.Errorf("module b in root namespace does not depend on module a in the root namespace")
}
}
func TestImplicitlyImportRootNamespace(t *testing.T) {
- _ = setupTest(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
".": `
- test_module {
- name: "a",
- }
+ test_module {
+ name: "a",
+ }
`,
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- // setupTest will report any errors
+ // RunTest will report any errors
}
func TestDependingOnBlueprintModuleInRootNamespace(t *testing.T) {
- _ = setupTest(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
".": `
- blueprint_test_module {
- name: "a",
- }
+ blueprint_test_module {
+ name: "a",
+ }
`,
"dir1": `
- soong_namespace {
- }
- blueprint_test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ }
+ blueprint_test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- // setupTest will report any errors
+ // RunTest will report any errors
}
func TestDependingOnModuleInImportedNamespace(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir2": `
- soong_namespace {
- imports: ["dir1"],
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ imports: ["dir1"],
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- a := getModule(ctx, "a")
- b := getModule(ctx, "b")
- if !dependsOn(ctx, b, a) {
+ a := getModule(result, "a")
+ b := getModule(result, "b")
+ if !dependsOn(result, b, a) {
t.Errorf("module b does not depend on module a in the same namespace")
}
}
func TestDependingOnModuleInNonImportedNamespace(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir2": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir3": `
- soong_namespace {
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
-
- expectedErrors := []error{
- errors.New(
- `dir3/Android.bp:4:4: "b" depends on undefined module "a"
+ }),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir3/Android.bp:4:5: "b" depends on undefined module "a"
Module "b" is defined in namespace "dir3" which can read these 2 namespaces: ["dir3" "."]
-Module "a" can be found in these namespaces: ["dir1" "dir2"]`),
- }
-
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+Module "a" can be found in these namespaces: ["dir1" "dir2"]\E`)).
+ RunTest(t)
}
func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir2": `
- soong_namespace {
- }
- test_module {
- name: "b",
- deps: ["//dir1:a"],
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "b",
+ deps: ["//dir1:a"],
+ }
`,
- },
- )
- a := getModule(ctx, "a")
- b := getModule(ctx, "b")
- if !dependsOn(ctx, b, a) {
+ }),
+ ).RunTest(t)
+
+ a := getModule(result, "a")
+ b := getModule(result, "b")
+ if !dependsOn(result, b, a) {
t.Errorf("module b does not depend on module a")
}
}
func TestSameNameInTwoNamespaces(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- id: "1",
- }
- test_module {
- name: "b",
- deps: ["a"],
- id: "2",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ id: "1",
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ id: "2",
+ }
`,
"dir2": `
- soong_namespace {
- }
- test_module {
- name: "a",
- id:"3",
- }
- test_module {
- name: "b",
- deps: ["a"],
- id:"4",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ id:"3",
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ id:"4",
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- one := findModuleById(ctx, "1")
- two := findModuleById(ctx, "2")
- three := findModuleById(ctx, "3")
- four := findModuleById(ctx, "4")
- if !dependsOn(ctx, two, one) {
+ one := findModuleById(result, "1")
+ two := findModuleById(result, "2")
+ three := findModuleById(result, "3")
+ four := findModuleById(result, "4")
+ if !dependsOn(result, two, one) {
t.Fatalf("Module 2 does not depend on module 1 in its namespace")
}
- if dependsOn(ctx, two, three) {
+ if dependsOn(result, two, three) {
t.Fatalf("Module 2 depends on module 3 in another namespace")
}
- if !dependsOn(ctx, four, three) {
+ if !dependsOn(result, four, three) {
t.Fatalf("Module 4 does not depend on module 3 in its namespace")
}
- if dependsOn(ctx, four, one) {
+ if dependsOn(result, four, one) {
t.Fatalf("Module 4 depends on module 1 in another namespace")
}
}
func TestSearchOrder(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- id: "1",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ id: "1",
+ }
`,
"dir2": `
- soong_namespace {
- }
- test_module {
- name: "a",
- id:"2",
- }
- test_module {
- name: "b",
- id:"3",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ id:"2",
+ }
+ test_module {
+ name: "b",
+ id:"3",
+ }
`,
"dir3": `
- soong_namespace {
- }
- test_module {
- name: "a",
- id:"4",
- }
- test_module {
- name: "b",
- id:"5",
- }
- test_module {
- name: "c",
- id:"6",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ id:"4",
+ }
+ test_module {
+ name: "b",
+ id:"5",
+ }
+ test_module {
+ name: "c",
+ id:"6",
+ }
`,
".": `
- test_module {
- name: "a",
- id: "7",
- }
- test_module {
- name: "b",
- id: "8",
- }
- test_module {
- name: "c",
- id: "9",
- }
- test_module {
- name: "d",
- id: "10",
- }
+ test_module {
+ name: "a",
+ id: "7",
+ }
+ test_module {
+ name: "b",
+ id: "8",
+ }
+ test_module {
+ name: "c",
+ id: "9",
+ }
+ test_module {
+ name: "d",
+ id: "10",
+ }
`,
"dir4": `
- soong_namespace {
- imports: ["dir1", "dir2", "dir3"]
- }
- test_module {
- name: "test_me",
- id:"0",
- deps: ["a", "b", "c", "d"],
- }
+ soong_namespace {
+ imports: ["dir1", "dir2", "dir3"]
+ }
+ test_module {
+ name: "test_me",
+ id:"0",
+ deps: ["a", "b", "c", "d"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- testMe := findModuleById(ctx, "0")
- if !dependsOn(ctx, testMe, findModuleById(ctx, "1")) {
+ testMe := findModuleById(result, "0")
+ if !dependsOn(result, testMe, findModuleById(result, "1")) {
t.Errorf("test_me doesn't depend on id 1")
}
- if !dependsOn(ctx, testMe, findModuleById(ctx, "3")) {
+ if !dependsOn(result, testMe, findModuleById(result, "3")) {
t.Errorf("test_me doesn't depend on id 3")
}
- if !dependsOn(ctx, testMe, findModuleById(ctx, "6")) {
+ if !dependsOn(result, testMe, findModuleById(result, "6")) {
t.Errorf("test_me doesn't depend on id 6")
}
- if !dependsOn(ctx, testMe, findModuleById(ctx, "10")) {
+ if !dependsOn(result, testMe, findModuleById(result, "10")) {
t.Errorf("test_me doesn't depend on id 10")
}
- if numDeps(ctx, testMe) != 4 {
- t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(ctx, testMe))
+ if numDeps(result, testMe) != 4 {
+ t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(result, testMe))
}
}
func TestTwoNamespacesCanImportEachOther(t *testing.T) {
- _ = setupTest(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- imports: ["dir2"]
- }
- test_module {
- name: "a",
- }
- test_module {
- name: "c",
- deps: ["b"],
- }
+ soong_namespace {
+ imports: ["dir2"]
+ }
+ test_module {
+ name: "a",
+ }
+ test_module {
+ name: "c",
+ deps: ["b"],
+ }
`,
"dir2": `
- soong_namespace {
- imports: ["dir1"],
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ imports: ["dir1"],
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- // setupTest will report any errors
+ // RunTest will report any errors
}
func TestImportingNonexistentNamespace(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- imports: ["a_nonexistent_namespace"]
- }
- test_module {
- name: "a",
- deps: ["a_nonexistent_module"]
- }
+ soong_namespace {
+ imports: ["a_nonexistent_namespace"]
+ }
+ test_module {
+ name: "a",
+ deps: ["a_nonexistent_module"]
+ }
`,
- },
- )
-
- // should complain about the missing namespace and not complain about the unresolvable dependency
- expectedErrors := []error{
- errors.New(`dir1/Android.bp:2:4: module "soong_namespace": namespace a_nonexistent_namespace does not exist`),
- }
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+ }),
+ ).
+ // should complain about the missing namespace and not complain about the unresolvable dependency
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:2:5: module "soong_namespace": namespace a_nonexistent_namespace does not exist\E`)).
+ RunTest(t)
}
func TestNamespacesDontInheritParentNamespaces(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir1/subdir1": `
- soong_namespace {
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
-
- expectedErrors := []error{
- errors.New(`dir1/subdir1/Android.bp:4:4: "b" depends on undefined module "a"
+ }),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/subdir1/Android.bp:4:5: "b" depends on undefined module "a"
Module "b" is defined in namespace "dir1/subdir1" which can read these 2 namespaces: ["dir1/subdir1" "."]
-Module "a" can be found in these namespaces: ["dir1"]`),
- }
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+Module "a" can be found in these namespaces: ["dir1"]\E`)).
+ RunTest(t)
}
func TestModulesDoReceiveParentNamespace(t *testing.T) {
- _ = setupTest(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir1/subdir": `
- test_module {
- name: "b",
- deps: ["a"],
- }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
- },
- )
+ }),
+ ).RunTest(t)
- // setupTest will report any errors
+ // RunTest will report any errors
}
func TestNamespaceImportsNotTransitive(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
`,
"dir2": `
- soong_namespace {
- imports: ["dir1"],
- }
- test_module {
- name: "b",
- deps: ["a"],
- }
+ soong_namespace {
+ imports: ["dir1"],
+ }
+ test_module {
+ name: "b",
+ deps: ["a"],
+ }
`,
"dir3": `
- soong_namespace {
- imports: ["dir2"],
- }
- test_module {
- name: "c",
- deps: ["a"],
- }
+ soong_namespace {
+ imports: ["dir2"],
+ }
+ test_module {
+ name: "c",
+ deps: ["a"],
+ }
`,
- },
- )
-
- expectedErrors := []error{
- errors.New(`dir3/Android.bp:5:4: "c" depends on undefined module "a"
+ }),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir3/Android.bp:5:5: "c" depends on undefined module "a"
Module "c" is defined in namespace "dir3" which can read these 3 namespaces: ["dir3" "dir2" "."]
-Module "a" can be found in these namespaces: ["dir1"]`),
- }
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+Module "a" can be found in these namespaces: ["dir1"]\E`)).
+ RunTest(t)
}
func TestTwoNamepacesInSameDir(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- soong_namespace {
- }
+ soong_namespace {
+ }
+ soong_namespace {
+ }
`,
- },
- )
-
- expectedErrors := []error{
- errors.New(`dir1/Android.bp:4:4: namespace dir1 already exists`),
- }
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+ }),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:4:5: namespace dir1 already exists\E`)).
+ RunTest(t)
}
func TestNamespaceNotAtTopOfFile(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- test_module {
- name: "a"
- }
- soong_namespace {
- }
+ test_module {
+ name: "a"
+ }
+ soong_namespace {
+ }
`,
- },
- )
-
- expectedErrors := []error{
- errors.New(`dir1/Android.bp:5:4: a namespace must be the first module in the file`),
- }
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+ }),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:5:5: a namespace must be the first module in the file\E`)).
+ RunTest(t)
}
func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) {
- _, errs := setupTestExpectErrs(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a"
- }
- test_module {
- name: "a"
- }
+ soong_namespace {
+ }
+ test_module {
+ name: "a"
+ }
+ test_module {
+ name: "a"
+ }
`,
- },
- )
-
- expectedErrors := []error{
- errors.New(`dir1/Android.bp:7:4: module "a" already defined
- dir1/Android.bp:4:4 <-- previous definition here`),
- }
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+ }),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:7:5: module "a" already defined
+ dir1/Android.bp:4:5 <-- previous definition here\E`)).
+ RunTest(t)
}
func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) {
- _, errs := setupTestFromFiles(t,
- map[string][]byte{
- "Android.bp": []byte(`
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ FixtureWithRootAndroidBp(`
build = ["include.bp"]
- `),
- "include.bp": []byte(`
+ `),
+ FixtureAddTextFile("include.bp", `
soong_namespace {
}
- `),
- },
- )
-
- expectedErrors := []error{
- errors.New(`include.bp:2:5: A namespace may only be declared in a file named Android.bp`),
- }
-
- if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() {
- t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs)
- }
+ `),
+ ).
+ ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(
+ `\Qinclude.bp:2:5: A namespace may only be declared in a file named Android.bp\E`,
+ )).
+ RunTest(t)
}
// so that the generated .ninja file will have consistent names
func TestConsistentNamespaceNames(t *testing.T) {
- ctx := setupTest(t,
- map[string]string{
+ result := GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": "soong_namespace{}",
"dir2": "soong_namespace{}",
"dir3": "soong_namespace{}",
- })
+ }),
+ ).RunTest(t)
- ns1, _ := ctx.NameResolver.namespaceAt("dir1")
- ns2, _ := ctx.NameResolver.namespaceAt("dir2")
- ns3, _ := ctx.NameResolver.namespaceAt("dir3")
+ ns1, _ := result.NameResolver.namespaceAt("dir1")
+ ns2, _ := result.NameResolver.namespaceAt("dir2")
+ ns3, _ := result.NameResolver.namespaceAt("dir3")
actualIds := []string{ns1.id, ns2.id, ns3.id}
expectedIds := []string{"1", "2", "3"}
if !reflect.DeepEqual(actualIds, expectedIds) {
@@ -604,103 +581,118 @@ func TestConsistentNamespaceNames(t *testing.T) {
// so that the generated .ninja file will have consistent names
func TestRename(t *testing.T) {
- _ = setupTest(t,
- map[string]string{
+ GroupFixturePreparers(
+ prepareForTestWithNamespace,
+ dirBpToPreparer(map[string]string{
"dir1": `
- soong_namespace {
- }
- test_module {
- name: "a",
- deps: ["c"],
- }
- test_module {
- name: "b",
- rename: "c",
- }
- `})
- // setupTest will report any errors
-}
-
-// some utils to support the tests
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ deps: ["c"],
+ }
+ test_module {
+ name: "b",
+ rename: "c",
+ }
+ `,
+ }),
+ ).RunTest(t)
-func mockFiles(bps map[string]string) (files map[string][]byte) {
- files = make(map[string][]byte, len(bps))
- files["Android.bp"] = []byte("")
- for dir, text := range bps {
- files[filepath.Join(dir, "Android.bp")] = []byte(text)
- }
- return files
+ // RunTest will report any errors
}
-func setupTestFromFiles(t *testing.T, bps MockFS) (ctx *TestContext, errs []error) {
+func TestNamespace_Exports(t *testing.T) {
result := GroupFixturePreparers(
- FixtureModifyContext(func(ctx *TestContext) {
- ctx.RegisterModuleType("test_module", newTestModule)
- ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
- ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
- ctx.BottomUp("rename", renameMutator)
- })
+ prepareForTestWithNamespace,
+ FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.NamespacesToExport = []string{"dir1"}
}),
- PrepareForTestWithNamespace,
- bps.AddToFixture(),
- ).
- // Ignore errors for now so tests can check them later.
- ExtendWithErrorHandler(FixtureIgnoreErrors).
- RunTest(t)
+ dirBpToPreparer(map[string]string{
+ "dir1": `
+ soong_namespace {
+ }
+ test_module {
+ name: "a",
+ }
+ `,
+ "dir2": `
+ soong_namespace {
+ }
+ test_module {
+ name: "b",
+ }
+ `,
+ }),
+ ).RunTest(t)
- return result.TestContext, result.Errs
+ aModule := result.Module("a", "")
+ AssertBoolEquals(t, "a exported", true, aModule.ExportedToMake())
+ bModule := result.Module("b", "")
+ AssertBoolEquals(t, "b not exported", false, bModule.ExportedToMake())
}
-func setupTestExpectErrs(t *testing.T, bps map[string]string) (ctx *TestContext, errs []error) {
- files := make(map[string][]byte, len(bps))
+// some utils to support the tests
+
+var prepareForTestWithNamespace = GroupFixturePreparers(
+ FixtureRegisterWithContext(registerNamespaceBuildComponents),
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.PreArchMutators(RegisterNamespaceMutator)
+ }),
+ FixtureModifyContext(func(ctx *TestContext) {
+ ctx.RegisterModuleType("test_module", newTestModule)
+ ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
+ ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("rename", renameMutator)
+ })
+ }),
+)
+
+// dirBpToPreparer takes a map from directory to the contents of the Android.bp file and produces a
+// FixturePreparer.
+func dirBpToPreparer(bps map[string]string) FixturePreparer {
+ files := make(MockFS, len(bps))
files["Android.bp"] = []byte("")
for dir, text := range bps {
files[filepath.Join(dir, "Android.bp")] = []byte(text)
}
- return setupTestFromFiles(t, files)
-}
-
-func setupTest(t *testing.T, bps map[string]string) (ctx *TestContext) {
- t.Helper()
- ctx, errs := setupTestExpectErrs(t, bps)
- FailIfErrored(t, errs)
- return ctx
+ return files.AddToFixture()
}
-func dependsOn(ctx *TestContext, module TestingModule, possibleDependency TestingModule) bool {
+func dependsOn(result *TestResult, module TestingModule, possibleDependency TestingModule) bool {
depends := false
visit := func(dependency blueprint.Module) {
if dependency == possibleDependency.module {
depends = true
}
}
- ctx.VisitDirectDeps(module.module, visit)
+ result.VisitDirectDeps(module.module, visit)
return depends
}
-func numDeps(ctx *TestContext, module TestingModule) int {
+func numDeps(result *TestResult, module TestingModule) int {
count := 0
visit := func(dependency blueprint.Module) {
count++
}
- ctx.VisitDirectDeps(module.module, visit)
+ result.VisitDirectDeps(module.module, visit)
return count
}
-func getModule(ctx *TestContext, moduleName string) TestingModule {
- return ctx.ModuleForTests(moduleName, "")
+func getModule(result *TestResult, moduleName string) TestingModule {
+ return result.ModuleForTests(moduleName, "")
}
-func findModuleById(ctx *TestContext, id string) (module TestingModule) {
+func findModuleById(result *TestResult, id string) (module TestingModule) {
visit := func(candidate blueprint.Module) {
testModule, ok := candidate.(*testModule)
if ok {
if testModule.properties.Id == id {
- module = newTestingModule(ctx.config, testModule)
+ module = newTestingModule(result.config, testModule)
}
}
}
- ctx.VisitAllModules(visit)
+ result.VisitAllModules(visit)
return module
}
@@ -747,7 +739,7 @@ type blueprintTestModule struct {
}
}
-func (b *blueprintTestModule) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string {
+func (b *blueprintTestModule) DynamicDependencies(_ blueprint.DynamicDependerModuleContext) []string {
return b.properties.Deps
}
diff --git a/android/neverallow.go b/android/neverallow.go
index aa47bcaeb..5f069b877 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -154,6 +154,7 @@ func createJavaDeviceForHostRules() []Rule {
"development/build",
"external/guava",
"external/robolectric-shadows",
+ "external/robolectric",
"frameworks/layoutlib",
}
diff --git a/android/testing.go b/android/testing.go
index 1b36c903a..f5210d185 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 3f8105c88..7c500b76c 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -97,19 +97,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 {
diff --git a/java/robolectric.go b/java/robolectric.go
index f71952172..80be04612 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -23,6 +23,8 @@ import (
"android/soong/android"
"android/soong/java/config"
"android/soong/tradefed"
+
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -63,6 +65,10 @@ type robolectricProperties struct {
// The version number of a robolectric prebuilt to use from prebuilts/misc/common/robolectric
// instead of the one built from source in external/robolectric-shadows.
Robolectric_prebuilt_version *string
+
+ // Use /external/robolectric rather than /external/robolectric-shadows as the version of robolectri
+ // to use. /external/robolectric closely tracks github's master, and will fully replace /external/robolectric-shadows
+ Upstream *bool
}
type robolectricTest struct {
@@ -106,7 +112,11 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
ctx.AddVariationDependencies(nil, libTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v))
} else {
- ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib)
+ if proptools.Bool(r.robolectricProperties.Upstream) {
+ ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib+"_upstream")
+ } else {
+ ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib)
+ }
}
ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 2f9aee9da..108a664ea 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -409,60 +409,6 @@ java_import {
)
})
- t.Run("SOONG_SDK_SNAPSHOT_PREFER=true", func(t *testing.T) {
- result := android.GroupFixturePreparers(
- preparer,
- android.FixtureMergeEnv(map[string]string{
- "SOONG_SDK_SNAPSHOT_PREFER": "true",
- }),
- ).RunTest(t)
-
- checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
- CheckSnapshot(t, result, "mysdk", "",
- checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "myjavalib",
- prefer: true,
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
-}
- `),
- )
- })
-
- t.Run("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=module:build_from_source", func(t *testing.T) {
- result := android.GroupFixturePreparers(
- preparer,
- android.FixtureMergeEnv(map[string]string{
- "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR": "module:build_from_source",
- }),
- ).RunTest(t)
-
- checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
- CheckSnapshot(t, result, "mysdk", "",
- checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "myjavalib",
- prefer: false,
- use_source_config_var: {
- config_namespace: "module",
- var_name: "build_from_source",
- },
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
-}
- `),
- )
- })
-
t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
diff --git a/sdk/update.go b/sdk/update.go
index 92a13fa7f..baa203302 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -34,41 +34,6 @@ import (
// Environment variables that affect the generated snapshot
// ========================================================
//
-// SOONG_SDK_SNAPSHOT_PREFER
-// By default every module in the generated snapshot has prefer: false. Building it
-// with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
-//
-// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR
-// If set this specifies the Soong config var that can be used to control whether the prebuilt
-// modules from the generated snapshot or the original source modules. Values must be a colon
-// separated pair of strings, the first of which is the Soong config namespace, and the second
-// is the name of the variable within that namespace.
-//
-// The config namespace and var name are used to set the `use_source_config_var` property. That
-// in turn will cause the generated prebuilts to use the soong config variable to select whether
-// source or the prebuilt is used.
-// e.g. If an sdk snapshot is built using:
-// m SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=acme:build_from_source sdkextensions-sdk
-// Then the resulting snapshot will include:
-// use_source_config_var: {
-// config_namespace: "acme",
-// var_name: "build_from_source",
-// }
-//
-// Assuming that the config variable is defined in .mk using something like:
-// $(call add_soong_config_namespace,acme)
-// $(call add_soong_config_var_value,acme,build_from_source,true)
-//
-// Then when the snapshot is unpacked in the repository it will have the following behavior:
-// m droid - will use the sdkextensions-sdk prebuilts if present. Otherwise, it will use the
-// sources.
-// m SOONG_CONFIG_acme_build_from_source=true droid - will use the sdkextensions-sdk
-// sources, if present. Otherwise, it will use the prebuilts.
-//
-// This is a temporary mechanism to control the prefer flags and will be removed once a more
-// maintainable solution has been implemented.
-// TODO(b/174997203): Remove when no longer necessary.
-//
// SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE
// This allows the target build release (i.e. the release version of the build within which
// the snapshot will be used) of the snapshot to be specified. If unspecified then it defaults
@@ -2019,29 +1984,12 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu
// Do not add the prefer property if the member snapshot module is a source module type.
moduleCtx := ctx.sdkMemberContext
- config := moduleCtx.Config()
if !memberType.UsesSourceModuleTypeInSnapshot() {
- // Set the prefer based on the environment variable. This is a temporary work around to allow a
- // snapshot to be created that sets prefer: true.
- // TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
- // dynamically at build time not at snapshot generation time.
- prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
-
// Set prefer. Setting this to false is not strictly required as that is the default but it does
// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to
// check the behavior when a prebuilt is preferred. It also makes it explicit what the default
// behavior is for the module.
- bpModule.insertAfter("name", "prefer", prefer)
-
- configVar := config.Getenv("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR")
- if configVar != "" {
- parts := strings.Split(configVar, ":")
- cfp := android.ConfigVarProperties{
- Config_namespace: proptools.StringPtr(parts[0]),
- Var_name: proptools.StringPtr(parts[1]),
- }
- bpModule.insertAfter("prefer", "use_source_config_var", cfp)
- }
+ bpModule.insertAfter("name", "prefer", false)
}
variants := selectApexVariantsWhereAvailable(ctx, member.variants)
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 285f1569b..45bfe5dfa 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -162,10 +162,7 @@ var BannerVars = []string{
"OUT_DIR",
"AUX_OS_VARIANT_LIST",
"PRODUCT_SOONG_NAMESPACES",
- "SOONG_SDK_SNAPSHOT_PREFER",
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
- "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
- "SOONG_SDK_SNAPSHOT_VERSION",
}
func Banner(make_vars map[string]string) string {