Support multiple expected errors in neverallow_test.go

Extracted some common code used by visibility_test.go and
neverallow_test.go into a new function CheckErrorsAgainstExpectations
in testing.go.

(cherry picked from commit 8e47e8bc4130b09c85ce8a129241a85b72889897)
Bug: 138428610
Test: m nothing
Change-Id: Iafbadf12c6ffdc4d9128fcfe7f15792df5cfd020
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 7f254b1..cfab4f9 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -28,9 +28,9 @@
 }
 
 var neverallowTests = []struct {
-	name          string
-	fs            map[string][]byte
-	expectedError string
+	name           string
+	fs             map[string][]byte
+	expectedErrors []string
 }{
 	// Test General Functionality
 
@@ -48,7 +48,9 @@
 					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
@@ -63,7 +65,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 +92,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 +108,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 +132,6 @@
 					},
 				}`),
 		},
-		expectedError: "",
 	},
 
 	{
@@ -140,7 +147,9 @@
 					},
 				}`),
 		},
-		expectedError: "manifest enforcement should be independent",
+		expectedErrors: []string{
+			"manifest enforcement should be independent",
+		},
 	},
 
 	{
@@ -156,7 +165,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",
@@ -171,7 +182,6 @@
 					},
 				}`),
 		},
-		expectedError: "",
 	},
 	{
 		name: "dependency on updatable-media",
@@ -182,7 +192,9 @@
 					libs: ["updatable-media"],
 				}`),
 		},
-		expectedError: "updatable-media includes private APIs. Use updatable_media_stubs instead.",
+		expectedErrors: []string{
+			"updatable-media includes private APIs. Use updatable_media_stubs instead.",
+		},
 	},
 	{
 		name: "java_device_for_host",
@@ -193,7 +205,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
 	{
@@ -215,7 +229,9 @@
 					sdk_version: "none",
 				}`),
 		},
-		expectedError: "module \"outside_core_libraries\": violates neverallow",
+		expectedErrors: []string{
+			"module \"outside_core_libraries\": violates neverallow",
+		},
 	},
 	{
 		name: "sdk_version: \"current\"",
@@ -233,19 +249,15 @@
 	config := TestConfig(buildDir, nil)
 
 	for _, test := range neverallowTests {
-		t.Run(test.name, func(t *testing.T) {
-			_, errs := testNeverallow(t, config, test.fs)
 
-			if test.expectedError == "" {
-				FailIfErrored(t, errs)
-			} else {
-				FailIfNoMatchingErrors(t, test.expectedError, errs)
-			}
+		t.Run(test.name, func(t *testing.T) {
+			_, 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)
 		})
 	}
 }