From 3b33eaa1c90cdf1af7204affb8e30a387e57ee76 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Thu, 8 Mar 2018 18:14:19 +0800 Subject: [PATCH 1/5] Add unit tests for android/util.go Bug: 62815515 Test: lunch aosp_sailfish-userdebug && make # runs soong unit tests Merged-In: I34f06abdc78bfb28af3b5250491bbcddb7595c9b Change-Id: I34f06abdc78bfb28af3b5250491bbcddb7595c9b --- android/util_test.go | 182 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/android/util_test.go b/android/util_test.go index 32f92b46c..dc8b9080c 100644 --- a/android/util_test.go +++ b/android/util_test.go @@ -118,3 +118,185 @@ func TestLastUniqueStrings(t *testing.T) { } } } + +func TestJoinWithPrefix(t *testing.T) { + testcases := []struct { + name string + input []string + expected string + }{ + { + name: "zero_inputs", + input: []string{}, + expected: "", + }, + { + name: "one_input", + input: []string{"a"}, + expected: "prefix:a", + }, + { + name: "two_inputs", + input: []string{"a", "b"}, + expected: "prefix:a prefix:b", + }, + } + + prefix := "prefix:" + + for _, testCase := range testcases { + t.Run(testCase.name, func(t *testing.T) { + out := JoinWithPrefix(testCase.input, prefix) + if out != testCase.expected { + t.Errorf("incorrect output:") + t.Errorf(" input: %#v", testCase.input) + t.Errorf(" prefix: %#v", prefix) + t.Errorf(" expected: %#v", testCase.expected) + t.Errorf(" got: %#v", out) + } + }) + } +} + +func TestIndexList(t *testing.T) { + input := []string{"a", "b", "c"} + + testcases := []struct { + key string + expected int + }{ + { + key: "a", + expected: 0, + }, + { + key: "b", + expected: 1, + }, + { + key: "c", + expected: 2, + }, + { + key: "X", + expected: -1, + }, + } + + for _, testCase := range testcases { + t.Run(testCase.key, func(t *testing.T) { + out := IndexList(testCase.key, input) + if out != testCase.expected { + t.Errorf("incorrect output:") + t.Errorf(" key: %#v", testCase.key) + t.Errorf(" input: %#v", input) + t.Errorf(" expected: %#v", testCase.expected) + t.Errorf(" got: %#v", out) + } + }) + } +} + +func TestInList(t *testing.T) { + input := []string{"a"} + + testcases := []struct { + key string + expected bool + }{ + { + key: "a", + expected: true, + }, + { + key: "X", + expected: false, + }, + } + + for _, testCase := range testcases { + t.Run(testCase.key, func(t *testing.T) { + out := InList(testCase.key, input) + if out != testCase.expected { + t.Errorf("incorrect output:") + t.Errorf(" key: %#v", testCase.key) + t.Errorf(" input: %#v", input) + t.Errorf(" expected: %#v", testCase.expected) + t.Errorf(" got: %#v", out) + } + }) + } +} + +func TestPrefixInList(t *testing.T) { + prefixes := []string{"a", "b"} + + testcases := []struct { + str string + expected bool + }{ + { + str: "a-example", + expected: true, + }, + { + str: "b-example", + expected: true, + }, + { + str: "X-example", + expected: false, + }, + } + + for _, testCase := range testcases { + t.Run(testCase.str, func(t *testing.T) { + out := PrefixInList(testCase.str, prefixes) + if out != testCase.expected { + t.Errorf("incorrect output:") + t.Errorf(" str: %#v", testCase.str) + t.Errorf(" prefixes: %#v", prefixes) + t.Errorf(" expected: %#v", testCase.expected) + t.Errorf(" got: %#v", out) + } + }) + } +} + +func TestFilterList(t *testing.T) { + input := []string{"a", "b", "c", "c", "b", "d", "a"} + filter := []string{"a", "c"} + remainder, filtered := FilterList(input, filter) + + expected := []string{"b", "b", "d"} + if !reflect.DeepEqual(remainder, expected) { + t.Errorf("incorrect remainder output:") + t.Errorf(" input: %#v", input) + t.Errorf(" filter: %#v", filter) + t.Errorf(" expected: %#v", expected) + t.Errorf(" got: %#v", remainder) + } + + expected = []string{"a", "c", "c", "a"} + if !reflect.DeepEqual(filtered, expected) { + t.Errorf("incorrect filtered output:") + t.Errorf(" input: %#v", input) + t.Errorf(" filter: %#v", filter) + t.Errorf(" expected: %#v", expected) + t.Errorf(" got: %#v", filtered) + } +} + +func TestRemoveListFromList(t *testing.T) { + input := []string{"a", "b", "c", "d", "a", "c", "d"} + filter := []string{"a", "c"} + expected := []string{"b", "d", "d"} + out := RemoveListFromList(input, filter) + if !reflect.DeepEqual(out, expected) { + t.Errorf("incorrect output:") + t.Errorf(" input: %#v", input) + t.Errorf(" filter: %#v", filter) + t.Errorf(" expected: %#v", expected) + t.Errorf(" got: %#v", out) + } +} From 3985402d74c7743724daecfc68dc10388cb870d9 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Tue, 6 Mar 2018 18:29:27 +0800 Subject: [PATCH 2/5] RemoveFromList() should remove all matches RemoveFromList() should remove all matches. Before this commit, RemoveFromList() only removes the first match. This commit rewrites RemoveFromList() so that it will remove all matches. Besides, a unit test is written. Note: aosp/461936 wants to make sure libc.so precedes libdl.so in DT_NEEDED entries. However, if there are two "libdl" in shared_libs, aosp/461936 won't achieve its goal because RemoveFromList() (prior to this commit) only removes the first "libdl". Bug: 62815515 Test: Build sailfish and check libstagefright.so Merged-In: I9bec563cbf800bff4bd508fb21e28869a92cfe56 Change-Id: I9bec563cbf800bff4bd508fb21e28869a92cfe56 --- android/util.go | 13 +++++++--- android/util_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/android/util.go b/android/util.go index 854d78280..e9b976435 100644 --- a/android/util.go +++ b/android/util.go @@ -101,11 +101,18 @@ func RemoveListFromList(list []string, filter_out []string) (result []string) { func RemoveFromList(s string, list []string) (bool, []string) { i := IndexList(s, list) - if i != -1 { - return true, append(list[:i], list[i+1:]...) - } else { + if i == -1 { return false, list } + + result := make([]string, 0, len(list)-1) + result = append(result, list[:i]...) + for _, l := range list[i+1:] { + if l != s { + result = append(result, l) + } + } + return true, result } // FirstUniqueStrings returns all unique elements of a slice of strings, keeping the first copy of diff --git a/android/util_test.go b/android/util_test.go index dc8b9080c..1c791b240 100644 --- a/android/util_test.go +++ b/android/util_test.go @@ -300,3 +300,62 @@ func TestRemoveListFromList(t *testing.T) { t.Errorf(" got: %#v", out) } } + +func TestRemoveFromList(t *testing.T) { + testcases := []struct { + name string + key string + input []string + expectedFound bool + expectedOut []string + }{ + { + name: "remove_one_match", + key: "a", + input: []string{"a", "b", "c"}, + expectedFound: true, + expectedOut: []string{"b", "c"}, + }, + { + name: "remove_three_matches", + key: "a", + input: []string{"a", "b", "a", "c", "a"}, + expectedFound: true, + expectedOut: []string{"b", "c"}, + }, + { + name: "remove_zero_matches", + key: "X", + input: []string{"a", "b", "a", "c", "a"}, + expectedFound: false, + expectedOut: []string{"a", "b", "a", "c", "a"}, + }, + { + name: "remove_all_matches", + key: "a", + input: []string{"a", "a", "a", "a"}, + expectedFound: true, + expectedOut: []string{}, + }, + } + + for _, testCase := range testcases { + t.Run(testCase.name, func(t *testing.T) { + found, out := RemoveFromList(testCase.key, testCase.input) + if found != testCase.expectedFound { + t.Errorf("incorrect output:") + t.Errorf(" key: %#v", testCase.key) + t.Errorf(" input: %#v", testCase.input) + t.Errorf(" expected: %#v", testCase.expectedFound) + t.Errorf(" got: %#v", found) + } + if !reflect.DeepEqual(out, testCase.expectedOut) { + t.Errorf("incorrect output:") + t.Errorf(" key: %#v", testCase.key) + t.Errorf(" input: %#v", testCase.input) + t.Errorf(" expected: %#v", testCase.expectedOut) + t.Errorf(" got: %#v", out) + } + }) + } +} From d44aa3b5c8afbfeb66e39668bab3ec0fac63f1e6 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Mon, 12 Mar 2018 16:29:17 +0800 Subject: [PATCH 3/5] Extract failIfErrored() to android/testing.go Bug: 74506774 Test: lunch aosp_walleye-userdebug && make # runs unit tests Merged-In: I1c09412d5988dca2cc1c5f041893b313ab1c163a Change-Id: I1c09412d5988dca2cc1c5f041893b313ab1c163a --- android/namespace_test.go | 11 +---------- android/prebuilt_test.go | 13 ++----------- android/testing.go | 11 +++++++++++ cc/cc_test.go | 13 ++----------- cc/test_data_test.go | 13 ++----------- java/java_test.go | 14 ++------------ python/python_test.go | 13 ++----------- 7 files changed, 22 insertions(+), 66 deletions(-) diff --git a/android/namespace_test.go b/android/namespace_test.go index a6fc9d592..8bec0add1 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -628,7 +628,7 @@ func setupTestExpectErrs(bps map[string]string) (ctx *TestContext, errs []error) func setupTest(t *testing.T, bps map[string]string) (ctx *TestContext) { ctx, errs := setupTestExpectErrs(bps) - failIfErrored(t, errs) + FailIfErrored(t, errs) return ctx } @@ -692,12 +692,3 @@ func newTestModule() Module { InitAndroidModule(m) return m } - -func failIfErrored(t *testing.T, errs []error) { - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 93f580535..69ce16a3c 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -138,9 +138,9 @@ func TestPrebuilts(t *testing.T) { }) _, errs := ctx.ParseBlueprintsFiles("Blueprints") - fail(t, errs) + FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) - fail(t, errs) + FailIfErrored(t, errs) foo := ctx.ModuleForTests("foo", "") @@ -231,12 +231,3 @@ func (s *sourceModule) DepsMutator(ctx BottomUpMutatorContext) { func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) { } - -func fail(t *testing.T, errs []error) { - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} diff --git a/android/testing.go b/android/testing.go index ae012b06e..6e80c5326 100644 --- a/android/testing.go +++ b/android/testing.go @@ -18,6 +18,7 @@ import ( "fmt" "path/filepath" "strings" + "testing" "github.com/google/blueprint" ) @@ -152,3 +153,13 @@ func (m TestingModule) Output(file string) BuildParams { panic(fmt.Errorf("couldn't find output %q.\nall outputs: %v", file, searchedOutputs)) } + +func FailIfErrored(t *testing.T, errs []error) { + t.Helper() + if len(errs) > 0 { + for _, err := range errs { + t.Error(err) + } + t.FailNow() + } +} diff --git a/cc/cc_test.go b/cc/cc_test.go index 19e4703b3..632960568 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -147,9 +147,9 @@ func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.T ctx := createTestContext(t, config, bp) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - failIfErrored(t, errs) + android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) - failIfErrored(t, errs) + android.FailIfErrored(t, errs) return ctx } @@ -1064,15 +1064,6 @@ func TestLinkReordering(t *testing.T) { } } -func failIfErrored(t *testing.T, errs []error) { - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} - func failIfNoMatchingErrors(t *testing.T, pattern string, errs []error) { matcher, err := regexp.Compile(pattern) if err != nil { diff --git a/cc/test_data_test.go b/cc/test_data_test.go index 434edcdf6..4a7b0f756 100644 --- a/cc/test_data_test.go +++ b/cc/test_data_test.go @@ -135,9 +135,9 @@ func TestDataTests(t *testing.T) { ctx.Register() _, errs := ctx.ParseBlueprintsFiles("Blueprints") - fail(t, errs) + android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) - fail(t, errs) + android.FailIfErrored(t, errs) foo := ctx.ModuleForTests("foo", "") @@ -186,12 +186,3 @@ func (test *testDataTest) DepsMutator(ctx android.BottomUpMutatorContext) { func (test *testDataTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { test.data = ctx.ExpandSources(test.Properties.Data, nil) } - -func fail(t *testing.T, errs []error) { - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} diff --git a/java/java_test.go b/java/java_test.go index 5d6a6e0e8..6ef406f76 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -190,9 +190,9 @@ func testContext(config android.Config, bp string, func run(t *testing.T, ctx *android.TestContext, config android.Config) { t.Helper() _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - fail(t, errs) + android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) - fail(t, errs) + android.FailIfErrored(t, errs) } func testJava(t *testing.T, bp string) *android.TestContext { @@ -977,13 +977,3 @@ func TestExcludeFileGroupInSrcs(t *testing.T) { t.Errorf(`foo inputs %v != ["java-fg/c.java"]`, javac.Inputs) } } - -func fail(t *testing.T, errs []error) { - t.Helper() - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} diff --git a/python/python_test.go b/python/python_test.go index 176c6eca0..ad80167e7 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -347,7 +347,7 @@ func TestPythonModule(t *testing.T) { ctx.Register() ctx.MockFileSystem(d.mockFiles) _, testErrs := ctx.ParseBlueprintsFiles(bpFile) - fail(t, testErrs) + android.FailIfErrored(t, testErrs) _, actErrs := ctx.PrepareBuildActions(config) if len(actErrs) > 0 { testErrs = append(testErrs, expectErrors(t, actErrs, d.errors)...) @@ -360,7 +360,7 @@ func TestPythonModule(t *testing.T) { e.parSpec, e.depsParSpecs)...) } } - fail(t, testErrs) + android.FailIfErrored(t, testErrs) }) } } @@ -458,12 +458,3 @@ func setupBuildEnv(t *testing.T) (config android.Config, buildDir string) { func tearDownBuildEnv(buildDir string) { os.RemoveAll(buildDir) } - -func fail(t *testing.T, errs []error) { - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} From b1ed497ca81762b5f431f08e3f1bbca8fc94bfa1 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Mon, 12 Mar 2018 16:34:26 +0800 Subject: [PATCH 4/5] Add unit tests for android/neverallow.go Bug: 74506774 Test: lunch aosp_walleye-userdebug && make # runs unit tests Merged-In: Ibde685d7213713be219681cb039ad58a43d9c377 Change-Id: Ibde685d7213713be219681cb039ad58a43d9c377 --- Android.bp | 1 + android/neverallow_test.go | 195 +++++++++++++++++++++++++++++++++++++ android/testing.go | 24 +++++ cc/cc_test.go | 28 +----- 4 files changed, 222 insertions(+), 26 deletions(-) create mode 100644 android/neverallow_test.go diff --git a/Android.bp b/Android.bp index 1d2c5167f..00db8f2da 100644 --- a/Android.bp +++ b/Android.bp @@ -71,6 +71,7 @@ bootstrap_go_package { "android/config_test.go", "android/expand_test.go", "android/namespace_test.go", + "android/neverallow_test.go", "android/paths_test.go", "android/prebuilt_test.go", "android/util_test.go", diff --git a/android/neverallow_test.go b/android/neverallow_test.go new file mode 100644 index 000000000..19eeb222d --- /dev/null +++ b/android/neverallow_test.go @@ -0,0 +1,195 @@ +// Copyright 2018 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 android + +import ( + "io/ioutil" + "os" + "testing" +) + +var neverallowTests = []struct { + name string + fs map[string][]byte + expectedError string +}{ + { + name: "no vndk.enabled under vendor directory", + fs: map[string][]byte{ + "vendor/Blueprints": []byte(` + cc_library { + name: "libvndk", + vendor_available: true, + vndk: { + enabled: true, + }, + }`), + }, + expectedError: "VNDK can never contain a library that is device dependent", + }, + { + name: "no vndk.enabled under device directory", + fs: map[string][]byte{ + "device/Blueprints": []byte(` + cc_library { + name: "libvndk", + vendor_available: true, + vndk: { + enabled: true, + }, + }`), + }, + expectedError: "VNDK can never contain a library that is device dependent", + }, + + { + name: "no enforce_vintf_manifest.cflags", + fs: map[string][]byte{ + "Blueprints": []byte(` + cc_library { + name: "libexample", + product_variables: { + enforce_vintf_manifest: { + cflags: ["-DSHOULD_NOT_EXIST"], + }, + }, + }`), + }, + expectedError: "manifest enforcement should be independent", + }, + { + name: "libhidltransport enforce_vintf_manifest.cflags", + fs: map[string][]byte{ + "Blueprints": []byte(` + cc_library { + name: "libhidltransport", + product_variables: { + enforce_vintf_manifest: { + cflags: ["-DSHOULD_NOT_EXIST"], + }, + }, + }`), + }, + expectedError: "", + }, + + { + name: "no treble_linker_namespaces.cflags", + fs: map[string][]byte{ + "Blueprints": []byte(` + cc_library { + name: "libexample", + product_variables: { + treble_linker_namespaces: { + cflags: ["-DSHOULD_NOT_EXIST"], + }, + }, + }`), + }, + expectedError: "nothing should care if linker namespaces are enabled or not", + }, + { + name: "libc_bionic_ndk treble_linker_namespaces.cflags", + fs: map[string][]byte{ + "Blueprints": []byte(` + cc_library { + name: "libc_bionic_ndk", + product_variables: { + treble_linker_namespaces: { + cflags: ["-DSHOULD_NOT_EXIST"], + }, + }, + }`), + }, + expectedError: "", + }, +} + +func TestNeverallow(t *testing.T) { + buildDir, err := ioutil.TempDir("", "soong_neverallow_test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(buildDir) + + 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) + } + }) + } +} + +func testNeverallow(t *testing.T, config Config, fs map[string][]byte) (*TestContext, []error) { + ctx := NewTestContext() + ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule)) + ctx.PostDepsMutators(registerNeverallowMutator) + ctx.Register() + + ctx.MockFileSystem(fs) + + _, errs := ctx.ParseBlueprintsFiles("Blueprints") + if len(errs) > 0 { + return ctx, errs + } + + _, errs = ctx.PrepareBuildActions(config) + return ctx, errs +} + +type mockProperties struct { + Vendor_available *bool + + Vndk struct { + Enabled *bool + Support_system_process *bool + Extends *string + } + + Product_variables struct { + Enforce_vintf_manifest struct { + Cflags []string + } + + Treble_linker_namespaces struct { + Cflags []string + } + } +} + +type mockCcLibraryModule struct { + ModuleBase + properties mockProperties +} + +func newMockCcLibraryModule() Module { + m := &mockCcLibraryModule{} + m.AddProperties(&m.properties) + InitAndroidModule(m) + return m +} + +func (p *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) { +} + +func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) { +} diff --git a/android/testing.go b/android/testing.go index 6e80c5326..f5d33e11a 100644 --- a/android/testing.go +++ b/android/testing.go @@ -17,6 +17,7 @@ package android import ( "fmt" "path/filepath" + "regexp" "strings" "testing" @@ -163,3 +164,26 @@ func FailIfErrored(t *testing.T, errs []error) { t.FailNow() } } + +func FailIfNoMatchingErrors(t *testing.T, pattern string, errs []error) { + t.Helper() + + matcher, err := regexp.Compile(pattern) + if err != nil { + t.Errorf("failed to compile regular expression %q because %s", pattern, err) + } + + found := false + for _, err := range errs { + if matcher.FindStringIndex(err.Error()) != nil { + found = true + break + } + } + if !found { + t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs)) + for i, err := range errs { + t.Errorf("errs[%d] = %s", i, err) + } + } +} diff --git a/cc/cc_test.go b/cc/cc_test.go index 632960568..2efee59d6 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -22,7 +22,6 @@ import ( "io/ioutil" "os" "reflect" - "regexp" "sort" "strings" "testing" @@ -178,13 +177,13 @@ func testCcError(t *testing.T, pattern string, bp string) { _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) if len(errs) > 0 { - failIfNoMatchingErrors(t, pattern, errs) + android.FailIfNoMatchingErrors(t, pattern, errs) return } _, errs = ctx.PrepareBuildActions(config) if len(errs) > 0 { - failIfNoMatchingErrors(t, pattern, errs) + android.FailIfNoMatchingErrors(t, pattern, errs) return } @@ -1064,29 +1063,6 @@ func TestLinkReordering(t *testing.T) { } } -func failIfNoMatchingErrors(t *testing.T, pattern string, errs []error) { - matcher, err := regexp.Compile(pattern) - if err != nil { - t.Errorf("failed to compile regular expression %q because %s", pattern, err) - } - - found := false - - for _, err := range errs { - if matcher.FindStringIndex(err.Error()) != nil { - found = true - break - } - } - - if !found { - t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs)) - for i, err := range errs { - t.Errorf("errs[%d] = %s", i, err) - } - } -} - func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) { for _, moduleName := range moduleNames { module := ctx.ModuleForTests(moduleName, variant).Module().(*Module) From 24e716e60367e1e1ac2953f48491717c7e364703 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Mon, 12 Mar 2018 16:35:58 +0800 Subject: [PATCH 5/5] Allow VNDK extensions under vendor or device This commit allows VNDK extensions (vndk.enabled:true and vendor:true) to reside under vendor/* or device/*. VNDK extensions will be installed into /vendor/lib[64]/vndk[-sp]. It is reasonable for their source being under vendor/* or device/*. Bug: 74506774 Test: lunch aosp_walleye-userdebug && make # runs unit tests Merged-In: I406c5bef10f5c549371dd978b8ecc16c65a7af4b Change-Id: I406c5bef10f5c549371dd978b8ecc16c65a7af4b --- android/neverallow.go | 10 ++++++++-- android/neverallow_test.go | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/android/neverallow.go b/android/neverallow.go index 261f2eeed..8fba4b902 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -46,9 +46,15 @@ func registerNeverallowMutator(ctx RegisterMutatorsContext) { } var neverallows = []*rule{ - neverallow().in("vendor", "device").with("vndk.enabled", "true"). + neverallow(). + in("vendor", "device"). + with("vndk.enabled", "true"). + without("vendor", "true"). because("the VNDK can never contain a library that is device dependent."), - neverallow().with("vndk.enabled", "true").without("owner", ""). + neverallow(). + with("vndk.enabled", "true"). + without("vendor", "true"). + without("owner", ""). because("a VNDK module can never have an owner."), neverallow().notIn("libcore").with("no_standard_libs", "true"), diff --git a/android/neverallow_test.go b/android/neverallow_test.go index 19eeb222d..a27836543 100644 --- a/android/neverallow_test.go +++ b/android/neverallow_test.go @@ -53,6 +53,28 @@ var neverallowTests = []struct { }, expectedError: "VNDK can never contain a library that is device dependent", }, + { + name: "vndk-ext under vendor or device directory", + fs: map[string][]byte{ + "device/Blueprints": []byte(` + cc_library { + name: "libvndk1_ext", + vendor: true, + vndk: { + enabled: true, + }, + }`), + "vendor/Blueprints": []byte(` + cc_library { + name: "libvndk2_ext", + vendor: true, + vndk: { + enabled: true, + }, + }`), + }, + expectedError: "", + }, { name: "no enforce_vintf_manifest.cflags",