blob: b2620ef9262e25ebbaafb54273016c28ba6abb64 [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 },
Jiyong Park3c306f32022-04-05 15:29:53 +0900316 // Tests for the rule prohibiting the use of framework
317 {
318 name: "prohibit framework",
319 fs: map[string][]byte{
320 "Android.bp": []byte(`
321 java_library {
322 name: "foo",
323 libs: ["framework"],
324 sdk_version: "current",
325 }`),
326 },
327 expectedErrors: []string{
328 "framework can't be used when building against SDK",
329 },
330 },
Alan Stokes73feba32022-11-14 12:21:24 +0000331 // Test for the rule restricting use of implementation_installable
332 {
333 name: `"implementation_installable" outside allowed list`,
334 fs: map[string][]byte{
335 "Android.bp": []byte(`
336 cc_library {
337 name: "outside_allowed_list",
338 stubs: {
339 implementation_installable: true,
340 },
341 }`),
342 },
343 expectedErrors: []string{
344 `module "outside_allowed_list": violates neverallow`,
345 },
346 },
Jihoon Kang381c2fa2023-06-01 22:17:32 +0000347 // Test for the rule restricting use of exclude_static_libs
348 {
349 name: `"exclude_static_libs" outside allowed directory`,
350 fs: map[string][]byte{
351 "a/b/Android.bp": []byte(`
352 java_library {
353 name: "baz",
354 exclude_static_libs: [
355 "bar",
356 ],
357 }
358 `),
359 },
360 expectedErrors: []string{
Jihoon Kang3d4d88d2023-06-14 23:14:42 +0000361 `exclude_static_libs property is only allowed for java modules defined in build/soong, libcore, and frameworks/base/api`,
Jihoon Kang381c2fa2023-06-01 22:17:32 +0000362 },
363 },
Mark Whitea15790a2023-08-22 21:28:11 +0000364 // Test for only allowing headers_only for framework-minus-apex-headers
365 {
366 name: `"headers_only" outside framework-minus-apex-headers modules`,
367 fs: map[string][]byte{
368 "a/b/Android.bp": []byte(`
369 java_library {
370 name: "baz",
371 headers_only: true,
372 }
373 `),
374 },
375 expectedErrors: []string{
376 `headers_only can only be used for generating framework-minus-apex headers for non-updatable modules`,
377 },
378 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800379}
380
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000381var prepareForNeverAllowTest = GroupFixturePreparers(
382 FixtureRegisterWithContext(func(ctx RegistrationContext) {
383 ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
384 ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
385 ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
386 ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000387 }),
388)
389
Logan Chienee97c3e2018-03-12 16:34:26 +0800390func TestNeverallow(t *testing.T) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800391 for _, test := range neverallowTests {
Paul Duffinb5af6202019-08-05 15:07:57 +0100392 t.Run(test.name, func(t *testing.T) {
Paul Duffin30ac3e72021-03-20 00:36:14 +0000393 GroupFixturePreparers(
394 prepareForNeverAllowTest,
Paul Duffin45338f02021-03-30 23:07:52 +0100395 PrepareForTestWithNeverallowRules(test.rules),
Paul Duffin30ac3e72021-03-20 00:36:14 +0000396 test.fs.AddToFixture(),
Paul Duffin3cb2c062021-03-22 19:24:26 +0000397 ).
398 ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
Paul Duffin30ac3e72021-03-20 00:36:14 +0000399 RunTest(t)
Logan Chienee97c3e2018-03-12 16:34:26 +0800400 })
401 }
402}
403
Neil Fullerdf5f3562018-10-21 17:19:10 +0100404type mockCcLibraryProperties struct {
Paul Duffinc8111702019-07-22 12:13:55 +0100405 Include_dirs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800406 Vendor_available *bool
Paul Duffin35781882019-07-25 15:41:09 +0100407 Static_libs []string
Colin Crossc511bc52020-04-07 16:50:32 +0000408 Sdk_version *string
409 Sdk_variant_only *bool
Logan Chienee97c3e2018-03-12 16:34:26 +0800410
411 Vndk struct {
412 Enabled *bool
413 Support_system_process *bool
414 Extends *string
415 }
416
417 Product_variables struct {
418 Enforce_vintf_manifest struct {
419 Cflags []string
420 }
421
422 Treble_linker_namespaces struct {
423 Cflags []string
424 }
425 }
Colin Crossc511bc52020-04-07 16:50:32 +0000426
427 Platform struct {
428 Shared_libs []string
429 }
Alan Stokes73feba32022-11-14 12:21:24 +0000430
431 Stubs struct {
432 Implementation_installable *bool
433 }
Logan Chienee97c3e2018-03-12 16:34:26 +0800434}
435
436type mockCcLibraryModule struct {
437 ModuleBase
Neil Fullerdf5f3562018-10-21 17:19:10 +0100438 properties mockCcLibraryProperties
Logan Chienee97c3e2018-03-12 16:34:26 +0800439}
440
441func newMockCcLibraryModule() Module {
442 m := &mockCcLibraryModule{}
443 m.AddProperties(&m.properties)
444 InitAndroidModule(m)
445 return m
446}
447
Paul Duffin35781882019-07-25 15:41:09 +0100448type neverallowTestDependencyTag struct {
449 blueprint.BaseDependencyTag
450 name string
451}
452
453var staticDepTag = neverallowTestDependencyTag{name: "static"}
454
455func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
456 for _, lib := range c.properties.Static_libs {
457 ctx.AddDependency(ctx.Module(), staticDepTag, lib)
458 }
459}
460
Logan Chienee97c3e2018-03-12 16:34:26 +0800461func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
462}
Neil Fullerdf5f3562018-10-21 17:19:10 +0100463
464type mockJavaLibraryProperties struct {
Jihoon Kang381c2fa2023-06-01 22:17:32 +0000465 Libs []string
466 Sdk_version *string
467 Uncompress_dex *bool
468 Exclude_static_libs []string
Mark Whitea15790a2023-08-22 21:28:11 +0000469 Headers_only *bool
Neil Fullerdf5f3562018-10-21 17:19:10 +0100470}
471
472type mockJavaLibraryModule struct {
473 ModuleBase
474 properties mockJavaLibraryProperties
475}
476
477func newMockJavaLibraryModule() Module {
478 m := &mockJavaLibraryModule{}
479 m.AddProperties(&m.properties)
480 InitAndroidModule(m)
481 return m
482}
483
Neil Fullerdf5f3562018-10-21 17:19:10 +0100484func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
485}