Merge "apex.go: Add support for diffing content of APEX with whitelist file"
diff --git a/android/neverallow.go b/android/neverallow.go
index 8355bb3..3d1454e 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -177,7 +177,7 @@
osClass := ctx.Module().Target().Os.Class
- for _, r := range neverallows {
+ for _, r := range neverallowRules(ctx.Config()) {
n := r.(*rule)
if !n.appliesToPath(dir) {
continue
@@ -551,3 +551,19 @@
panic("Can't handle type: " + value.Kind().String())
}
+
+var neverallowRulesKey = NewOnceKey("neverallowRules")
+
+func neverallowRules(config Config) []Rule {
+ return config.Once(neverallowRulesKey, func() interface{} {
+ // No test rules were set by setTestNeverallowRules, use the global rules
+ return neverallows
+ }).([]Rule)
+}
+
+// Overrides the default neverallow rules for the supplied config.
+//
+// For testing only.
+func setTestNeverallowRules(config Config, testRules []Rule) {
+ config.Once(neverallowRulesKey, func() interface{} { return testRules })
+}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 920b9a5..4584585 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -20,23 +20,29 @@
"github.com/google/blueprint"
)
-func init() {
- // Add extra rules needed for testing.
- AddNeverAllowRules(
- NeverAllow().InDirectDeps("not_allowed_in_direct_deps"),
- )
-}
-
var neverallowTests = []struct {
- name string
- fs map[string][]byte
- expectedError string
+ // The name of the test.
+ name string
+
+ // Optional test specific rules. If specified then they are used instead of the default rules.
+ rules []Rule
+
+ // Additional contents to add to the virtual filesystem used by the tests.
+ fs map[string][]byte
+
+ // The expected error patterns. If empty then no errors are expected, otherwise each error
+ // reported must be matched by at least one of these patterns. A pattern matches if the error
+ // message contains the pattern. A pattern does not have to match the whole error message.
+ expectedErrors []string
}{
// Test General Functionality
// in direct deps tests
{
name: "not_allowed_in_direct_deps",
+ rules: []Rule{
+ NeverAllow().InDirectDeps("not_allowed_in_direct_deps"),
+ },
fs: map[string][]byte{
"top/Blueprints": []byte(`
cc_library {
@@ -48,10 +54,12 @@
static_libs: ["not_allowed_in_direct_deps"],
}`),
},
- expectedError: `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
+ expectedErrors: []string{
+ `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
+ },
},
- // Test specific rules
+ // Test android specific rules
// include_dir rule tests
{
@@ -63,7 +71,9 @@
include_dirs: ["art/libdexfile/include"],
}`),
},
- expectedError: "all usages of 'art' have been migrated",
+ expectedErrors: []string{
+ "all usages of 'art' have been migrated",
+ },
},
{
name: "include_dir can reference another location",
@@ -88,7 +98,9 @@
},
}`),
},
- expectedError: "VNDK can never contain a library that is device dependent",
+ expectedErrors: []string{
+ "VNDK can never contain a library that is device dependent",
+ },
},
{
name: "no vndk.enabled under device directory",
@@ -102,7 +114,9 @@
},
}`),
},
- expectedError: "VNDK can never contain a library that is device dependent",
+ expectedErrors: []string{
+ "VNDK can never contain a library that is device dependent",
+ },
},
{
name: "vndk-ext under vendor or device directory",
@@ -124,7 +138,6 @@
},
}`),
},
- expectedError: "",
},
{
@@ -140,7 +153,9 @@
},
}`),
},
- expectedError: "manifest enforcement should be independent",
+ expectedErrors: []string{
+ "manifest enforcement should be independent",
+ },
},
{
name: "libhidltransport enforce_vintf_manifest.cflags",
@@ -155,7 +170,6 @@
},
}`),
},
- expectedError: "",
},
{
@@ -171,7 +185,9 @@
},
}`),
},
- expectedError: "nothing should care if linker namespaces are enabled or not",
+ expectedErrors: []string{
+ "nothing should care if linker namespaces are enabled or not",
+ },
},
{
name: "libc_bionic_ndk treble_linker_namespaces.cflags",
@@ -186,7 +202,6 @@
},
}`),
},
- expectedError: "",
},
{
name: "java_device_for_host",
@@ -197,7 +212,9 @@
libs: ["core-libart"],
}`),
},
- expectedError: "java_device_for_host can only be used in whitelisted projects",
+ expectedErrors: []string{
+ "java_device_for_host can only be used in whitelisted projects",
+ },
},
// Libcore rule tests
{
@@ -219,7 +236,9 @@
sdk_version: "none",
}`),
},
- expectedError: "module \"outside_core_libraries\": violates neverallow",
+ expectedErrors: []string{
+ "module \"outside_core_libraries\": violates neverallow",
+ },
},
{
name: "sdk_version: \"current\"",
@@ -234,22 +253,22 @@
}
func TestNeverallow(t *testing.T) {
- config := TestConfig(buildDir, nil)
-
for _, test := range neverallowTests {
- t.Run(test.name, func(t *testing.T) {
- _, errs := testNeverallow(t, config, test.fs)
+ // Create a test per config to allow for test specific config, e.g. test rules.
+ config := TestConfig(buildDir, nil)
- if test.expectedError == "" {
- FailIfErrored(t, errs)
- } else {
- FailIfNoMatchingErrors(t, test.expectedError, errs)
+ t.Run(test.name, func(t *testing.T) {
+ // If the test has its own rules then use them instead of the default ones.
+ if test.rules != nil {
+ setTestNeverallowRules(config, test.rules)
}
+ _, errs := testNeverallow(config, test.fs)
+ CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
})
}
}
-func testNeverallow(t *testing.T, config Config, fs map[string][]byte) (*TestContext, []error) {
+func testNeverallow(config Config, fs map[string][]byte) (*TestContext, []error) {
ctx := NewTestContext()
ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule))
ctx.RegisterModuleType("java_library", ModuleFactoryAdaptor(newMockJavaLibraryModule))
diff --git a/android/testing.go b/android/testing.go
index b59f399..447ffd6 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -372,6 +372,29 @@
}
}
+func CheckErrorsAgainstExpectations(t *testing.T, errs []error, expectedErrorPatterns []string) {
+ t.Helper()
+
+ if expectedErrorPatterns == nil {
+ FailIfErrored(t, errs)
+ } else {
+ for _, expectedError := range expectedErrorPatterns {
+ FailIfNoMatchingErrors(t, expectedError, errs)
+ }
+ if len(errs) > len(expectedErrorPatterns) {
+ t.Errorf("additional errors found, expected %d, found %d",
+ len(expectedErrorPatterns), len(errs))
+ for i, expectedError := range expectedErrorPatterns {
+ t.Errorf("expectedErrors[%d] = %s", i, expectedError)
+ }
+ for i, err := range errs {
+ t.Errorf("errs[%d] = %s", i, err)
+ }
+ }
+ }
+
+}
+
func AndroidMkEntriesForTest(t *testing.T, config Config, bpPath string, mod blueprint.Module) AndroidMkEntries {
var p AndroidMkEntriesProvider
var ok bool
diff --git a/android/visibility_test.go b/android/visibility_test.go
index c44dc9e..d13fadf 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -860,23 +860,7 @@
t.Run(test.name, func(t *testing.T) {
_, errs := testVisibility(buildDir, test.fs)
- expectedErrors := test.expectedErrors
- if expectedErrors == nil {
- FailIfErrored(t, errs)
- } else {
- for _, expectedError := range expectedErrors {
- FailIfNoMatchingErrors(t, expectedError, errs)
- }
- if len(errs) > len(expectedErrors) {
- t.Errorf("additional errors found, expected %d, found %d", len(expectedErrors), len(errs))
- for i, expectedError := range expectedErrors {
- t.Errorf("expectedErrors[%d] = %s", i, expectedError)
- }
- for i, err := range errs {
- t.Errorf("errs[%d] = %s", i, err)
- }
- }
- }
+ CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
})
}
}