blob: c04379108081a64368d6fc836a54af29f8a3756b [file] [log] [blame]
Bob Badour37af0462021-01-07 03:34:31 +00001package android
2
3import (
4 "testing"
5
6 "github.com/google/blueprint"
7)
8
9var licensesTests = []struct {
Paul Duffin3c298a32021-03-04 17:44:03 +000010 name string
11 fs map[string][]byte
12 expectedErrors []string
13 effectiveLicenses map[string][]string
14 effectiveInheritedLicenses map[string][]string
15 effectivePackage map[string]string
16 effectiveNotices map[string][]string
17 effectiveKinds map[string][]string
18 effectiveConditions map[string][]string
Bob Badour37af0462021-01-07 03:34:31 +000019}{
20 {
21 name: "invalid module type without licenses property",
22 fs: map[string][]byte{
23 "top/Blueprints": []byte(`
24 mock_bad_module {
25 name: "libexample",
26 }`),
27 },
28 expectedErrors: []string{`module type "mock_bad_module" must have an applicable licenses property`},
29 },
30 {
31 name: "license must exist",
32 fs: map[string][]byte{
33 "top/Blueprints": []byte(`
34 mock_library {
35 name: "libexample",
36 licenses: ["notice"],
37 }`),
38 },
39 expectedErrors: []string{`"libexample" depends on undefined module "notice"`},
40 },
41 {
42 name: "all good",
43 fs: map[string][]byte{
44 "top/Blueprints": []byte(`
45 license_kind {
46 name: "notice",
47 conditions: ["shownotice"],
48 }
49
50 license {
51 name: "top_Apache2",
52 license_kinds: ["notice"],
53 package_name: "topDog",
54 license_text: ["LICENSE", "NOTICE"],
55 }
56
57 mock_library {
58 name: "libexample1",
59 licenses: ["top_Apache2"],
60 }`),
61 "top/nested/Blueprints": []byte(`
62 mock_library {
63 name: "libnested",
64 licenses: ["top_Apache2"],
65 }`),
66 "other/Blueprints": []byte(`
67 mock_library {
68 name: "libother",
69 licenses: ["top_Apache2"],
70 }`),
71 },
72 effectiveLicenses: map[string][]string{
73 "libexample1": []string{"top_Apache2"},
Paul Duffin3c298a32021-03-04 17:44:03 +000074 "libnested": []string{"top_Apache2"},
75 "libother": []string{"top_Apache2"},
Bob Badour37af0462021-01-07 03:34:31 +000076 },
77 effectiveKinds: map[string][]string{
78 "libexample1": []string{"notice"},
Paul Duffin3c298a32021-03-04 17:44:03 +000079 "libnested": []string{"notice"},
80 "libother": []string{"notice"},
Bob Badour37af0462021-01-07 03:34:31 +000081 },
82 effectivePackage: map[string]string{
83 "libexample1": "topDog",
Paul Duffin3c298a32021-03-04 17:44:03 +000084 "libnested": "topDog",
85 "libother": "topDog",
Bob Badour37af0462021-01-07 03:34:31 +000086 },
87 effectiveConditions: map[string][]string{
88 "libexample1": []string{"shownotice"},
Paul Duffin3c298a32021-03-04 17:44:03 +000089 "libnested": []string{"shownotice"},
90 "libother": []string{"shownotice"},
Bob Badour37af0462021-01-07 03:34:31 +000091 },
92 effectiveNotices: map[string][]string{
93 "libexample1": []string{"top/LICENSE", "top/NOTICE"},
Paul Duffin3c298a32021-03-04 17:44:03 +000094 "libnested": []string{"top/LICENSE", "top/NOTICE"},
95 "libother": []string{"top/LICENSE", "top/NOTICE"},
Bob Badour37af0462021-01-07 03:34:31 +000096 },
97 },
98
99 // Defaults propagation tests
100 {
101 // Check that licenses is the union of the defaults modules.
102 name: "defaults union, basic",
103 fs: map[string][]byte{
104 "top/Blueprints": []byte(`
105 license_kind {
106 name: "top_notice",
107 conditions: ["notice"],
108 }
109
110 license {
111 name: "top_other",
112 license_kinds: ["top_notice"],
113 }
114
115 mock_defaults {
116 name: "libexample_defaults",
117 licenses: ["top_other"],
118 }
119 mock_library {
120 name: "libexample",
121 licenses: ["nested_other"],
122 defaults: ["libexample_defaults"],
123 }
124 mock_library {
125 name: "libsamepackage",
126 deps: ["libexample"],
127 }`),
128 "top/nested/Blueprints": []byte(`
129 license_kind {
130 name: "nested_notice",
131 conditions: ["notice"],
132 }
133
134 license {
135 name: "nested_other",
136 license_kinds: ["nested_notice"],
137 }
138
139 mock_library {
140 name: "libnested",
141 deps: ["libexample"],
142 }`),
143 "other/Blueprints": []byte(`
144 mock_library {
145 name: "libother",
146 deps: ["libexample"],
147 }`),
148 },
149 effectiveLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000150 "libexample": []string{"nested_other", "top_other"},
Bob Badour37af0462021-01-07 03:34:31 +0000151 "libsamepackage": []string{},
Paul Duffin3c298a32021-03-04 17:44:03 +0000152 "libnested": []string{},
153 "libother": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000154 },
155 effectiveInheritedLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000156 "libexample": []string{"nested_other", "top_other"},
Bob Badour37af0462021-01-07 03:34:31 +0000157 "libsamepackage": []string{"nested_other", "top_other"},
Paul Duffin3c298a32021-03-04 17:44:03 +0000158 "libnested": []string{"nested_other", "top_other"},
159 "libother": []string{"nested_other", "top_other"},
Bob Badour37af0462021-01-07 03:34:31 +0000160 },
161 effectiveKinds: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000162 "libexample": []string{"nested_notice", "top_notice"},
Bob Badour37af0462021-01-07 03:34:31 +0000163 "libsamepackage": []string{},
Paul Duffin3c298a32021-03-04 17:44:03 +0000164 "libnested": []string{},
165 "libother": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000166 },
167 effectiveConditions: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000168 "libexample": []string{"notice"},
Bob Badour37af0462021-01-07 03:34:31 +0000169 "libsamepackage": []string{},
Paul Duffin3c298a32021-03-04 17:44:03 +0000170 "libnested": []string{},
171 "libother": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000172 },
173 },
174 {
175 name: "defaults union, multiple defaults",
176 fs: map[string][]byte{
177 "top/Blueprints": []byte(`
178 license {
179 name: "top",
180 }
181 mock_defaults {
182 name: "libexample_defaults_1",
183 licenses: ["other"],
184 }
185 mock_defaults {
186 name: "libexample_defaults_2",
187 licenses: ["top_nested"],
188 }
189 mock_library {
190 name: "libexample",
191 defaults: ["libexample_defaults_1", "libexample_defaults_2"],
192 }
193 mock_library {
194 name: "libsamepackage",
195 deps: ["libexample"],
196 }`),
197 "top/nested/Blueprints": []byte(`
198 license {
199 name: "top_nested",
200 license_text: ["LICENSE.txt"],
201 }
202 mock_library {
203 name: "libnested",
204 deps: ["libexample"],
205 }`),
206 "other/Blueprints": []byte(`
207 license {
208 name: "other",
209 }
210 mock_library {
211 name: "libother",
212 deps: ["libexample"],
213 }`),
214 "outsider/Blueprints": []byte(`
215 mock_library {
216 name: "liboutsider",
217 deps: ["libexample"],
218 }`),
219 },
220 effectiveLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000221 "libexample": []string{"other", "top_nested"},
Bob Badour37af0462021-01-07 03:34:31 +0000222 "libsamepackage": []string{},
Paul Duffin3c298a32021-03-04 17:44:03 +0000223 "libnested": []string{},
224 "libother": []string{},
225 "liboutsider": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000226 },
227 effectiveInheritedLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000228 "libexample": []string{"other", "top_nested"},
Bob Badour37af0462021-01-07 03:34:31 +0000229 "libsamepackage": []string{"other", "top_nested"},
Paul Duffin3c298a32021-03-04 17:44:03 +0000230 "libnested": []string{"other", "top_nested"},
231 "libother": []string{"other", "top_nested"},
232 "liboutsider": []string{"other", "top_nested"},
Bob Badour37af0462021-01-07 03:34:31 +0000233 },
234 effectiveKinds: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000235 "libexample": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000236 "libsamepackage": []string{},
Paul Duffin3c298a32021-03-04 17:44:03 +0000237 "libnested": []string{},
238 "libother": []string{},
239 "liboutsider": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000240 },
241 effectiveNotices: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000242 "libexample": []string{"top/nested/LICENSE.txt"},
Bob Badour37af0462021-01-07 03:34:31 +0000243 "libsamepackage": []string{},
Paul Duffin3c298a32021-03-04 17:44:03 +0000244 "libnested": []string{},
245 "libother": []string{},
246 "liboutsider": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000247 },
248 },
249
250 // Defaults module's defaults_licenses tests
251 {
252 name: "defaults_licenses invalid",
253 fs: map[string][]byte{
254 "top/Blueprints": []byte(`
255 mock_defaults {
256 name: "top_defaults",
257 licenses: ["notice"],
258 }`),
259 },
260 expectedErrors: []string{`"top_defaults" depends on undefined module "notice"`},
261 },
262 {
263 name: "defaults_licenses overrides package default",
264 fs: map[string][]byte{
265 "top/Blueprints": []byte(`
266 package {
267 default_applicable_licenses: ["by_exception_only"],
268 }
269 license {
270 name: "by_exception_only",
271 }
272 license {
273 name: "notice",
274 }
275 mock_defaults {
276 name: "top_defaults",
277 licenses: ["notice"],
278 }
279 mock_library {
280 name: "libexample",
281 }
282 mock_library {
283 name: "libdefaults",
284 defaults: ["top_defaults"],
285 }`),
286 },
287 effectiveLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000288 "libexample": []string{"by_exception_only"},
Bob Badour37af0462021-01-07 03:34:31 +0000289 "libdefaults": []string{"notice"},
290 },
291 effectiveInheritedLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000292 "libexample": []string{"by_exception_only"},
Bob Badour37af0462021-01-07 03:34:31 +0000293 "libdefaults": []string{"notice"},
294 },
295 },
296
297 // Package default_applicable_licenses tests
298 {
299 name: "package default_applicable_licenses must exist",
300 fs: map[string][]byte{
301 "top/Blueprints": []byte(`
302 package {
303 default_applicable_licenses: ["notice"],
304 }`),
305 },
306 expectedErrors: []string{`"//top" depends on undefined module "notice"`},
307 },
308 {
309 // This test relies on the default licenses being legacy_public.
310 name: "package default_applicable_licenses property used when no licenses specified",
311 fs: map[string][]byte{
312 "top/Blueprints": []byte(`
313 package {
314 default_applicable_licenses: ["top_notice"],
315 }
316
317 license {
318 name: "top_notice",
319 }
320 mock_library {
321 name: "libexample",
322 }`),
323 "outsider/Blueprints": []byte(`
324 mock_library {
325 name: "liboutsider",
326 deps: ["libexample"],
327 }`),
328 },
329 effectiveLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000330 "libexample": []string{"top_notice"},
Bob Badour37af0462021-01-07 03:34:31 +0000331 "liboutsider": []string{},
332 },
333 effectiveInheritedLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000334 "libexample": []string{"top_notice"},
Bob Badour37af0462021-01-07 03:34:31 +0000335 "liboutsider": []string{"top_notice"},
336 },
337 },
338 {
339 name: "package default_applicable_licenses not inherited to subpackages",
340 fs: map[string][]byte{
341 "top/Blueprints": []byte(`
342 package {
343 default_applicable_licenses: ["top_notice"],
344 }
345 license {
346 name: "top_notice",
347 }
348 mock_library {
349 name: "libexample",
350 }`),
351 "top/nested/Blueprints": []byte(`
352 package {
353 default_applicable_licenses: ["outsider"],
354 }
355
356 mock_library {
357 name: "libnested",
358 }`),
359 "top/other/Blueprints": []byte(`
360 mock_library {
361 name: "libother",
362 }`),
363 "outsider/Blueprints": []byte(`
364 license {
365 name: "outsider",
366 }
367 mock_library {
368 name: "liboutsider",
369 deps: ["libexample", "libother", "libnested"],
370 }`),
371 },
372 effectiveLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000373 "libexample": []string{"top_notice"},
374 "libnested": []string{"outsider"},
375 "libother": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000376 "liboutsider": []string{},
377 },
378 effectiveInheritedLicenses: map[string][]string{
Paul Duffin3c298a32021-03-04 17:44:03 +0000379 "libexample": []string{"top_notice"},
380 "libnested": []string{"outsider"},
381 "libother": []string{},
Bob Badour37af0462021-01-07 03:34:31 +0000382 "liboutsider": []string{"top_notice", "outsider"},
383 },
384 },
385 {
386 name: "verify that prebuilt dependencies are included",
387 fs: map[string][]byte{
388 "prebuilts/Blueprints": []byte(`
389 license {
390 name: "prebuilt"
391 }
392 prebuilt {
393 name: "module",
394 licenses: ["prebuilt"],
395 }`),
396 "top/sources/source_file": nil,
397 "top/sources/Blueprints": []byte(`
398 license {
399 name: "top_sources"
400 }
401 source {
402 name: "module",
403 licenses: ["top_sources"],
404 }`),
405 "top/other/source_file": nil,
406 "top/other/Blueprints": []byte(`
407 source {
408 name: "other",
409 deps: [":module"],
410 }`),
411 },
412 effectiveLicenses: map[string][]string{
413 "other": []string{},
414 },
415 effectiveInheritedLicenses: map[string][]string{
416 "other": []string{"prebuilt", "top_sources"},
417 },
418 },
419 {
420 name: "verify that prebuilt dependencies are ignored for licenses reasons (preferred)",
421 fs: map[string][]byte{
422 "prebuilts/Blueprints": []byte(`
423 license {
424 name: "prebuilt"
425 }
426 prebuilt {
427 name: "module",
428 licenses: ["prebuilt"],
429 prefer: true,
430 }`),
431 "top/sources/source_file": nil,
432 "top/sources/Blueprints": []byte(`
433 license {
434 name: "top_sources"
435 }
436 source {
437 name: "module",
438 licenses: ["top_sources"],
439 }`),
440 "top/other/source_file": nil,
441 "top/other/Blueprints": []byte(`
442 source {
443 name: "other",
444 deps: [":module"],
445 }`),
446 },
447 effectiveLicenses: map[string][]string{
448 "other": []string{},
449 },
450 effectiveInheritedLicenses: map[string][]string{
451 "module": []string{"prebuilt", "top_sources"},
Paul Duffin3c298a32021-03-04 17:44:03 +0000452 "other": []string{"prebuilt", "top_sources"},
Bob Badour37af0462021-01-07 03:34:31 +0000453 },
454 },
455}
456
457func TestLicenses(t *testing.T) {
458 for _, test := range licensesTests {
459 t.Run(test.name, func(t *testing.T) {
460 ctx, errs := testLicenses(buildDir, test.fs)
461
462 CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
463
464 if test.effectiveLicenses != nil {
465 checkEffectiveLicenses(t, ctx, test.effectiveLicenses)
466 }
467
468 if test.effectivePackage != nil {
469 checkEffectivePackage(t, ctx, test.effectivePackage)
470 }
471
472 if test.effectiveNotices != nil {
473 checkEffectiveNotices(t, ctx, test.effectiveNotices)
474 }
475
476 if test.effectiveKinds != nil {
477 checkEffectiveKinds(t, ctx, test.effectiveKinds)
478 }
479
480 if test.effectiveConditions != nil {
481 checkEffectiveConditions(t, ctx, test.effectiveConditions)
482 }
483
484 if test.effectiveInheritedLicenses != nil {
485 checkEffectiveInheritedLicenses(t, ctx, test.effectiveInheritedLicenses)
486 }
487 })
488 }
489}
490
491func checkEffectiveLicenses(t *testing.T, ctx *TestContext, effectiveLicenses map[string][]string) {
492 actualLicenses := make(map[string][]string)
493 ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
494 if _, ok := m.(*licenseModule); ok {
495 return
496 }
497 if _, ok := m.(*licenseKindModule); ok {
498 return
499 }
500 if _, ok := m.(*packageModule); ok {
501 return
502 }
503 module, ok := m.(Module)
504 if !ok {
505 t.Errorf("%q not a module", m.Name())
506 return
507 }
508 base := module.base()
509 if base == nil {
510 return
511 }
512 actualLicenses[m.Name()] = base.commonProperties.Effective_licenses
513 })
514
515 for moduleName, expectedLicenses := range effectiveLicenses {
516 licenses, ok := actualLicenses[moduleName]
517 if !ok {
518 licenses = []string{}
519 }
520 if !compareUnorderedStringArrays(expectedLicenses, licenses) {
521 t.Errorf("effective licenses mismatch for module %q: expected %q, found %q", moduleName, expectedLicenses, licenses)
522 }
523 }
524}
525
526func checkEffectiveInheritedLicenses(t *testing.T, ctx *TestContext, effectiveInheritedLicenses map[string][]string) {
527 actualLicenses := make(map[string][]string)
528 ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
529 if _, ok := m.(*licenseModule); ok {
530 return
531 }
532 if _, ok := m.(*licenseKindModule); ok {
533 return
534 }
535 if _, ok := m.(*packageModule); ok {
536 return
537 }
538 module, ok := m.(Module)
539 if !ok {
540 t.Errorf("%q not a module", m.Name())
541 return
542 }
543 base := module.base()
544 if base == nil {
545 return
546 }
547 inherited := make(map[string]bool)
548 for _, l := range base.commonProperties.Effective_licenses {
549 inherited[l] = true
550 }
551 ctx.Context.Context.VisitDepsDepthFirst(m, func(c blueprint.Module) {
552 if _, ok := c.(*licenseModule); ok {
553 return
554 }
555 if _, ok := c.(*licenseKindModule); ok {
556 return
557 }
558 if _, ok := c.(*packageModule); ok {
559 return
560 }
561 cmodule, ok := c.(Module)
562 if !ok {
563 t.Errorf("%q not a module", c.Name())
564 return
565 }
566 cbase := cmodule.base()
567 if cbase == nil {
568 return
569 }
570 for _, l := range cbase.commonProperties.Effective_licenses {
571 inherited[l] = true
572 }
573 })
574 actualLicenses[m.Name()] = []string{}
575 for l := range inherited {
576 actualLicenses[m.Name()] = append(actualLicenses[m.Name()], l)
577 }
578 })
579
580 for moduleName, expectedInheritedLicenses := range effectiveInheritedLicenses {
581 licenses, ok := actualLicenses[moduleName]
582 if !ok {
583 licenses = []string{}
584 }
585 if !compareUnorderedStringArrays(expectedInheritedLicenses, licenses) {
586 t.Errorf("effective inherited licenses mismatch for module %q: expected %q, found %q", moduleName, expectedInheritedLicenses, licenses)
587 }
588 }
589}
590
591func checkEffectivePackage(t *testing.T, ctx *TestContext, effectivePackage map[string]string) {
592 actualPackage := make(map[string]string)
593 ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
594 if _, ok := m.(*licenseModule); ok {
595 return
596 }
597 if _, ok := m.(*licenseKindModule); ok {
598 return
599 }
600 if _, ok := m.(*packageModule); ok {
601 return
602 }
603 module, ok := m.(Module)
604 if !ok {
605 t.Errorf("%q not a module", m.Name())
606 return
607 }
608 base := module.base()
609 if base == nil {
610 return
611 }
612
613 if base.commonProperties.Effective_package_name == nil {
614 actualPackage[m.Name()] = ""
615 } else {
616 actualPackage[m.Name()] = *base.commonProperties.Effective_package_name
617 }
618 })
619
620 for moduleName, expectedPackage := range effectivePackage {
621 packageName, ok := actualPackage[moduleName]
622 if !ok {
623 packageName = ""
624 }
625 if expectedPackage != packageName {
626 t.Errorf("effective package mismatch for module %q: expected %q, found %q", moduleName, expectedPackage, packageName)
627 }
628 }
629}
630
631func checkEffectiveNotices(t *testing.T, ctx *TestContext, effectiveNotices map[string][]string) {
632 actualNotices := make(map[string][]string)
633 ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
634 if _, ok := m.(*licenseModule); ok {
635 return
636 }
637 if _, ok := m.(*licenseKindModule); ok {
638 return
639 }
640 if _, ok := m.(*packageModule); ok {
641 return
642 }
643 module, ok := m.(Module)
644 if !ok {
645 t.Errorf("%q not a module", m.Name())
646 return
647 }
648 base := module.base()
649 if base == nil {
650 return
651 }
652 actualNotices[m.Name()] = base.commonProperties.Effective_license_text
653 })
654
655 for moduleName, expectedNotices := range effectiveNotices {
656 notices, ok := actualNotices[moduleName]
657 if !ok {
658 notices = []string{}
659 }
660 if !compareUnorderedStringArrays(expectedNotices, notices) {
661 t.Errorf("effective notice files mismatch for module %q: expected %q, found %q", moduleName, expectedNotices, notices)
662 }
663 }
664}
665
666func checkEffectiveKinds(t *testing.T, ctx *TestContext, effectiveKinds map[string][]string) {
667 actualKinds := make(map[string][]string)
668 ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
669 if _, ok := m.(*licenseModule); ok {
670 return
671 }
672 if _, ok := m.(*licenseKindModule); ok {
673 return
674 }
675 if _, ok := m.(*packageModule); ok {
676 return
677 }
678 module, ok := m.(Module)
679 if !ok {
680 t.Errorf("%q not a module", m.Name())
681 return
682 }
683 base := module.base()
684 if base == nil {
685 return
686 }
687 actualKinds[m.Name()] = base.commonProperties.Effective_license_kinds
688 })
689
690 for moduleName, expectedKinds := range effectiveKinds {
691 kinds, ok := actualKinds[moduleName]
692 if !ok {
693 kinds = []string{}
694 }
695 if !compareUnorderedStringArrays(expectedKinds, kinds) {
696 t.Errorf("effective license kinds mismatch for module %q: expected %q, found %q", moduleName, expectedKinds, kinds)
697 }
698 }
699}
700
701func checkEffectiveConditions(t *testing.T, ctx *TestContext, effectiveConditions map[string][]string) {
702 actualConditions := make(map[string][]string)
703 ctx.Context.Context.VisitAllModules(func(m blueprint.Module) {
704 if _, ok := m.(*licenseModule); ok {
705 return
706 }
707 if _, ok := m.(*licenseKindModule); ok {
708 return
709 }
710 if _, ok := m.(*packageModule); ok {
711 return
712 }
713 module, ok := m.(Module)
714 if !ok {
715 t.Errorf("%q not a module", m.Name())
716 return
717 }
718 base := module.base()
719 if base == nil {
720 return
721 }
722 actualConditions[m.Name()] = base.commonProperties.Effective_license_conditions
723 })
724
725 for moduleName, expectedConditions := range effectiveConditions {
726 conditions, ok := actualConditions[moduleName]
727 if !ok {
728 conditions = []string{}
729 }
730 if !compareUnorderedStringArrays(expectedConditions, conditions) {
731 t.Errorf("effective license conditions mismatch for module %q: expected %q, found %q", moduleName, expectedConditions, conditions)
732 }
733 }
734}
735
736func compareUnorderedStringArrays(expected, actual []string) bool {
737 if len(expected) != len(actual) {
738 return false
739 }
740 s := make(map[string]int)
741 for _, v := range expected {
742 s[v] += 1
743 }
744 for _, v := range actual {
745 c, ok := s[v]
746 if !ok {
747 return false
748 }
749 if c < 1 {
750 return false
751 }
752 s[v] -= 1
753 }
754 return true
755}
756
757func testLicenses(buildDir string, fs map[string][]byte) (*TestContext, []error) {
758
759 // Create a new config per test as licenses information is stored in the config.
760 env := make(map[string]string)
761 env["ANDROID_REQUIRE_LICENSES"] = "1"
762 config := TestArchConfig(buildDir, env, "", fs)
763
764 ctx := NewTestArchContext(config)
765 ctx.RegisterModuleType("mock_bad_module", newMockLicensesBadModule)
766 ctx.RegisterModuleType("mock_library", newMockLicensesLibraryModule)
767 ctx.RegisterModuleType("mock_defaults", defaultsLicensesFactory)
768
769 // Order of the following method calls is significant.
770 RegisterPackageBuildComponents(ctx)
771 registerTestPrebuiltBuildComponents(ctx)
772 RegisterLicenseKindBuildComponents(ctx)
773 RegisterLicenseBuildComponents(ctx)
774 ctx.PreArchMutators(RegisterVisibilityRuleChecker)
775 ctx.PreArchMutators(RegisterLicensesPackageMapper)
776 ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
777 ctx.PreArchMutators(RegisterLicensesPropertyGatherer)
778 ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
779 ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
780 ctx.PostDepsMutators(RegisterLicensesDependencyChecker)
781 ctx.Register()
782
783 _, errs := ctx.ParseBlueprintsFiles(".")
784 if len(errs) > 0 {
785 return ctx, errs
786 }
787
788 _, errs = ctx.PrepareBuildActions(config)
789 return ctx, errs
790}
791
792type mockLicensesBadProperties struct {
793 Visibility []string
794}
795
796type mockLicensesBadModule struct {
797 ModuleBase
798 DefaultableModuleBase
799 properties mockLicensesBadProperties
800}
801
802func newMockLicensesBadModule() Module {
803 m := &mockLicensesBadModule{}
804
805 base := m.base()
806 m.AddProperties(&base.nameProperties, &m.properties)
807
808 base.generalProperties = m.GetProperties()
809 base.customizableProperties = m.GetProperties()
810
811 // The default_visibility property needs to be checked and parsed by the visibility module during
812 // its checking and parsing phases so make it the primary visibility property.
813 setPrimaryVisibilityProperty(m, "visibility", &m.properties.Visibility)
814
815 initAndroidModuleBase(m)
816 InitDefaultableModule(m)
817
818 return m
819}
820
821func (m *mockLicensesBadModule) GenerateAndroidBuildActions(ModuleContext) {
822}
823
824type mockLicensesLibraryProperties struct {
825 Deps []string
826}
827
828type mockLicensesLibraryModule struct {
829 ModuleBase
830 DefaultableModuleBase
831 properties mockLicensesLibraryProperties
832}
833
834func newMockLicensesLibraryModule() Module {
835 m := &mockLicensesLibraryModule{}
836 m.AddProperties(&m.properties)
837 InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
838 InitDefaultableModule(m)
839 return m
840}
841
842type dependencyLicensesTag struct {
843 blueprint.BaseDependencyTag
844 name string
845}
846
847func (j *mockLicensesLibraryModule) DepsMutator(ctx BottomUpMutatorContext) {
848 ctx.AddVariationDependencies(nil, dependencyLicensesTag{name: "mockdeps"}, j.properties.Deps...)
849}
850
851func (p *mockLicensesLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
852}
853
854type mockLicensesDefaults struct {
855 ModuleBase
856 DefaultsModuleBase
857}
858
859func defaultsLicensesFactory() Module {
860 m := &mockLicensesDefaults{}
861 InitDefaultsModule(m)
862 return m
863}