123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- // 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 (
- "regexp"
- "testing"
- "github.com/google/blueprint"
- )
- var neverallowTests = []struct {
- // 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 MockFS
- // 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/Android.bp": []byte(`
- cc_library {
- name: "not_allowed_in_direct_deps",
- }`),
- "other/Android.bp": []byte(`
- cc_library {
- name: "libother",
- static_libs: ["not_allowed_in_direct_deps"],
- }`),
- },
- expectedErrors: []string{
- regexp.QuoteMeta("module \"libother\": violates neverallow requirements. Not allowed:\n\tdep(s): [\"not_allowed_in_direct_deps\"]"),
- },
- },
- {
- name: "multiple constraints",
- rules: []Rule{
- NeverAllow().
- InDirectDeps("not_allowed_in_direct_deps").
- In("other").
- ModuleType("cc_library").
- NotIn("top").
- NotModuleType("cc_binary"),
- },
- fs: map[string][]byte{
- "top/Android.bp": []byte(`
- cc_library {
- name: "not_allowed_in_direct_deps",
- }`),
- "other/Android.bp": []byte(`
- cc_library {
- name: "libother",
- static_libs: ["not_allowed_in_direct_deps"],
- }`),
- },
- expectedErrors: []string{
- regexp.QuoteMeta(`module "libother": violates neverallow requirements. Not allowed:
- in dirs: ["other/"]
- module types: ["cc_library"]
- dep(s): ["not_allowed_in_direct_deps"]
- EXCEPT in dirs: ["top/"]
- EXCEPT module types: ["cc_binary"]`),
- },
- },
- // Test android specific rules
- // include_dir rule tests
- {
- name: "include_dir not allowed to reference art",
- fs: map[string][]byte{
- "other/Android.bp": []byte(`
- cc_library {
- name: "libother",
- include_dirs: ["art/libdexfile/include"],
- }`),
- },
- expectedErrors: []string{
- "all usages of 'art' have been migrated",
- },
- },
- {
- name: "include_dir not allowed to reference art",
- fs: map[string][]byte{
- "system/libfmq/Android.bp": []byte(`
- cc_library {
- name: "libother",
- include_dirs: ["any/random/file"],
- }`),
- },
- expectedErrors: []string{
- "all usages of them in 'system/libfmq' have been migrated",
- },
- },
- {
- name: "include_dir can work",
- fs: map[string][]byte{
- "other/Android.bp": []byte(`
- cc_library {
- name: "libother",
- include_dirs: ["another/include"],
- }`),
- },
- },
- // Treble rule tests
- {
- name: "no vndk.enabled under vendor directory",
- fs: map[string][]byte{
- "vendor/Android.bp": []byte(`
- cc_library {
- name: "libvndk",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
- }`),
- },
- expectedErrors: []string{
- "VNDK can never contain a library that is device dependent",
- },
- },
- {
- name: "no vndk.enabled under device directory",
- fs: map[string][]byte{
- "device/Android.bp": []byte(`
- cc_library {
- name: "libvndk",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
- }`),
- },
- expectedErrors: []string{
- "VNDK can never contain a library that is device dependent",
- },
- },
- {
- name: "vndk-ext under vendor or device directory",
- fs: map[string][]byte{
- "device/Android.bp": []byte(`
- cc_library {
- name: "libvndk1_ext",
- vendor: true,
- vndk: {
- enabled: true,
- },
- }`),
- "vendor/Android.bp": []byte(`
- cc_library {
- name: "libvndk2_ext",
- vendor: true,
- vndk: {
- enabled: true,
- },
- }`),
- },
- },
- {
- name: "no enforce_vintf_manifest.cflags",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "libexample",
- product_variables: {
- enforce_vintf_manifest: {
- cflags: ["-DSHOULD_NOT_EXIST"],
- },
- },
- }`),
- },
- expectedErrors: []string{
- "manifest enforcement should be independent",
- },
- },
- {
- name: "no treble_linker_namespaces.cflags",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "libexample",
- product_variables: {
- treble_linker_namespaces: {
- cflags: ["-DSHOULD_NOT_EXIST"],
- },
- },
- }`),
- },
- expectedErrors: []string{
- "nothing should care if linker namespaces are enabled or not",
- },
- },
- {
- name: "libc_bionic_ndk treble_linker_namespaces.cflags",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "libc_bionic_ndk",
- product_variables: {
- treble_linker_namespaces: {
- cflags: ["-DSHOULD_NOT_EXIST"],
- },
- },
- }`),
- },
- },
- {
- name: "java_device_for_host",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- java_device_for_host {
- name: "device_for_host",
- libs: ["core-libart"],
- }`),
- },
- expectedErrors: []string{
- "java_device_for_host can only be used in allowed projects",
- },
- },
- // CC sdk rule tests
- {
- name: `"sdk_variant_only" outside allowed list`,
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "outside_allowed_list",
- sdk_version: "current",
- sdk_variant_only: true,
- }`),
- },
- expectedErrors: []string{
- `module "outside_allowed_list": violates neverallow`,
- },
- },
- {
- name: `"sdk_variant_only: false" outside allowed list`,
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "outside_allowed_list",
- sdk_version: "current",
- sdk_variant_only: false,
- }`),
- },
- expectedErrors: []string{
- `module "outside_allowed_list": violates neverallow`,
- },
- },
- {
- name: `"platform" outside allowed list`,
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "outside_allowed_list",
- platform: {
- shared_libs: ["libfoo"],
- },
- }`),
- },
- expectedErrors: []string{
- `module "outside_allowed_list": violates neverallow`,
- },
- },
- {
- name: "uncompress_dex inside art",
- fs: map[string][]byte{
- "art/Android.bp": []byte(`
- java_library {
- name: "inside_art_libraries",
- uncompress_dex: true,
- }`),
- },
- },
- {
- name: "uncompress_dex outside art",
- fs: map[string][]byte{
- "other/Android.bp": []byte(`
- java_library {
- name: "outside_art_libraries",
- uncompress_dex: true,
- }`),
- },
- expectedErrors: []string{
- "module \"outside_art_libraries\": violates neverallow",
- },
- },
- // Tests for the rule prohibiting the use of framework
- {
- name: "prohibit framework",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- java_library {
- name: "foo",
- libs: ["framework"],
- sdk_version: "current",
- }`),
- },
- expectedErrors: []string{
- "framework can't be used when building against SDK",
- },
- },
- // Test for the rule restricting use of implementation_installable
- {
- name: `"implementation_installable" outside allowed list`,
- fs: map[string][]byte{
- "Android.bp": []byte(`
- cc_library {
- name: "outside_allowed_list",
- stubs: {
- implementation_installable: true,
- },
- }`),
- },
- expectedErrors: []string{
- `module "outside_allowed_list": violates neverallow`,
- },
- },
- // Test for the rule restricting use of exclude_static_libs
- {
- name: `"exclude_static_libs" outside allowed directory`,
- fs: map[string][]byte{
- "a/b/Android.bp": []byte(`
- java_library {
- name: "baz",
- exclude_static_libs: [
- "bar",
- ],
- }
- `),
- },
- expectedErrors: []string{
- `exclude_static_libs property is only allowed for java modules defined in build/soong, libcore, and frameworks/base/api`,
- },
- },
- }
- var prepareForNeverAllowTest = GroupFixturePreparers(
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
- ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
- ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
- ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
- }),
- )
- func TestNeverallow(t *testing.T) {
- for _, test := range neverallowTests {
- t.Run(test.name, func(t *testing.T) {
- GroupFixturePreparers(
- prepareForNeverAllowTest,
- PrepareForTestWithNeverallowRules(test.rules),
- test.fs.AddToFixture(),
- ).
- ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
- RunTest(t)
- })
- }
- }
- type mockCcLibraryProperties struct {
- Include_dirs []string
- Vendor_available *bool
- Static_libs []string
- Sdk_version *string
- Sdk_variant_only *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
- }
- }
- Platform struct {
- Shared_libs []string
- }
- Stubs struct {
- Implementation_installable *bool
- }
- }
- type mockCcLibraryModule struct {
- ModuleBase
- properties mockCcLibraryProperties
- }
- func newMockCcLibraryModule() Module {
- m := &mockCcLibraryModule{}
- m.AddProperties(&m.properties)
- InitAndroidModule(m)
- return m
- }
- type neverallowTestDependencyTag struct {
- blueprint.BaseDependencyTag
- name string
- }
- var staticDepTag = neverallowTestDependencyTag{name: "static"}
- func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
- for _, lib := range c.properties.Static_libs {
- ctx.AddDependency(ctx.Module(), staticDepTag, lib)
- }
- }
- func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
- }
- type mockJavaLibraryProperties struct {
- Libs []string
- Sdk_version *string
- Uncompress_dex *bool
- Exclude_static_libs []string
- }
- type mockJavaLibraryModule struct {
- ModuleBase
- properties mockJavaLibraryProperties
- }
- func newMockJavaLibraryModule() Module {
- m := &mockJavaLibraryModule{}
- m.AddProperties(&m.properties)
- InitAndroidModule(m)
- return m
- }
- func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
- }
|