blob: 5f5f9a19314f0ceb5ad27040e2dd6dfb81cead4c [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 (
Liz Kammera3d79152021-10-28 18:14:04 -040018 "regexp"
Logan Chienee97c3e2018-03-12 16:34:26 +080019 "testing"
Paul Duffin35781882019-07-25 15:41:09 +010020
21 "github.com/google/blueprint"
Logan Chienee97c3e2018-03-12 16:34:26 +080022)
23
24var neverallowTests = []struct {
Paul Duffin115445b2019-08-07 15:31:07 +010025 // The name of the test.
26 name string
27
28 // Optional test specific rules. If specified then they are used instead of the default rules.
29 rules []Rule
30
31 // Additional contents to add to the virtual filesystem used by the tests.
Paul Duffin3c6a4ea2021-03-16 23:41:40 +000032 fs MockFS
Paul Duffin115445b2019-08-07 15:31:07 +010033
34 // The expected error patterns. If empty then no errors are expected, otherwise each error
35 // reported must be matched by at least one of these patterns. A pattern matches if the error
36 // message contains the pattern. A pattern does not have to match the whole error message.
Paul Duffinb5af6202019-08-05 15:07:57 +010037 expectedErrors []string
Logan Chienee97c3e2018-03-12 16:34:26 +080038}{
Paul Duffin35781882019-07-25 15:41:09 +010039 // Test General Functionality
40
41 // in direct deps tests
42 {
43 name: "not_allowed_in_direct_deps",
Paul Duffin115445b2019-08-07 15:31:07 +010044 rules: []Rule{
45 NeverAllow().InDirectDeps("not_allowed_in_direct_deps"),
46 },
Paul Duffin35781882019-07-25 15:41:09 +010047 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -080048 "top/Android.bp": []byte(`
Paul Duffin35781882019-07-25 15:41:09 +010049 cc_library {
50 name: "not_allowed_in_direct_deps",
51 }`),
Colin Cross98be1bb2019-12-13 20:41:13 -080052 "other/Android.bp": []byte(`
Paul Duffin35781882019-07-25 15:41:09 +010053 cc_library {
54 name: "libother",
55 static_libs: ["not_allowed_in_direct_deps"],
56 }`),
57 },
Paul Duffinb5af6202019-08-05 15:07:57 +010058 expectedErrors: []string{
Liz Kammera3d79152021-10-28 18:14:04 -040059 regexp.QuoteMeta("module \"libother\": violates neverallow requirements. Not allowed:\n\tdep(s): [\"not_allowed_in_direct_deps\"]"),
60 },
61 },
62 {
63 name: "multiple constraints",
64 rules: []Rule{
65 NeverAllow().
66 InDirectDeps("not_allowed_in_direct_deps").
67 In("other").
68 ModuleType("cc_library").
69 NotIn("top").
70 NotModuleType("cc_binary"),
71 },
72 fs: map[string][]byte{
73 "top/Android.bp": []byte(`
74 cc_library {
75 name: "not_allowed_in_direct_deps",
76 }`),
77 "other/Android.bp": []byte(`
78 cc_library {
79 name: "libother",
80 static_libs: ["not_allowed_in_direct_deps"],
81 }`),
82 },
83 expectedErrors: []string{
84 regexp.QuoteMeta(`module "libother": violates neverallow requirements. Not allowed:
85 in dirs: ["other/"]
86 module types: ["cc_library"]
87 dep(s): ["not_allowed_in_direct_deps"]
88 EXCEPT in dirs: ["top/"]
89 EXCEPT module types: ["cc_binary"]`),
Paul Duffinb5af6202019-08-05 15:07:57 +010090 },
Paul Duffin35781882019-07-25 15:41:09 +010091 },
92
Paul Duffin115445b2019-08-07 15:31:07 +010093 // Test android specific rules
Paul Duffin35781882019-07-25 15:41:09 +010094
Paul Duffinc8111702019-07-22 12:13:55 +010095 // include_dir rule tests
96 {
97 name: "include_dir not allowed to reference art",
98 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -080099 "other/Android.bp": []byte(`
Paul Duffinc8111702019-07-22 12:13:55 +0100100 cc_library {
101 name: "libother",
102 include_dirs: ["art/libdexfile/include"],
103 }`),
104 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100105 expectedErrors: []string{
106 "all usages of 'art' have been migrated",
107 },
Paul Duffinc8111702019-07-22 12:13:55 +0100108 },
109 {
Steven Moreland8fc8dbf2021-04-27 02:31:07 +0000110 name: "include_dir not allowed to reference art",
111 fs: map[string][]byte{
112 "system/libfmq/Android.bp": []byte(`
113 cc_library {
114 name: "libother",
115 include_dirs: ["any/random/file"],
116 }`),
117 },
118 expectedErrors: []string{
119 "all usages of them in 'system/libfmq' have been migrated",
120 },
121 },
122 {
123 name: "include_dir can work",
Paul Duffinc8111702019-07-22 12:13:55 +0100124 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800125 "other/Android.bp": []byte(`
Paul Duffinc8111702019-07-22 12:13:55 +0100126 cc_library {
127 name: "libother",
128 include_dirs: ["another/include"],
129 }`),
130 },
131 },
132 // Treble rule tests
Logan Chienee97c3e2018-03-12 16:34:26 +0800133 {
134 name: "no vndk.enabled under vendor directory",
135 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800136 "vendor/Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800137 cc_library {
138 name: "libvndk",
139 vendor_available: true,
140 vndk: {
141 enabled: true,
142 },
143 }`),
144 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100145 expectedErrors: []string{
146 "VNDK can never contain a library that is device dependent",
147 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800148 },
149 {
150 name: "no vndk.enabled under device directory",
151 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800152 "device/Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800153 cc_library {
154 name: "libvndk",
155 vendor_available: true,
156 vndk: {
157 enabled: true,
158 },
159 }`),
160 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100161 expectedErrors: []string{
162 "VNDK can never contain a library that is device dependent",
163 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800164 },
Logan Chienaf29bad2018-03-12 16:35:58 +0800165 {
166 name: "vndk-ext under vendor or device directory",
167 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800168 "device/Android.bp": []byte(`
Logan Chienaf29bad2018-03-12 16:35:58 +0800169 cc_library {
170 name: "libvndk1_ext",
171 vendor: true,
172 vndk: {
173 enabled: true,
174 },
175 }`),
Colin Cross98be1bb2019-12-13 20:41:13 -0800176 "vendor/Android.bp": []byte(`
Logan Chienaf29bad2018-03-12 16:35:58 +0800177 cc_library {
178 name: "libvndk2_ext",
179 vendor: true,
180 vndk: {
181 enabled: true,
182 },
183 }`),
184 },
Logan Chienaf29bad2018-03-12 16:35:58 +0800185 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800186
187 {
188 name: "no enforce_vintf_manifest.cflags",
189 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800190 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800191 cc_library {
192 name: "libexample",
193 product_variables: {
194 enforce_vintf_manifest: {
195 cflags: ["-DSHOULD_NOT_EXIST"],
196 },
197 },
198 }`),
199 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100200 expectedErrors: []string{
201 "manifest enforcement should be independent",
202 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800203 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800204
205 {
206 name: "no treble_linker_namespaces.cflags",
207 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800208 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800209 cc_library {
210 name: "libexample",
211 product_variables: {
212 treble_linker_namespaces: {
213 cflags: ["-DSHOULD_NOT_EXIST"],
214 },
215 },
216 }`),
217 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100218 expectedErrors: []string{
219 "nothing should care if linker namespaces are enabled or not",
220 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800221 },
222 {
223 name: "libc_bionic_ndk treble_linker_namespaces.cflags",
224 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800225 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800226 cc_library {
227 name: "libc_bionic_ndk",
228 product_variables: {
229 treble_linker_namespaces: {
230 cflags: ["-DSHOULD_NOT_EXIST"],
231 },
232 },
233 }`),
234 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800235 },
Neil Fullerdf5f3562018-10-21 17:19:10 +0100236 {
Colin Crossfd4f7432019-03-05 15:06:16 -0800237 name: "java_device_for_host",
238 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800239 "Android.bp": []byte(`
Colin Crossfd4f7432019-03-05 15:06:16 -0800240 java_device_for_host {
241 name: "device_for_host",
242 libs: ["core-libart"],
243 }`),
244 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100245 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700246 "java_device_for_host can only be used in allowed projects",
Paul Duffinb5af6202019-08-05 15:07:57 +0100247 },
Colin Crossfd4f7432019-03-05 15:06:16 -0800248 },
Colin Crossc511bc52020-04-07 16:50:32 +0000249 // CC sdk rule tests
250 {
Colin Cross440e0d02020-06-11 11:32:11 -0700251 name: `"sdk_variant_only" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000252 fs: map[string][]byte{
253 "Android.bp": []byte(`
254 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700255 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000256 sdk_version: "current",
257 sdk_variant_only: true,
258 }`),
259 },
260 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700261 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000262 },
263 },
264 {
Colin Cross440e0d02020-06-11 11:32:11 -0700265 name: `"sdk_variant_only: false" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000266 fs: map[string][]byte{
267 "Android.bp": []byte(`
268 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700269 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000270 sdk_version: "current",
271 sdk_variant_only: false,
272 }`),
273 },
274 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700275 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000276 },
277 },
278 {
Colin Cross440e0d02020-06-11 11:32:11 -0700279 name: `"platform" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000280 fs: map[string][]byte{
281 "Android.bp": []byte(`
282 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700283 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000284 platform: {
285 shared_libs: ["libfoo"],
286 },
287 }`),
288 },
289 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700290 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000291 },
292 },
David Srbeckye033cba2020-05-20 22:20:28 +0100293 {
294 name: "uncompress_dex inside art",
295 fs: map[string][]byte{
296 "art/Android.bp": []byte(`
297 java_library {
298 name: "inside_art_libraries",
299 uncompress_dex: true,
300 }`),
301 },
302 },
303 {
304 name: "uncompress_dex outside art",
305 fs: map[string][]byte{
306 "other/Android.bp": []byte(`
307 java_library {
308 name: "outside_art_libraries",
309 uncompress_dex: true,
310 }`),
311 },
312 expectedErrors: []string{
313 "module \"outside_art_libraries\": violates neverallow",
314 },
315 },
Yifan Hong696ed4d2020-07-27 12:59:58 -0700316 {
317 name: "disallowed makefile_goal",
318 fs: map[string][]byte{
319 "Android.bp": []byte(`
320 makefile_goal {
321 name: "foo",
322 product_out_path: "boot/trap.img"
323 }
324 `),
325 },
326 expectedErrors: []string{
Jooyung Han39cadf92022-07-25 12:32:32 +0900327 "Only boot images.* may be imported as a makefile goal",
328 },
329 },
330 {
331 name: "disallowed makefile_goal outside external",
332 fs: map[string][]byte{
333 "project/Android.bp": []byte(`
334 makefile_goal {
335 name: "foo",
336 product_out_path: "obj/EXE/foo",
337 }
338 `),
339 },
340 expectedErrors: []string{
341 "not in allowed projects",
342 },
343 },
344 {
345 name: "allow makefile_goal within external",
346 fs: map[string][]byte{
347 "frameworks/opt/net/wifi/libwifi_hal/Android.bp": []byte(`
348 makefile_goal {
349 name: "foo",
350 product_out_path: "obj/EXE/foo",
351 }
352 `),
Yifan Hong696ed4d2020-07-27 12:59:58 -0700353 },
354 },
Jiyong Park3c306f32022-04-05 15:29:53 +0900355 // Tests for the rule prohibiting the use of framework
356 {
357 name: "prohibit framework",
358 fs: map[string][]byte{
359 "Android.bp": []byte(`
360 java_library {
361 name: "foo",
362 libs: ["framework"],
363 sdk_version: "current",
364 }`),
365 },
366 expectedErrors: []string{
367 "framework can't be used when building against SDK",
368 },
369 },
Alan Stokes73feba32022-11-14 12:21:24 +0000370 // Test for the rule restricting use of implementation_installable
371 {
372 name: `"implementation_installable" outside allowed list`,
373 fs: map[string][]byte{
374 "Android.bp": []byte(`
375 cc_library {
376 name: "outside_allowed_list",
377 stubs: {
378 implementation_installable: true,
379 },
380 }`),
381 },
382 expectedErrors: []string{
383 `module "outside_allowed_list": violates neverallow`,
384 },
385 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800386}
387
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000388var prepareForNeverAllowTest = GroupFixturePreparers(
389 FixtureRegisterWithContext(func(ctx RegistrationContext) {
390 ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
391 ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
392 ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
393 ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
394 ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000395 }),
396)
397
Logan Chienee97c3e2018-03-12 16:34:26 +0800398func TestNeverallow(t *testing.T) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800399 for _, test := range neverallowTests {
Paul Duffinb5af6202019-08-05 15:07:57 +0100400 t.Run(test.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000401 GroupFixturePreparers(
402 prepareForNeverAllowTest,
Paul Duffin45338f02021-03-30 23:07:52 +0100403 PrepareForTestWithNeverallowRules(test.rules),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000404 test.fs.AddToFixture(),
Paul Duffin3cb2c062021-03-22 19:24:26 +0000405 ).
406 ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
Paul Duffin30ac3e72021-03-20 00:36:14 +0000407 RunTest(t)
Logan Chienee97c3e2018-03-12 16:34:26 +0800408 })
409 }
410}
411
Neil Fullerdf5f3562018-10-21 17:19:10 +0100412type mockCcLibraryProperties struct {
Paul Duffinc8111702019-07-22 12:13:55 +0100413 Include_dirs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800414 Vendor_available *bool
Paul Duffin35781882019-07-25 15:41:09 +0100415 Static_libs []string
Colin Crossc511bc52020-04-07 16:50:32 +0000416 Sdk_version *string
417 Sdk_variant_only *bool
Logan Chienee97c3e2018-03-12 16:34:26 +0800418
419 Vndk struct {
420 Enabled *bool
421 Support_system_process *bool
422 Extends *string
423 }
424
425 Product_variables struct {
426 Enforce_vintf_manifest struct {
427 Cflags []string
428 }
429
430 Treble_linker_namespaces struct {
431 Cflags []string
432 }
433 }
Colin Crossc511bc52020-04-07 16:50:32 +0000434
435 Platform struct {
436 Shared_libs []string
437 }
Alan Stokes73feba32022-11-14 12:21:24 +0000438
439 Stubs struct {
440 Implementation_installable *bool
441 }
Logan Chienee97c3e2018-03-12 16:34:26 +0800442}
443
444type mockCcLibraryModule struct {
445 ModuleBase
Neil Fullerdf5f3562018-10-21 17:19:10 +0100446 properties mockCcLibraryProperties
Logan Chienee97c3e2018-03-12 16:34:26 +0800447}
448
449func newMockCcLibraryModule() Module {
450 m := &mockCcLibraryModule{}
451 m.AddProperties(&m.properties)
452 InitAndroidModule(m)
453 return m
454}
455
Paul Duffin35781882019-07-25 15:41:09 +0100456type neverallowTestDependencyTag struct {
457 blueprint.BaseDependencyTag
458 name string
459}
460
461var staticDepTag = neverallowTestDependencyTag{name: "static"}
462
463func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
464 for _, lib := range c.properties.Static_libs {
465 ctx.AddDependency(ctx.Module(), staticDepTag, lib)
466 }
467}
468
Logan Chienee97c3e2018-03-12 16:34:26 +0800469func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
470}
Neil Fullerdf5f3562018-10-21 17:19:10 +0100471
472type mockJavaLibraryProperties struct {
Anton Hanssone1b18362021-12-23 15:05:38 +0000473 Libs []string
474 Sdk_version *string
475 Uncompress_dex *bool
Neil Fullerdf5f3562018-10-21 17:19:10 +0100476}
477
478type mockJavaLibraryModule struct {
479 ModuleBase
480 properties mockJavaLibraryProperties
481}
482
483func newMockJavaLibraryModule() Module {
484 m := &mockJavaLibraryModule{}
485 m.AddProperties(&m.properties)
486 InitAndroidModule(m)
487 return m
488}
489
Neil Fullerdf5f3562018-10-21 17:19:10 +0100490func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
491}
Yifan Hong696ed4d2020-07-27 12:59:58 -0700492
493type mockMakefileGoalProperties struct {
494 Product_out_path *string
495}
496
497type mockMakefileGoalModule struct {
498 ModuleBase
499 properties mockMakefileGoalProperties
500}
501
502func newMockMakefileGoalModule() Module {
503 m := &mockMakefileGoalModule{}
504 m.AddProperties(&m.properties)
505 InitAndroidModule(m)
506 return m
507}
508
509func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
510}