123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- // 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 (
- "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 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/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{
- `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
- },
- },
- // 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 can reference another location",
- 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: "dependency on updatable-media",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- java_library {
- name: "needs_updatable_media",
- libs: ["updatable-media"],
- }`),
- },
- expectedErrors: []string{
- "updatable-media includes private APIs. Use updatable_media_stubs instead.",
- },
- },
- {
- 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",
- },
- },
- // Libcore rule tests
- {
- name: "sdk_version: \"none\" inside core libraries",
- fs: map[string][]byte{
- "libcore/Android.bp": []byte(`
- java_library {
- name: "inside_core_libraries",
- sdk_version: "none",
- }`),
- },
- },
- {
- name: "sdk_version: \"none\" on android_*stubs_current stub",
- fs: map[string][]byte{
- "frameworks/base/Android.bp": []byte(`
- java_library {
- name: "android_stubs_current",
- sdk_version: "none",
- }`),
- },
- },
- {
- name: "sdk_version: \"none\" outside core libraries",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- java_library {
- name: "outside_core_libraries",
- sdk_version: "none",
- }`),
- },
- expectedErrors: []string{
- "module \"outside_core_libraries\": violates neverallow",
- },
- },
- {
- name: "sdk_version: \"current\"",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- java_library {
- name: "outside_core_libraries",
- sdk_version: "current",
- }`),
- },
- },
- // 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",
- },
- },
- {
- name: "disallowed makefile_goal",
- fs: map[string][]byte{
- "Android.bp": []byte(`
- makefile_goal {
- name: "foo",
- product_out_path: "boot/trap.img"
- }
- `),
- },
- expectedErrors: []string{
- "Only boot images may be imported as a makefile goal.",
- },
- },
- }
- func TestNeverallow(t *testing.T) {
- for _, test := range neverallowTests {
- // Create a test per config to allow for test specific config, e.g. test rules.
- config := TestConfig(buildDir, nil, "", test.fs)
- 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)
- CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
- })
- }
- }
- func testNeverallow(config Config) (*TestContext, []error) {
- ctx := NewTestContext()
- ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
- ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
- ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
- ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
- ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
- ctx.PostDepsMutators(RegisterNeverallowMutator)
- ctx.Register(config)
- _, errs := ctx.ParseBlueprintsFiles("Android.bp")
- if len(errs) > 0 {
- return ctx, errs
- }
- _, errs = ctx.PrepareBuildActions(config)
- return ctx, errs
- }
- 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
- }
- }
- 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
- }
- type mockJavaLibraryModule struct {
- ModuleBase
- properties mockJavaLibraryProperties
- }
- func newMockJavaLibraryModule() Module {
- m := &mockJavaLibraryModule{}
- m.AddProperties(&m.properties)
- InitAndroidModule(m)
- return m
- }
- func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
- }
- type mockMakefileGoalProperties struct {
- Product_out_path *string
- }
- type mockMakefileGoalModule struct {
- ModuleBase
- properties mockMakefileGoalProperties
- }
- func newMockMakefileGoalModule() Module {
- m := &mockMakefileGoalModule{}
- m.AddProperties(&m.properties)
- InitAndroidModule(m)
- return m
- }
- func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
- }
|