blob: 45845859728abf383c41b3a1c73d46d77898705a [file] [log] [blame]
Logan Chienee97c3e2018-03-12 16:34:26 +08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
Logan Chienee97c3e2018-03-12 16:34:26 +080018 "testing"
Paul Duffin35781882019-07-25 15:41:09 +010019
20 "github.com/google/blueprint"
Logan Chienee97c3e2018-03-12 16:34:26 +080021)
22
23var neverallowTests = []struct {
Paul Duffin115445b2019-08-07 15:31:07 +010024 // The name of the test.
25 name string
26
27 // Optional test specific rules. If specified then they are used instead of the default rules.
28 rules []Rule
29
30 // Additional contents to add to the virtual filesystem used by the tests.
31 fs map[string][]byte
32
33 // The expected error patterns. If empty then no errors are expected, otherwise each error
34 // reported must be matched by at least one of these patterns. A pattern matches if the error
35 // message contains the pattern. A pattern does not have to match the whole error message.
Paul Duffin91e38192019-08-05 15:07:57 +010036 expectedErrors []string
Logan Chienee97c3e2018-03-12 16:34:26 +080037}{
Paul Duffin35781882019-07-25 15:41:09 +010038 // Test General Functionality
39
40 // in direct deps tests
41 {
42 name: "not_allowed_in_direct_deps",
Paul Duffin115445b2019-08-07 15:31:07 +010043 rules: []Rule{
44 NeverAllow().InDirectDeps("not_allowed_in_direct_deps"),
45 },
Paul Duffin35781882019-07-25 15:41:09 +010046 fs: map[string][]byte{
47 "top/Blueprints": []byte(`
48 cc_library {
49 name: "not_allowed_in_direct_deps",
50 }`),
51 "other/Blueprints": []byte(`
52 cc_library {
53 name: "libother",
54 static_libs: ["not_allowed_in_direct_deps"],
55 }`),
56 },
Paul Duffin91e38192019-08-05 15:07:57 +010057 expectedErrors: []string{
58 `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
59 },
Paul Duffin35781882019-07-25 15:41:09 +010060 },
61
Paul Duffin115445b2019-08-07 15:31:07 +010062 // Test android specific rules
Paul Duffin35781882019-07-25 15:41:09 +010063
Paul Duffin2ac2bef2019-07-16 14:18:22 +010064 // include_dir rule tests
65 {
66 name: "include_dir not allowed to reference art",
67 fs: map[string][]byte{
68 "other/Blueprints": []byte(`
69 cc_library {
70 name: "libother",
71 include_dirs: ["art/libdexfile/include"],
72 }`),
73 },
Paul Duffin91e38192019-08-05 15:07:57 +010074 expectedErrors: []string{
75 "all usages of 'art' have been migrated",
76 },
Paul Duffin2ac2bef2019-07-16 14:18:22 +010077 },
78 {
79 name: "include_dir can reference another location",
80 fs: map[string][]byte{
81 "other/Blueprints": []byte(`
82 cc_library {
83 name: "libother",
84 include_dirs: ["another/include"],
85 }`),
86 },
87 },
88 // Treble rule tests
Logan Chienee97c3e2018-03-12 16:34:26 +080089 {
90 name: "no vndk.enabled under vendor directory",
91 fs: map[string][]byte{
92 "vendor/Blueprints": []byte(`
93 cc_library {
94 name: "libvndk",
95 vendor_available: true,
96 vndk: {
97 enabled: true,
98 },
99 }`),
100 },
Paul Duffin91e38192019-08-05 15:07:57 +0100101 expectedErrors: []string{
102 "VNDK can never contain a library that is device dependent",
103 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800104 },
105 {
106 name: "no vndk.enabled under device directory",
107 fs: map[string][]byte{
108 "device/Blueprints": []byte(`
109 cc_library {
110 name: "libvndk",
111 vendor_available: true,
112 vndk: {
113 enabled: true,
114 },
115 }`),
116 },
Paul Duffin91e38192019-08-05 15:07:57 +0100117 expectedErrors: []string{
118 "VNDK can never contain a library that is device dependent",
119 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800120 },
Logan Chienaf29bad2018-03-12 16:35:58 +0800121 {
122 name: "vndk-ext under vendor or device directory",
123 fs: map[string][]byte{
124 "device/Blueprints": []byte(`
125 cc_library {
126 name: "libvndk1_ext",
127 vendor: true,
128 vndk: {
129 enabled: true,
130 },
131 }`),
132 "vendor/Blueprints": []byte(`
133 cc_library {
134 name: "libvndk2_ext",
135 vendor: true,
136 vndk: {
137 enabled: true,
138 },
139 }`),
140 },
Logan Chienaf29bad2018-03-12 16:35:58 +0800141 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800142
143 {
144 name: "no enforce_vintf_manifest.cflags",
145 fs: map[string][]byte{
146 "Blueprints": []byte(`
147 cc_library {
148 name: "libexample",
149 product_variables: {
150 enforce_vintf_manifest: {
151 cflags: ["-DSHOULD_NOT_EXIST"],
152 },
153 },
154 }`),
155 },
Paul Duffin91e38192019-08-05 15:07:57 +0100156 expectedErrors: []string{
157 "manifest enforcement should be independent",
158 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800159 },
160 {
161 name: "libhidltransport enforce_vintf_manifest.cflags",
162 fs: map[string][]byte{
163 "Blueprints": []byte(`
164 cc_library {
165 name: "libhidltransport",
166 product_variables: {
167 enforce_vintf_manifest: {
168 cflags: ["-DSHOULD_NOT_EXIST"],
169 },
170 },
171 }`),
172 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800173 },
174
175 {
176 name: "no treble_linker_namespaces.cflags",
177 fs: map[string][]byte{
178 "Blueprints": []byte(`
179 cc_library {
180 name: "libexample",
181 product_variables: {
182 treble_linker_namespaces: {
183 cflags: ["-DSHOULD_NOT_EXIST"],
184 },
185 },
186 }`),
187 },
Paul Duffin91e38192019-08-05 15:07:57 +0100188 expectedErrors: []string{
189 "nothing should care if linker namespaces are enabled or not",
190 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800191 },
192 {
193 name: "libc_bionic_ndk treble_linker_namespaces.cflags",
194 fs: map[string][]byte{
195 "Blueprints": []byte(`
196 cc_library {
197 name: "libc_bionic_ndk",
198 product_variables: {
199 treble_linker_namespaces: {
200 cflags: ["-DSHOULD_NOT_EXIST"],
201 },
202 },
203 }`),
204 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800205 },
Neil Fullerdf5f3562018-10-21 17:19:10 +0100206 {
Colin Crossc35c5f92019-03-05 15:06:16 -0800207 name: "java_device_for_host",
208 fs: map[string][]byte{
209 "Blueprints": []byte(`
210 java_device_for_host {
211 name: "device_for_host",
212 libs: ["core-libart"],
213 }`),
214 },
Paul Duffin91e38192019-08-05 15:07:57 +0100215 expectedErrors: []string{
216 "java_device_for_host can only be used in whitelisted projects",
217 },
Colin Crossc35c5f92019-03-05 15:06:16 -0800218 },
Paul Duffinb6c6bdd2019-06-07 11:43:55 +0100219 // Libcore rule tests
220 {
Paul Duffin52d398a2019-06-11 12:31:14 +0100221 name: "sdk_version: \"none\" inside core libraries",
222 fs: map[string][]byte{
223 "libcore/Blueprints": []byte(`
224 java_library {
225 name: "inside_core_libraries",
226 sdk_version: "none",
227 }`),
228 },
229 },
230 {
231 name: "sdk_version: \"none\" outside core libraries",
232 fs: map[string][]byte{
233 "Blueprints": []byte(`
234 java_library {
235 name: "outside_core_libraries",
236 sdk_version: "none",
237 }`),
238 },
Paul Duffin91e38192019-08-05 15:07:57 +0100239 expectedErrors: []string{
240 "module \"outside_core_libraries\": violates neverallow",
241 },
Paul Duffin52d398a2019-06-11 12:31:14 +0100242 },
243 {
244 name: "sdk_version: \"current\"",
245 fs: map[string][]byte{
246 "Blueprints": []byte(`
247 java_library {
248 name: "outside_core_libraries",
249 sdk_version: "current",
250 }`),
251 },
252 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800253}
254
255func TestNeverallow(t *testing.T) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800256 for _, test := range neverallowTests {
Paul Duffin115445b2019-08-07 15:31:07 +0100257 // Create a test per config to allow for test specific config, e.g. test rules.
258 config := TestConfig(buildDir, nil)
Logan Chienee97c3e2018-03-12 16:34:26 +0800259
Paul Duffin91e38192019-08-05 15:07:57 +0100260 t.Run(test.name, func(t *testing.T) {
Paul Duffin115445b2019-08-07 15:31:07 +0100261 // If the test has its own rules then use them instead of the default ones.
262 if test.rules != nil {
263 setTestNeverallowRules(config, test.rules)
264 }
Paul Duffin91e38192019-08-05 15:07:57 +0100265 _, errs := testNeverallow(config, test.fs)
266 CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
Logan Chienee97c3e2018-03-12 16:34:26 +0800267 })
268 }
269}
270
Paul Duffin91e38192019-08-05 15:07:57 +0100271func testNeverallow(config Config, fs map[string][]byte) (*TestContext, []error) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800272 ctx := NewTestContext()
273 ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule))
Neil Fullerdf5f3562018-10-21 17:19:10 +0100274 ctx.RegisterModuleType("java_library", ModuleFactoryAdaptor(newMockJavaLibraryModule))
Paul Duffinb815ada2019-06-11 13:54:26 +0100275 ctx.RegisterModuleType("java_library_host", ModuleFactoryAdaptor(newMockJavaLibraryModule))
Colin Crossc35c5f92019-03-05 15:06:16 -0800276 ctx.RegisterModuleType("java_device_for_host", ModuleFactoryAdaptor(newMockJavaLibraryModule))
Logan Chienee97c3e2018-03-12 16:34:26 +0800277 ctx.PostDepsMutators(registerNeverallowMutator)
278 ctx.Register()
279
280 ctx.MockFileSystem(fs)
281
282 _, errs := ctx.ParseBlueprintsFiles("Blueprints")
283 if len(errs) > 0 {
284 return ctx, errs
285 }
286
287 _, errs = ctx.PrepareBuildActions(config)
288 return ctx, errs
289}
290
Neil Fullerdf5f3562018-10-21 17:19:10 +0100291type mockCcLibraryProperties struct {
Paul Duffin2ac2bef2019-07-16 14:18:22 +0100292 Include_dirs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800293 Vendor_available *bool
Paul Duffin35781882019-07-25 15:41:09 +0100294 Static_libs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800295
296 Vndk struct {
297 Enabled *bool
298 Support_system_process *bool
299 Extends *string
300 }
301
302 Product_variables struct {
303 Enforce_vintf_manifest struct {
304 Cflags []string
305 }
306
307 Treble_linker_namespaces struct {
308 Cflags []string
309 }
310 }
311}
312
313type mockCcLibraryModule struct {
314 ModuleBase
Neil Fullerdf5f3562018-10-21 17:19:10 +0100315 properties mockCcLibraryProperties
Logan Chienee97c3e2018-03-12 16:34:26 +0800316}
317
318func newMockCcLibraryModule() Module {
319 m := &mockCcLibraryModule{}
320 m.AddProperties(&m.properties)
321 InitAndroidModule(m)
322 return m
323}
324
Paul Duffin35781882019-07-25 15:41:09 +0100325type neverallowTestDependencyTag struct {
326 blueprint.BaseDependencyTag
327 name string
328}
329
330var staticDepTag = neverallowTestDependencyTag{name: "static"}
331
332func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
333 for _, lib := range c.properties.Static_libs {
334 ctx.AddDependency(ctx.Module(), staticDepTag, lib)
335 }
336}
337
Logan Chienee97c3e2018-03-12 16:34:26 +0800338func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
339}
Neil Fullerdf5f3562018-10-21 17:19:10 +0100340
341type mockJavaLibraryProperties struct {
Paul Duffina3d09862019-06-11 13:40:47 +0100342 Libs []string
343 Sdk_version *string
Neil Fullerdf5f3562018-10-21 17:19:10 +0100344}
345
346type mockJavaLibraryModule struct {
347 ModuleBase
348 properties mockJavaLibraryProperties
349}
350
351func newMockJavaLibraryModule() Module {
352 m := &mockJavaLibraryModule{}
353 m.AddProperties(&m.properties)
354 InitAndroidModule(m)
355 return m
356}
357
Neil Fullerdf5f3562018-10-21 17:19:10 +0100358func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
359}