blob: 5ac97e775b4dd9f5dbbce77495a78f3d67e26a82 [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 {
79 name: "include_dir can reference another location",
80 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -080081 "other/Android.bp": []byte(`
Paul Duffinc8111702019-07-22 12:13:55 +010082 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{
Colin Cross98be1bb2019-12-13 20:41:13 -080092 "vendor/Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +080093 cc_library {
94 name: "libvndk",
95 vendor_available: true,
96 vndk: {
97 enabled: true,
98 },
99 }`),
100 },
Paul Duffinb5af6202019-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{
Colin Cross98be1bb2019-12-13 20:41:13 -0800108 "device/Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800109 cc_library {
110 name: "libvndk",
111 vendor_available: true,
112 vndk: {
113 enabled: true,
114 },
115 }`),
116 },
Paul Duffinb5af6202019-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{
Colin Cross98be1bb2019-12-13 20:41:13 -0800124 "device/Android.bp": []byte(`
Logan Chienaf29bad2018-03-12 16:35:58 +0800125 cc_library {
126 name: "libvndk1_ext",
127 vendor: true,
128 vndk: {
129 enabled: true,
130 },
131 }`),
Colin Cross98be1bb2019-12-13 20:41:13 -0800132 "vendor/Android.bp": []byte(`
Logan Chienaf29bad2018-03-12 16:35:58 +0800133 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{
Colin Cross98be1bb2019-12-13 20:41:13 -0800146 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800147 cc_library {
148 name: "libexample",
149 product_variables: {
150 enforce_vintf_manifest: {
151 cflags: ["-DSHOULD_NOT_EXIST"],
152 },
153 },
154 }`),
155 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100156 expectedErrors: []string{
157 "manifest enforcement should be independent",
158 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800159 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800160
161 {
162 name: "no treble_linker_namespaces.cflags",
163 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800164 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800165 cc_library {
166 name: "libexample",
167 product_variables: {
168 treble_linker_namespaces: {
169 cflags: ["-DSHOULD_NOT_EXIST"],
170 },
171 },
172 }`),
173 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100174 expectedErrors: []string{
175 "nothing should care if linker namespaces are enabled or not",
176 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800177 },
178 {
179 name: "libc_bionic_ndk treble_linker_namespaces.cflags",
180 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800181 "Android.bp": []byte(`
Logan Chienee97c3e2018-03-12 16:34:26 +0800182 cc_library {
183 name: "libc_bionic_ndk",
184 product_variables: {
185 treble_linker_namespaces: {
186 cflags: ["-DSHOULD_NOT_EXIST"],
187 },
188 },
189 }`),
190 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800191 },
Neil Fullerdf5f3562018-10-21 17:19:10 +0100192 {
Colin Crossfd4f7432019-03-05 15:06:16 -0800193 name: "java_device_for_host",
194 fs: map[string][]byte{
Colin Cross98be1bb2019-12-13 20:41:13 -0800195 "Android.bp": []byte(`
Colin Crossfd4f7432019-03-05 15:06:16 -0800196 java_device_for_host {
197 name: "device_for_host",
198 libs: ["core-libart"],
199 }`),
200 },
Paul Duffinb5af6202019-08-05 15:07:57 +0100201 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700202 "java_device_for_host can only be used in allowed projects",
Paul Duffinb5af6202019-08-05 15:07:57 +0100203 },
Colin Crossfd4f7432019-03-05 15:06:16 -0800204 },
Colin Crossc511bc52020-04-07 16:50:32 +0000205 // CC sdk rule tests
206 {
Colin Cross440e0d02020-06-11 11:32:11 -0700207 name: `"sdk_variant_only" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000208 fs: map[string][]byte{
209 "Android.bp": []byte(`
210 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700211 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000212 sdk_version: "current",
213 sdk_variant_only: true,
214 }`),
215 },
216 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700217 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000218 },
219 },
220 {
Colin Cross440e0d02020-06-11 11:32:11 -0700221 name: `"sdk_variant_only: false" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000222 fs: map[string][]byte{
223 "Android.bp": []byte(`
224 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700225 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000226 sdk_version: "current",
227 sdk_variant_only: false,
228 }`),
229 },
230 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700231 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000232 },
233 },
234 {
Colin Cross440e0d02020-06-11 11:32:11 -0700235 name: `"platform" outside allowed list`,
Colin Crossc511bc52020-04-07 16:50:32 +0000236 fs: map[string][]byte{
237 "Android.bp": []byte(`
238 cc_library {
Colin Cross440e0d02020-06-11 11:32:11 -0700239 name: "outside_allowed_list",
Colin Crossc511bc52020-04-07 16:50:32 +0000240 platform: {
241 shared_libs: ["libfoo"],
242 },
243 }`),
244 },
245 expectedErrors: []string{
Colin Cross440e0d02020-06-11 11:32:11 -0700246 `module "outside_allowed_list": violates neverallow`,
Colin Crossc511bc52020-04-07 16:50:32 +0000247 },
248 },
David Srbeckye033cba2020-05-20 22:20:28 +0100249 {
250 name: "uncompress_dex inside art",
251 fs: map[string][]byte{
252 "art/Android.bp": []byte(`
253 java_library {
254 name: "inside_art_libraries",
255 uncompress_dex: true,
256 }`),
257 },
258 },
259 {
260 name: "uncompress_dex outside art",
261 fs: map[string][]byte{
262 "other/Android.bp": []byte(`
263 java_library {
264 name: "outside_art_libraries",
265 uncompress_dex: true,
266 }`),
267 },
268 expectedErrors: []string{
269 "module \"outside_art_libraries\": violates neverallow",
270 },
271 },
Yifan Hong696ed4d2020-07-27 12:59:58 -0700272 {
273 name: "disallowed makefile_goal",
274 fs: map[string][]byte{
275 "Android.bp": []byte(`
276 makefile_goal {
277 name: "foo",
278 product_out_path: "boot/trap.img"
279 }
280 `),
281 },
282 expectedErrors: []string{
283 "Only boot images may be imported as a makefile goal.",
284 },
285 },
Logan Chienee97c3e2018-03-12 16:34:26 +0800286}
287
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000288var prepareForNeverAllowTest = GroupFixturePreparers(
289 FixtureRegisterWithContext(func(ctx RegistrationContext) {
290 ctx.RegisterModuleType("cc_library", newMockCcLibraryModule)
291 ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
292 ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
293 ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
294 ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
295 ctx.PostDepsMutators(RegisterNeverallowMutator)
296 }),
297)
298
Logan Chienee97c3e2018-03-12 16:34:26 +0800299func TestNeverallow(t *testing.T) {
Logan Chienee97c3e2018-03-12 16:34:26 +0800300 for _, test := range neverallowTests {
Paul Duffinb5af6202019-08-05 15:07:57 +0100301 t.Run(test.name, func(t *testing.T) {
Paul Duffin3c6a4ea2021-03-16 23:41:40 +0000302 emptyTestFixtureFactory.
303 ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
304 RunTest(t,
305 prepareForNeverAllowTest,
306 FixtureModifyConfig(func(config Config) {
307 // If the test has its own rules then use them instead of the default ones.
308 if test.rules != nil {
309 SetTestNeverallowRules(config, test.rules)
310 }
311 }),
312 test.fs.AddToFixture(),
313 )
Logan Chienee97c3e2018-03-12 16:34:26 +0800314 })
315 }
316}
317
Neil Fullerdf5f3562018-10-21 17:19:10 +0100318type mockCcLibraryProperties struct {
Paul Duffinc8111702019-07-22 12:13:55 +0100319 Include_dirs []string
Logan Chienee97c3e2018-03-12 16:34:26 +0800320 Vendor_available *bool
Paul Duffin35781882019-07-25 15:41:09 +0100321 Static_libs []string
Colin Crossc511bc52020-04-07 16:50:32 +0000322 Sdk_version *string
323 Sdk_variant_only *bool
Logan Chienee97c3e2018-03-12 16:34:26 +0800324
325 Vndk struct {
326 Enabled *bool
327 Support_system_process *bool
328 Extends *string
329 }
330
331 Product_variables struct {
332 Enforce_vintf_manifest struct {
333 Cflags []string
334 }
335
336 Treble_linker_namespaces struct {
337 Cflags []string
338 }
339 }
Colin Crossc511bc52020-04-07 16:50:32 +0000340
341 Platform struct {
342 Shared_libs []string
343 }
Logan Chienee97c3e2018-03-12 16:34:26 +0800344}
345
346type mockCcLibraryModule struct {
347 ModuleBase
Neil Fullerdf5f3562018-10-21 17:19:10 +0100348 properties mockCcLibraryProperties
Logan Chienee97c3e2018-03-12 16:34:26 +0800349}
350
351func newMockCcLibraryModule() Module {
352 m := &mockCcLibraryModule{}
353 m.AddProperties(&m.properties)
354 InitAndroidModule(m)
355 return m
356}
357
Paul Duffin35781882019-07-25 15:41:09 +0100358type neverallowTestDependencyTag struct {
359 blueprint.BaseDependencyTag
360 name string
361}
362
363var staticDepTag = neverallowTestDependencyTag{name: "static"}
364
365func (c *mockCcLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
366 for _, lib := range c.properties.Static_libs {
367 ctx.AddDependency(ctx.Module(), staticDepTag, lib)
368 }
369}
370
Logan Chienee97c3e2018-03-12 16:34:26 +0800371func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
372}
Neil Fullerdf5f3562018-10-21 17:19:10 +0100373
374type mockJavaLibraryProperties struct {
David Srbeckye033cba2020-05-20 22:20:28 +0100375 Libs []string
376 Sdk_version *string
377 Uncompress_dex *bool
Neil Fullerdf5f3562018-10-21 17:19:10 +0100378}
379
380type mockJavaLibraryModule struct {
381 ModuleBase
382 properties mockJavaLibraryProperties
383}
384
385func newMockJavaLibraryModule() Module {
386 m := &mockJavaLibraryModule{}
387 m.AddProperties(&m.properties)
388 InitAndroidModule(m)
389 return m
390}
391
Neil Fullerdf5f3562018-10-21 17:19:10 +0100392func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
393}
Yifan Hong696ed4d2020-07-27 12:59:58 -0700394
395type mockMakefileGoalProperties struct {
396 Product_out_path *string
397}
398
399type mockMakefileGoalModule struct {
400 ModuleBase
401 properties mockMakefileGoalProperties
402}
403
404func newMockMakefileGoalModule() Module {
405 m := &mockMakefileGoalModule{}
406 m.AddProperties(&m.properties)
407 InitAndroidModule(m)
408 return m
409}
410
411func (p *mockMakefileGoalModule) GenerateAndroidBuildActions(ModuleContext) {
412}