blob: 58a90b307a4c944fd5ce35b53dda68524f1616a1 [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{
Yuntao Xufeb07562021-11-18 22:33:02 +0000327 "Only boot images and seapp contexts may be imported as a makefile goal.",
Yifan Hong696ed4d2020-07-27 12:59:58 -0700328 },
329 },
Remi NGUYEN VAN1fdd6ca2021-12-02 19:39:35 +0900330 {
331 name: "min_sdk too low",
332 fs: map[string][]byte{
333 "Android.bp": []byte(`
334 java_library {
335 name: "min_sdk_too_low",
336 min_sdk_version: "30",
337 }`),
338 },
339 rules: []Rule{
340 NeverAllow().WithMatcher("min_sdk_version", LessThanSdkVersion("31")),
341 },
342 expectedErrors: []string{
343 "module \"min_sdk_too_low\": violates neverallow",
344 },
345 },
346 {
347 name: "min_sdk high enough",
348 fs: map[string][]byte{
349 "Android.bp": []byte(`
350 java_library {
351 name: "min_sdk_high_enough",
352 min_sdk_version: "31",
353 }`),
354 },
355 rules: []Rule{
356 NeverAllow().WithMatcher("min_sdk_version", LessThanSdkVersion("31")),
357 },
358 },
359 {
360 name: "current min_sdk high enough",
361 fs: map[string][]byte{
362 "Android.bp": []byte(`
363 java_library {
364 name: "current_min_sdk_high_enough",
365 min_sdk_version: "current",
366 }`),
367 },
368 rules: []Rule{
369 NeverAllow().WithMatcher("min_sdk_version", LessThanSdkVersion("31")),
370 },
371 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800372}
373
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000374var prepareForNeverAllowTest = GroupFixturePreparers(
375 FixtureRegisterWithContext(func(ctx RegistrationContext) {
376 ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
377 ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
378 ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
379 ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
380 ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000381 }),
382)
383
Logan Chienee97c3e2018-03-12 16:34:26 +0800384func TestNeverallow(t *testing.T) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800385 for _, test := range neverallowTests {
Paul Duffinb5af6202019-08-05 15:07:57 +0100386 t.Run(test.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000387 GroupFixturePreparers(
388 prepareForNeverAllowTest,
Paul Duffin45338f02021-03-30 23:07:52 +0100389 PrepareForTestWithNeverallowRules(test.rules),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000390 test.fs.AddToFixture(),
Paul Duffin3cb2c062021-03-22 19:24:26 +0000391 ).
392 ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
Paul Duffin30ac3e72021-03-20 00:36:14 +0000393 RunTest(t)
Logan Chienee97c3e2018-03-12 16:34:26 +0800394 })
395 }
396}
397
Neil Fullerdf5f3562018-10-21 17:19:10 +0100398type mockCcLibraryProperties struct {
Paul Duffinc8111702019-07-22 12:13:55 +0100399 Include_dirs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800400 Vendor_available *bool
Paul Duffin35781882019-07-25 15:41:09 +0100401 Static_libs []string
Colin Crossc511bc52020-04-07 16:50:32 +0000402 Sdk_version *string
403 Sdk_variant_only *bool
Logan Chienee97c3e2018-03-12 16:34:26 +0800404
405 Vndk struct {
406 Enabled *bool
407 Support_system_process *bool
408 Extends *string
409 }
410
411 Product_variables struct {
412 Enforce_vintf_manifest struct {
413 Cflags []string
414 }
415
416 Treble_linker_namespaces struct {
417 Cflags []string
418 }
419 }
Colin Crossc511bc52020-04-07 16:50:32 +0000420
421 Platform struct {
422 Shared_libs []string
423 }
Logan Chienee97c3e2018-03-12 16:34:26 +0800424}
425
426type mockCcLibraryModule struct {
427 ModuleBase
Neil Fullerdf5f3562018-10-21 17:19:10 +0100428 properties mockCcLibraryProperties
Logan Chienee97c3e2018-03-12 16:34:26 +0800429}
430
431func newMockCcLibraryModule() Module {
432 m := &mockCcLibraryModule{}
433 m.AddProperties(&m.properties)
434 InitAndroidModule(m)
435 return m
436}
437
Paul Duffin35781882019-07-25 15:41:09 +0100438type neverallowTestDependencyTag struct {
439 blueprint.BaseDependencyTag
440 name string
441}
442
443var staticDepTag = neverallowTestDependencyTag{name: "static"}
444
445func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
446 for _, lib := range c.properties.Static_libs {
447 ctx.AddDependency(ctx.Module(), staticDepTag, lib)
448 }
449}
450
Logan Chienee97c3e2018-03-12 16:34:26 +0800451func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
452}
Neil Fullerdf5f3562018-10-21 17:19:10 +0100453
454type mockJavaLibraryProperties struct {
Remi NGUYEN VAN1fdd6ca2021-12-02 19:39:35 +0900455 Libs []string
456 Min_sdk_version *string
457 Sdk_version *string
458 Uncompress_dex *bool
Neil Fullerdf5f3562018-10-21 17:19:10 +0100459}
460
461type mockJavaLibraryModule struct {
462 ModuleBase
463 properties mockJavaLibraryProperties
464}
465
466func newMockJavaLibraryModule() Module {
467 m := &mockJavaLibraryModule{}
468 m.AddProperties(&m.properties)
469 InitAndroidModule(m)
470 return m
471}
472
Neil Fullerdf5f3562018-10-21 17:19:10 +0100473func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
474}
Yifan Hong696ed4d2020-07-27 12:59:58 -0700475
476type mockMakefileGoalProperties struct {
477 Product_out_path *string
478}
479
480type mockMakefileGoalModule struct {
481 ModuleBase
482 properties mockMakefileGoalProperties
483}
484
485func newMockMakefileGoalModule() Module {
486 m := &mockMakefileGoalModule{}
487 m.AddProperties(&m.properties)
488 InitAndroidModule(m)
489 return m
490}
491
492func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
493}