blob: 18a8705019497d05368e1e7856b3d7800f1157a3 [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.
Paul Duffin3c6a4ea2021-03-16 23:41:40 +000031 fs MockFS
Paul Duffin115445b2019-08-07 15:31:07 +010032
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 Duffinb5af6202019-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{
Colin Cross98be1bb2019-12-13 20:41:13 -080047 "top/Android.bp": []byte(`
Paul Duffin35781882019-07-25 15:41:09 +010048 cc_library {
49 name: "not_allowed_in_direct_deps",
50 }`),
Colin Cross98be1bb2019-12-13 20:41:13 -080051 "other/Android.bp": []byte(`
Paul Duffin35781882019-07-25 15:41:09 +010052 cc_library {
53 name: "libother",
54 static_libs: ["not_allowed_in_direct_deps"],
55 }`),
56 },
Paul Duffinb5af6202019-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 Duffinc8111702019-07-22 12:13:55 +010064 // include_dir rule tests
65 {
66 name: "include_dir not allowed to reference art",
67 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -080068 "other/Android.bp": []byte(`
Paul Duffinc8111702019-07-22 12:13:55 +010069 cc_library {
70 name: "libother",
71 include_dirs: ["art/libdexfile/include"],
72 }`),
73 },
Paul Duffinb5af6202019-08-05 15:07:57 +010074 expectedErrors: []string{
75 "all usages of 'art' have been migrated",
76 },
Paul Duffinc8111702019-07-22 12:13:55 +010077 },
78 {
Steven Moreland8fc8dbf2021-04-27 02:31:07 +000079 name: "include_dir not allowed to reference art",
80 fs: map[string][]byte{
81 "system/libfmq/Android.bp": []byte(`
82 cc_library {
83 name: "libother",
84 include_dirs: ["any/random/file"],
85 }`),
86 },
87 expectedErrors: []string{
88 "all usages of them in 'system/libfmq' have been migrated",
89 },
90 },
91 {
92 name: "include_dir can work",
Paul Duffinc8111702019-07-22 12:13:55 +010093 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -080094 "other/Android.bp": []byte(`
Paul Duffinc8111702019-07-22 12:13:55 +010095 cc_library {
96 name: "libother",
97 include_dirs: ["another/include"],
98 }`),
99 },
100 },
101 // Treble rule tests
Logan Chienee97c3e2018-03-12 16:34:26 +0800102 {
103 name: "no vndk.enabled under vendor directory",
104 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800105 "vendor/Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800106 cc_library {
107 name: "libvndk",
108 vendor_available: true,
109 vndk: {
110 enabled: true,
111 },
112 }`),
113 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100114 expectedErrors: []string{
115 "VNDK can never contain a library that is device dependent",
116 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800117 },
118 {
119 name: "no vndk.enabled under device directory",
120 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800121 "device/Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800122 cc_library {
123 name: "libvndk",
124 vendor_available: true,
125 vndk: {
126 enabled: true,
127 },
128 }`),
129 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100130 expectedErrors: []string{
131 "VNDK can never contain a library that is device dependent",
132 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800133 },
Logan Chienaf29bad2018-03-12 16:35:58 +0800134 {
135 name: "vndk-ext under vendor or device directory",
136 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800137 "device/Android.bp": []byte(`
Logan Chienaf29bad2018-03-12 16:35:58 +0800138 cc_library {
139 name: "libvndk1_ext",
140 vendor: true,
141 vndk: {
142 enabled: true,
143 },
144 }`),
Colin Cross98be1bb2019-12-13 20:41:13 -0800145 "vendor/Android.bp": []byte(`
Logan Chienaf29bad2018-03-12 16:35:58 +0800146 cc_library {
147 name: "libvndk2_ext",
148 vendor: true,
149 vndk: {
150 enabled: true,
151 },
152 }`),
153 },
Logan Chienaf29bad2018-03-12 16:35:58 +0800154 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800155
156 {
157 name: "no enforce_vintf_manifest.cflags",
158 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800159 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800160 cc_library {
161 name: "libexample",
162 product_variables: {
163 enforce_vintf_manifest: {
164 cflags: ["-DSHOULD_NOT_EXIST"],
165 },
166 },
167 }`),
168 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100169 expectedErrors: []string{
170 "manifest enforcement should be independent",
171 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800172 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800173
174 {
175 name: "no treble_linker_namespaces.cflags",
176 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800177 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800178 cc_library {
179 name: "libexample",
180 product_variables: {
181 treble_linker_namespaces: {
182 cflags: ["-DSHOULD_NOT_EXIST"],
183 },
184 },
185 }`),
186 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100187 expectedErrors: []string{
188 "nothing should care if linker namespaces are enabled or not",
189 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800190 },
191 {
192 name: "libc_bionic_ndk treble_linker_namespaces.cflags",
193 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800194 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800195 cc_library {
196 name: "libc_bionic_ndk",
197 product_variables: {
198 treble_linker_namespaces: {
199 cflags: ["-DSHOULD_NOT_EXIST"],
200 },
201 },
202 }`),
203 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800204 },
Neil Fullerdf5f3562018-10-21 17:19:10 +0100205 {
Colin Crossfd4f7432019-03-05 15:06:16 -0800206 name: "java_device_for_host",
207 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800208 "Android.bp": []byte(`
Colin Crossfd4f7432019-03-05 15:06:16 -0800209 java_device_for_host {
210 name: "device_for_host",
211 libs: ["core-libart"],
212 }`),
213 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100214 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700215 "java_device_for_host can only be used in allowed projects",
Paul Duffinb5af6202019-08-05 15:07:57 +0100216 },
Colin Crossfd4f7432019-03-05 15:06:16 -0800217 },
Colin Crossc511bc52020-04-07 16:50:32 +0000218 // CC sdk rule tests
219 {
Colin Cross440e0d02020-06-11 11:32:11 -0700220 name: `"sdk_variant_only" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000221 fs: map[string][]byte{
222 "Android.bp": []byte(`
223 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700224 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000225 sdk_version: "current",
226 sdk_variant_only: true,
227 }`),
228 },
229 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700230 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000231 },
232 },
233 {
Colin Cross440e0d02020-06-11 11:32:11 -0700234 name: `"sdk_variant_only: false" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000235 fs: map[string][]byte{
236 "Android.bp": []byte(`
237 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700238 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000239 sdk_version: "current",
240 sdk_variant_only: false,
241 }`),
242 },
243 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700244 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000245 },
246 },
247 {
Colin Cross440e0d02020-06-11 11:32:11 -0700248 name: `"platform" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000249 fs: map[string][]byte{
250 "Android.bp": []byte(`
251 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700252 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000253 platform: {
254 shared_libs: ["libfoo"],
255 },
256 }`),
257 },
258 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700259 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000260 },
261 },
David Srbeckye033cba2020-05-20 22:20:28 +0100262 {
263 name: "uncompress_dex inside art",
264 fs: map[string][]byte{
265 "art/Android.bp": []byte(`
266 java_library {
267 name: "inside_art_libraries",
268 uncompress_dex: true,
269 }`),
270 },
271 },
272 {
273 name: "uncompress_dex outside art",
274 fs: map[string][]byte{
275 "other/Android.bp": []byte(`
276 java_library {
277 name: "outside_art_libraries",
278 uncompress_dex: true,
279 }`),
280 },
281 expectedErrors: []string{
282 "module \"outside_art_libraries\": violates neverallow",
283 },
284 },
Yifan Hong696ed4d2020-07-27 12:59:58 -0700285 {
286 name: "disallowed makefile_goal",
287 fs: map[string][]byte{
288 "Android.bp": []byte(`
289 makefile_goal {
290 name: "foo",
291 product_out_path: "boot/trap.img"
292 }
293 `),
294 },
295 expectedErrors: []string{
Yuntao Xufeb07562021-11-18 22:33:02 +0000296 "Only boot images and seapp contexts may be imported as a makefile goal.",
Yifan Hong696ed4d2020-07-27 12:59:58 -0700297 },
298 },
Remi NGUYEN VAN1fdd6ca2021-12-02 19:39:35 +0900299 {
300 name: "min_sdk too low",
301 fs: map[string][]byte{
302 "Android.bp": []byte(`
303 java_library {
304 name: "min_sdk_too_low",
305 min_sdk_version: "30",
306 }`),
307 },
308 rules: []Rule{
309 NeverAllow().WithMatcher("min_sdk_version", LessThanSdkVersion("31")),
310 },
311 expectedErrors: []string{
312 "module \"min_sdk_too_low\": violates neverallow",
313 },
314 },
315 {
316 name: "min_sdk high enough",
317 fs: map[string][]byte{
318 "Android.bp": []byte(`
319 java_library {
320 name: "min_sdk_high_enough",
321 min_sdk_version: "31",
322 }`),
323 },
324 rules: []Rule{
325 NeverAllow().WithMatcher("min_sdk_version", LessThanSdkVersion("31")),
326 },
327 },
328 {
329 name: "current min_sdk high enough",
330 fs: map[string][]byte{
331 "Android.bp": []byte(`
332 java_library {
333 name: "current_min_sdk_high_enough",
334 min_sdk_version: "current",
335 }`),
336 },
337 rules: []Rule{
338 NeverAllow().WithMatcher("min_sdk_version", LessThanSdkVersion("31")),
339 },
340 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800341}
342
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000343var prepareForNeverAllowTest = GroupFixturePreparers(
344 FixtureRegisterWithContext(func(ctx RegistrationContext) {
345 ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
346 ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
347 ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
348 ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
349 ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000350 }),
351)
352
Logan Chienee97c3e2018-03-12 16:34:26 +0800353func TestNeverallow(t *testing.T) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800354 for _, test := range neverallowTests {
Paul Duffinb5af6202019-08-05 15:07:57 +0100355 t.Run(test.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000356 GroupFixturePreparers(
357 prepareForNeverAllowTest,
Paul Duffin45338f02021-03-30 23:07:52 +0100358 PrepareForTestWithNeverallowRules(test.rules),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000359 test.fs.AddToFixture(),
Paul Duffin3cb2c062021-03-22 19:24:26 +0000360 ).
361 ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
Paul Duffin30ac3e72021-03-20 00:36:14 +0000362 RunTest(t)
Logan Chienee97c3e2018-03-12 16:34:26 +0800363 })
364 }
365}
366
Neil Fullerdf5f3562018-10-21 17:19:10 +0100367type mockCcLibraryProperties struct {
Paul Duffinc8111702019-07-22 12:13:55 +0100368 Include_dirs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800369 Vendor_available *bool
Paul Duffin35781882019-07-25 15:41:09 +0100370 Static_libs []string
Colin Crossc511bc52020-04-07 16:50:32 +0000371 Sdk_version *string
372 Sdk_variant_only *bool
Logan Chienee97c3e2018-03-12 16:34:26 +0800373
374 Vndk struct {
375 Enabled *bool
376 Support_system_process *bool
377 Extends *string
378 }
379
380 Product_variables struct {
381 Enforce_vintf_manifest struct {
382 Cflags []string
383 }
384
385 Treble_linker_namespaces struct {
386 Cflags []string
387 }
388 }
Colin Crossc511bc52020-04-07 16:50:32 +0000389
390 Platform struct {
391 Shared_libs []string
392 }
Logan Chienee97c3e2018-03-12 16:34:26 +0800393}
394
395type mockCcLibraryModule struct {
396 ModuleBase
Neil Fullerdf5f3562018-10-21 17:19:10 +0100397 properties mockCcLibraryProperties
Logan Chienee97c3e2018-03-12 16:34:26 +0800398}
399
400func newMockCcLibraryModule() Module {
401 m := &mockCcLibraryModule{}
402 m.AddProperties(&m.properties)
403 InitAndroidModule(m)
404 return m
405}
406
Paul Duffin35781882019-07-25 15:41:09 +0100407type neverallowTestDependencyTag struct {
408 blueprint.BaseDependencyTag
409 name string
410}
411
412var staticDepTag = neverallowTestDependencyTag{name: "static"}
413
414func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
415 for _, lib := range c.properties.Static_libs {
416 ctx.AddDependency(ctx.Module(), staticDepTag, lib)
417 }
418}
419
Logan Chienee97c3e2018-03-12 16:34:26 +0800420func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
421}
Neil Fullerdf5f3562018-10-21 17:19:10 +0100422
423type mockJavaLibraryProperties struct {
Remi NGUYEN VAN1fdd6ca2021-12-02 19:39:35 +0900424 Libs []string
425 Min_sdk_version *string
426 Sdk_version *string
427 Uncompress_dex *bool
Neil Fullerdf5f3562018-10-21 17:19:10 +0100428}
429
430type mockJavaLibraryModule struct {
431 ModuleBase
432 properties mockJavaLibraryProperties
433}
434
435func newMockJavaLibraryModule() Module {
436 m := &mockJavaLibraryModule{}
437 m.AddProperties(&m.properties)
438 InitAndroidModule(m)
439 return m
440}
441
Neil Fullerdf5f3562018-10-21 17:19:10 +0100442func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
443}
Yifan Hong696ed4d2020-07-27 12:59:58 -0700444
445type mockMakefileGoalProperties struct {
446 Product_out_path *string
447}
448
449type mockMakefileGoalModule struct {
450 ModuleBase
451 properties mockMakefileGoalProperties
452}
453
454func newMockMakefileGoalModule() Module {
455 m := &mockMakefileGoalModule{}
456 m.AddProperties(&m.properties)
457 InitAndroidModule(m)
458 return m
459}
460
461func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
462}