blob: 081b0e564973bc3493cf3cfb8a7d3bf6b90f2a9d [file] [log] [blame]
Liz Kammer2dd9ca42020-11-25 16:06:39 -08001// Copyright 2020 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 bp2build
16
17import (
18 "android/soong/android"
Jingwen Chen316e07c2020-12-14 09:09:52 -050019 "android/soong/genrule"
Liz Kammer356f7d42021-01-26 09:18:53 -050020 "strings"
Liz Kammer2dd9ca42020-11-25 16:06:39 -080021 "testing"
22)
23
24func TestGenerateSoongModuleTargets(t *testing.T) {
25 testCases := []struct {
26 bp string
27 expectedBazelTarget string
28 }{
29 {
30 bp: `custom {
31 name: "foo",
32}
33 `,
34 expectedBazelTarget: `soong_module(
35 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -050036 soong_module_name = "foo",
37 soong_module_type = "custom",
38 soong_module_variant = "",
39 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -080040 ],
41)`,
42 },
43 {
44 bp: `custom {
45 name: "foo",
46 ramdisk: true,
47}
48 `,
49 expectedBazelTarget: `soong_module(
50 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -050051 soong_module_name = "foo",
52 soong_module_type = "custom",
53 soong_module_variant = "",
54 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -080055 ],
56 ramdisk = True,
57)`,
58 },
59 {
60 bp: `custom {
61 name: "foo",
62 owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
63}
64 `,
65 expectedBazelTarget: `soong_module(
66 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -050067 soong_module_name = "foo",
68 soong_module_type = "custom",
69 soong_module_variant = "",
70 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -080071 ],
72 owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
73)`,
74 },
75 {
76 bp: `custom {
77 name: "foo",
78 required: ["bar"],
79}
80 `,
81 expectedBazelTarget: `soong_module(
82 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -050083 soong_module_name = "foo",
84 soong_module_type = "custom",
85 soong_module_variant = "",
86 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -080087 ],
88 required = [
89 "bar",
90 ],
91)`,
92 },
93 {
94 bp: `custom {
95 name: "foo",
96 target_required: ["qux", "bazqux"],
97}
98 `,
99 expectedBazelTarget: `soong_module(
100 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -0500101 soong_module_name = "foo",
102 soong_module_type = "custom",
103 soong_module_variant = "",
104 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800105 ],
106 target_required = [
107 "qux",
108 "bazqux",
109 ],
110)`,
111 },
112 {
113 bp: `custom {
114 name: "foo",
115 dist: {
116 targets: ["goal_foo"],
117 tag: ".foo",
118 },
119 dists: [
120 {
121 targets: ["goal_bar"],
122 tag: ".bar",
123 },
124 ],
125}
126 `,
127 expectedBazelTarget: `soong_module(
128 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -0500129 soong_module_name = "foo",
130 soong_module_type = "custom",
131 soong_module_variant = "",
132 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800133 ],
134 dist = {
135 "tag": ".foo",
136 "targets": [
137 "goal_foo",
138 ],
139 },
140 dists = [
141 {
142 "tag": ".bar",
143 "targets": [
144 "goal_bar",
145 ],
146 },
147 ],
148)`,
149 },
150 {
151 bp: `custom {
152 name: "foo",
153 required: ["bar"],
154 target_required: ["qux", "bazqux"],
155 ramdisk: true,
156 owner: "custom_owner",
157 dists: [
158 {
159 tag: ".tag",
160 targets: ["my_goal"],
161 },
162 ],
163}
164 `,
165 expectedBazelTarget: `soong_module(
166 name = "foo",
Jingwen Chen288e2ba2021-01-25 04:36:04 -0500167 soong_module_name = "foo",
168 soong_module_type = "custom",
169 soong_module_variant = "",
170 soong_module_deps = [
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800171 ],
172 dists = [
173 {
174 "tag": ".tag",
175 "targets": [
176 "my_goal",
177 ],
178 },
179 ],
180 owner = "custom_owner",
181 ramdisk = True,
182 required = [
183 "bar",
184 ],
185 target_required = [
186 "qux",
187 "bazqux",
188 ],
189)`,
190 },
191 }
192
193 dir := "."
194 for _, testCase := range testCases {
195 config := android.TestConfig(buildDir, nil, testCase.bp, nil)
196 ctx := android.NewTestContext(config)
197 ctx.RegisterModuleType("custom", customModuleFactory)
198 ctx.Register()
199
200 _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
201 android.FailIfErrored(t, errs)
202 _, errs = ctx.PrepareBuildActions(config)
203 android.FailIfErrored(t, errs)
204
Jingwen Chen4d2c0872021-02-02 07:06:56 -0500205 bazelTargets := GenerateBazelTargets(ctx.Context.Context, QueryView)[dir]
Jingwen Chen4e4756d2021-01-24 21:13:13 -0500206 if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
207 t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800208 }
209
210 actualBazelTarget := bazelTargets[0]
211 if actualBazelTarget.content != testCase.expectedBazelTarget {
212 t.Errorf(
213 "Expected generated Bazel target to be '%s', got '%s'",
214 testCase.expectedBazelTarget,
Jingwen Chen73850672020-12-14 08:25:34 -0500215 actualBazelTarget.content,
216 )
217 }
218 }
219}
220
221func TestGenerateBazelTargetModules(t *testing.T) {
222 testCases := []struct {
223 bp string
224 expectedBazelTarget string
225 }{
226 {
227 bp: `custom {
228 name: "foo",
229 string_list_prop: ["a", "b"],
230 string_prop: "a",
231}`,
232 expectedBazelTarget: `custom(
233 name = "foo",
234 string_list_prop = [
235 "a",
236 "b",
237 ],
238 string_prop = "a",
239)`,
240 },
241 }
242
243 dir := "."
244 for _, testCase := range testCases {
245 config := android.TestConfig(buildDir, nil, testCase.bp, nil)
246 ctx := android.NewTestContext(config)
247 ctx.RegisterModuleType("custom", customModuleFactory)
248 ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator)
249 ctx.RegisterForBazelConversion()
250
251 _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
Liz Kammer356f7d42021-01-26 09:18:53 -0500252 if Errored(t, "", errs) {
253 continue
254 }
Jingwen Chen73850672020-12-14 08:25:34 -0500255 _, errs = ctx.ResolveDependencies(config)
Liz Kammer356f7d42021-01-26 09:18:53 -0500256 if Errored(t, "", errs) {
257 continue
258 }
Jingwen Chen73850672020-12-14 08:25:34 -0500259
Jingwen Chen4d2c0872021-02-02 07:06:56 -0500260 bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
Jingwen Chen4e4756d2021-01-24 21:13:13 -0500261 if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
Liz Kammer356f7d42021-01-26 09:18:53 -0500262 t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
263 } else {
264 actualBazelTarget := bazelTargets[0]
265 if actualBazelTarget.content != testCase.expectedBazelTarget {
266 t.Errorf(
267 "Expected generated Bazel target to be '%s', got '%s'",
268 testCase.expectedBazelTarget,
269 actualBazelTarget.content,
270 )
271 }
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800272 }
273 }
274}
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500275
Jingwen Chen40067de2021-01-26 21:58:43 -0500276func TestLoadStatements(t *testing.T) {
277 testCases := []struct {
278 bazelTargets BazelTargets
279 expectedLoadStatements string
280 }{
281 {
282 bazelTargets: BazelTargets{
283 BazelTarget{
284 name: "foo",
285 ruleClass: "cc_library",
286 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
287 },
288 },
289 expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
290 },
291 {
292 bazelTargets: BazelTargets{
293 BazelTarget{
294 name: "foo",
295 ruleClass: "cc_library",
296 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
297 },
298 BazelTarget{
299 name: "bar",
300 ruleClass: "cc_library",
301 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
302 },
303 },
304 expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
305 },
306 {
307 bazelTargets: BazelTargets{
308 BazelTarget{
309 name: "foo",
310 ruleClass: "cc_library",
311 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
312 },
313 BazelTarget{
314 name: "bar",
315 ruleClass: "cc_binary",
316 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
317 },
318 },
319 expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")`,
320 },
321 {
322 bazelTargets: BazelTargets{
323 BazelTarget{
324 name: "foo",
325 ruleClass: "cc_library",
326 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
327 },
328 BazelTarget{
329 name: "bar",
330 ruleClass: "cc_binary",
331 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
332 },
333 BazelTarget{
334 name: "baz",
335 ruleClass: "java_binary",
336 bzlLoadLocation: "//build/bazel/rules:java.bzl",
337 },
338 },
339 expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")
340load("//build/bazel/rules:java.bzl", "java_binary")`,
341 },
342 {
343 bazelTargets: BazelTargets{
344 BazelTarget{
345 name: "foo",
346 ruleClass: "cc_binary",
347 bzlLoadLocation: "//build/bazel/rules:cc.bzl",
348 },
349 BazelTarget{
350 name: "bar",
351 ruleClass: "java_binary",
352 bzlLoadLocation: "//build/bazel/rules:java.bzl",
353 },
354 BazelTarget{
355 name: "baz",
356 ruleClass: "genrule",
357 // Note: no bzlLoadLocation for native rules
358 },
359 },
360 expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary")
361load("//build/bazel/rules:java.bzl", "java_binary")`,
362 },
363 }
364
365 for _, testCase := range testCases {
366 actual := testCase.bazelTargets.LoadStatements()
367 expected := testCase.expectedLoadStatements
368 if actual != expected {
369 t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
370 }
371 }
372
373}
374
375func TestGenerateBazelTargetModules_OneToMany_LoadedFromStarlark(t *testing.T) {
376 testCases := []struct {
377 bp string
378 expectedBazelTarget string
379 expectedBazelTargetCount int
380 expectedLoadStatements string
381 }{
382 {
383 bp: `custom {
384 name: "bar",
385}`,
386 expectedBazelTarget: `my_library(
387 name = "bar",
388)
389
390my_proto_library(
391 name = "bar_my_proto_library_deps",
392)
393
394proto_library(
395 name = "bar_proto_library_deps",
396)`,
397 expectedBazelTargetCount: 3,
398 expectedLoadStatements: `load("//build/bazel/rules:proto.bzl", "my_proto_library", "proto_library")
399load("//build/bazel/rules:rules.bzl", "my_library")`,
400 },
401 }
402
403 dir := "."
404 for _, testCase := range testCases {
405 config := android.TestConfig(buildDir, nil, testCase.bp, nil)
406 ctx := android.NewTestContext(config)
407 ctx.RegisterModuleType("custom", customModuleFactory)
408 ctx.RegisterBp2BuildMutator("custom_starlark", customBp2BuildMutatorFromStarlark)
409 ctx.RegisterForBazelConversion()
410
411 _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
412 android.FailIfErrored(t, errs)
413 _, errs = ctx.ResolveDependencies(config)
414 android.FailIfErrored(t, errs)
415
Jingwen Chen4d2c0872021-02-02 07:06:56 -0500416 bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
Jingwen Chen40067de2021-01-26 21:58:43 -0500417 if actualCount := len(bazelTargets); actualCount != testCase.expectedBazelTargetCount {
418 t.Fatalf("Expected %d bazel target, got %d", testCase.expectedBazelTargetCount, actualCount)
419 }
420
421 actualBazelTargets := bazelTargets.String()
422 if actualBazelTargets != testCase.expectedBazelTarget {
423 t.Errorf(
424 "Expected generated Bazel target to be '%s', got '%s'",
425 testCase.expectedBazelTarget,
426 actualBazelTargets,
427 )
428 }
429
430 actualLoadStatements := bazelTargets.LoadStatements()
431 if actualLoadStatements != testCase.expectedLoadStatements {
432 t.Errorf(
433 "Expected generated load statements to be '%s', got '%s'",
434 testCase.expectedLoadStatements,
435 actualLoadStatements,
436 )
437 }
438 }
439}
440
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500441func TestModuleTypeBp2Build(t *testing.T) {
Liz Kammer356f7d42021-01-26 09:18:53 -0500442 otherGenruleBp := map[string]string{
443 "other/Android.bp": `genrule {
444 name: "foo.tool",
445 out: ["foo_tool.out"],
446 srcs: ["foo_tool.in"],
447 cmd: "cp $(in) $(out)",
448}
449genrule {
450 name: "other.tool",
451 out: ["other_tool.out"],
452 srcs: ["other_tool.in"],
453 cmd: "cp $(in) $(out)",
454}`,
455 }
456
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500457 testCases := []struct {
Liz Kammer356f7d42021-01-26 09:18:53 -0500458 description string
Jingwen Chena42d6412021-01-26 21:57:27 -0500459 moduleTypeUnderTest string
460 moduleTypeUnderTestFactory android.ModuleFactory
461 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
Liz Kammer356f7d42021-01-26 09:18:53 -0500462 preArchMutators []android.RegisterMutatorFunc
463 depsMutators []android.RegisterMutatorFunc
Jingwen Chena42d6412021-01-26 21:57:27 -0500464 bp string
Liz Kammer356f7d42021-01-26 09:18:53 -0500465 expectedBazelTargets []string
466 fs map[string]string
467 dir string
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500468 }{
469 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500470 description: "filegroup with no srcs",
471 moduleTypeUnderTest: "filegroup",
472 moduleTypeUnderTestFactory: android.FileGroupFactory,
473 moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500474 bp: `filegroup {
Liz Kammer356f7d42021-01-26 09:18:53 -0500475 name: "fg_foo",
476 srcs: [],
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500477}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500478 expectedBazelTargets: []string{
479 `filegroup(
480 name = "fg_foo",
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500481 srcs = [
482 ],
483)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500484 },
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500485 },
486 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500487 description: "filegroup with srcs",
488 moduleTypeUnderTest: "filegroup",
489 moduleTypeUnderTestFactory: android.FileGroupFactory,
490 moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500491 bp: `filegroup {
Liz Kammer356f7d42021-01-26 09:18:53 -0500492 name: "fg_foo",
493 srcs: ["a", "b"],
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500494}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500495 expectedBazelTargets: []string{`filegroup(
496 name = "fg_foo",
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500497 srcs = [
498 "a",
499 "b",
500 ],
501)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500502 },
503 },
504 {
505 description: "filegroup with excludes srcs",
506 moduleTypeUnderTest: "filegroup",
507 moduleTypeUnderTestFactory: android.FileGroupFactory,
508 moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
509 bp: `filegroup {
510 name: "fg_foo",
511 srcs: ["a", "b"],
512 exclude_srcs: ["a"],
513}`,
514 expectedBazelTargets: []string{`filegroup(
515 name = "fg_foo",
516 srcs = [
517 "b",
518 ],
519)`,
520 },
521 },
522 {
523 description: "filegroup with glob",
524 moduleTypeUnderTest: "filegroup",
525 moduleTypeUnderTestFactory: android.FileGroupFactory,
526 moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
527 bp: `filegroup {
528 name: "foo",
529 srcs: ["**/*.txt"],
530}`,
531 expectedBazelTargets: []string{`filegroup(
532 name = "foo",
533 srcs = [
534 "other/a.txt",
535 "other/b.txt",
536 "other/subdir/a.txt",
537 ],
538)`,
539 },
540 fs: map[string]string{
541 "other/a.txt": "",
542 "other/b.txt": "",
543 "other/subdir/a.txt": "",
544 "other/file": "",
545 },
546 },
547 {
548 description: "filegroup with glob in subdir",
549 moduleTypeUnderTest: "filegroup",
550 moduleTypeUnderTestFactory: android.FileGroupFactory,
551 moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
552 bp: `filegroup {
553 name: "foo",
554 srcs: ["a.txt"],
555}`,
556 dir: "other",
557 expectedBazelTargets: []string{`filegroup(
558 name = "fg_foo",
559 srcs = [
560 "a.txt",
561 "b.txt",
562 "subdir/a.txt",
563 ],
564)`,
565 },
566 fs: map[string]string{
567 "other/Android.bp": `filegroup {
568 name: "fg_foo",
569 srcs: ["**/*.txt"],
570}`,
571 "other/a.txt": "",
572 "other/b.txt": "",
573 "other/subdir/a.txt": "",
574 "other/file": "",
575 },
576 },
577 {
578 description: "depends_on_other_dir_module",
579 moduleTypeUnderTest: "filegroup",
580 moduleTypeUnderTestFactory: android.FileGroupFactory,
581 moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
582 bp: `filegroup {
583 name: "foobar",
584 srcs: [
585 ":foo",
586 "c",
587 ],
588}`,
589 expectedBazelTargets: []string{`filegroup(
590 name = "foobar",
591 srcs = [
592 "//other:foo",
593 "c",
594 ],
595)`,
596 },
597 fs: map[string]string{
598 "other/Android.bp": `filegroup {
599 name: "foo",
600 srcs: ["a", "b"],
601}`,
602 },
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500603 },
Jingwen Chen316e07c2020-12-14 09:09:52 -0500604 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500605 description: "genrule with command line variable replacements",
606 moduleTypeUnderTest: "genrule",
607 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
608 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
Liz Kammer356f7d42021-01-26 09:18:53 -0500609 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
Jingwen Chen316e07c2020-12-14 09:09:52 -0500610 bp: `genrule {
Liz Kammer356f7d42021-01-26 09:18:53 -0500611 name: "foo.tool",
612 out: ["foo_tool.out"],
613 srcs: ["foo_tool.in"],
614 cmd: "cp $(in) $(out)",
615}
616
617genrule {
Jingwen Chen316e07c2020-12-14 09:09:52 -0500618 name: "foo",
619 out: ["foo.out"],
620 srcs: ["foo.in"],
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500621 tools: [":foo.tool"],
622 cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)",
Jingwen Chen316e07c2020-12-14 09:09:52 -0500623}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500624 expectedBazelTargets: []string{
625 `genrule(
Jingwen Chen316e07c2020-12-14 09:09:52 -0500626 name = "foo",
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500627 cmd = "$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)",
Jingwen Chen316e07c2020-12-14 09:09:52 -0500628 outs = [
629 "foo.out",
630 ],
631 srcs = [
632 "foo.in",
633 ],
634 tools = [
635 ":foo.tool",
636 ],
637)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500638 `genrule(
639 name = "foo.tool",
640 cmd = "cp $(SRCS) $(OUTS)",
641 outs = [
642 "foo_tool.out",
643 ],
644 srcs = [
645 "foo_tool.in",
646 ],
647)`,
648 },
Jingwen Chen316e07c2020-12-14 09:09:52 -0500649 },
650 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500651 description: "genrule using $(locations :label)",
652 moduleTypeUnderTest: "genrule",
653 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
654 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
Liz Kammer356f7d42021-01-26 09:18:53 -0500655 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
Jingwen Chen316e07c2020-12-14 09:09:52 -0500656 bp: `genrule {
Liz Kammer356f7d42021-01-26 09:18:53 -0500657 name: "foo.tools",
658 out: ["foo_tool.out", "foo_tool2.out"],
659 srcs: ["foo_tool.in"],
660 cmd: "cp $(in) $(out)",
661 }
662
663genrule {
Jingwen Chen316e07c2020-12-14 09:09:52 -0500664 name: "foo",
665 out: ["foo.out"],
666 srcs: ["foo.in"],
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500667 tools: [":foo.tools"],
668 cmd: "$(locations :foo.tools) -s $(out) $(in)",
Jingwen Chen316e07c2020-12-14 09:09:52 -0500669}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500670 expectedBazelTargets: []string{`genrule(
Jingwen Chen316e07c2020-12-14 09:09:52 -0500671 name = "foo",
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500672 cmd = "$(locations :foo.tools) -s $(OUTS) $(SRCS)",
673 outs = [
674 "foo.out",
675 ],
676 srcs = [
677 "foo.in",
678 ],
679 tools = [
680 ":foo.tools",
681 ],
682)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500683 `genrule(
684 name = "foo.tools",
685 cmd = "cp $(SRCS) $(OUTS)",
686 outs = [
687 "foo_tool.out",
688 "foo_tool2.out",
689 ],
690 srcs = [
691 "foo_tool.in",
692 ],
693)`,
694 },
695 },
696 {
697 description: "genrule using $(locations //absolute:label)",
698 moduleTypeUnderTest: "genrule",
699 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
700 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
701 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
702 bp: `genrule {
703 name: "foo",
704 out: ["foo.out"],
705 srcs: ["foo.in"],
706 tool_files: [":foo.tool"],
707 cmd: "$(locations :foo.tool) -s $(out) $(in)",
708}`,
709 expectedBazelTargets: []string{`genrule(
710 name = "foo",
711 cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)",
712 outs = [
713 "foo.out",
714 ],
715 srcs = [
716 "foo.in",
717 ],
718 tools = [
719 "//other:foo.tool",
720 ],
721)`,
722 },
723 fs: otherGenruleBp,
724 },
725 {
726 description: "genrule srcs using $(locations //absolute:label)",
727 moduleTypeUnderTest: "genrule",
728 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
729 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
730 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
731 bp: `genrule {
732 name: "foo",
733 out: ["foo.out"],
734 srcs: [":other.tool"],
735 tool_files: [":foo.tool"],
736 cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)",
737}`,
738 expectedBazelTargets: []string{`genrule(
739 name = "foo",
740 cmd = "$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)",
741 outs = [
742 "foo.out",
743 ],
744 srcs = [
745 "//other:other.tool",
746 ],
747 tools = [
748 "//other:foo.tool",
749 ],
750)`,
751 },
752 fs: otherGenruleBp,
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500753 },
754 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500755 description: "genrule using $(location) label should substitute first tool label automatically",
756 moduleTypeUnderTest: "genrule",
757 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
758 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
Liz Kammer356f7d42021-01-26 09:18:53 -0500759 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500760 bp: `genrule {
761 name: "foo",
762 out: ["foo.out"],
763 srcs: ["foo.in"],
764 tool_files: [":foo.tool", ":other.tool"],
765 cmd: "$(location) -s $(out) $(in)",
766}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500767 expectedBazelTargets: []string{`genrule(
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500768 name = "foo",
Liz Kammer356f7d42021-01-26 09:18:53 -0500769 cmd = "$(location //other:foo.tool) -s $(OUTS) $(SRCS)",
Jingwen Chen316e07c2020-12-14 09:09:52 -0500770 outs = [
771 "foo.out",
772 ],
773 srcs = [
774 "foo.in",
775 ],
776 tools = [
Liz Kammer356f7d42021-01-26 09:18:53 -0500777 "//other:foo.tool",
778 "//other:other.tool",
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500779 ],
780)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500781 },
782 fs: otherGenruleBp,
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500783 },
784 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500785 description: "genrule using $(locations) label should substitute first tool label automatically",
786 moduleTypeUnderTest: "genrule",
787 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
788 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
Liz Kammer356f7d42021-01-26 09:18:53 -0500789 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500790 bp: `genrule {
791 name: "foo",
792 out: ["foo.out"],
793 srcs: ["foo.in"],
794 tools: [":foo.tool", ":other.tool"],
795 cmd: "$(locations) -s $(out) $(in)",
796}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500797 expectedBazelTargets: []string{`genrule(
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500798 name = "foo",
Liz Kammer356f7d42021-01-26 09:18:53 -0500799 cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)",
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500800 outs = [
801 "foo.out",
802 ],
803 srcs = [
804 "foo.in",
805 ],
806 tools = [
Liz Kammer356f7d42021-01-26 09:18:53 -0500807 "//other:foo.tool",
808 "//other:other.tool",
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500809 ],
810)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500811 },
812 fs: otherGenruleBp,
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500813 },
814 {
Jingwen Chena42d6412021-01-26 21:57:27 -0500815 description: "genrule without tools or tool_files can convert successfully",
816 moduleTypeUnderTest: "genrule",
817 moduleTypeUnderTestFactory: genrule.GenRuleFactory,
818 moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
Liz Kammer356f7d42021-01-26 09:18:53 -0500819 depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500820 bp: `genrule {
821 name: "foo",
822 out: ["foo.out"],
823 srcs: ["foo.in"],
824 cmd: "cp $(in) $(out)",
825}`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500826 expectedBazelTargets: []string{`genrule(
Jingwen Chen885ee7a2021-01-26 03:16:49 -0500827 name = "foo",
828 cmd = "cp $(SRCS) $(OUTS)",
829 outs = [
830 "foo.out",
831 ],
832 srcs = [
833 "foo.in",
Jingwen Chen316e07c2020-12-14 09:09:52 -0500834 ],
835)`,
Liz Kammer356f7d42021-01-26 09:18:53 -0500836 },
Jingwen Chen316e07c2020-12-14 09:09:52 -0500837 },
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500838 }
839
840 dir := "."
841 for _, testCase := range testCases {
Liz Kammer356f7d42021-01-26 09:18:53 -0500842 fs := make(map[string][]byte)
843 toParse := []string{
844 "Android.bp",
845 }
846 for f, content := range testCase.fs {
847 if strings.HasSuffix(f, "Android.bp") {
848 toParse = append(toParse, f)
849 }
850 fs[f] = []byte(content)
851 }
852 config := android.TestConfig(buildDir, nil, testCase.bp, fs)
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500853 ctx := android.NewTestContext(config)
854 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
Liz Kammer356f7d42021-01-26 09:18:53 -0500855 for _, m := range testCase.depsMutators {
856 ctx.DepsBp2BuildMutators(m)
857 }
Jingwen Chena42d6412021-01-26 21:57:27 -0500858 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500859 ctx.RegisterForBazelConversion()
860
Liz Kammer356f7d42021-01-26 09:18:53 -0500861 _, errs := ctx.ParseFileList(dir, toParse)
862 if Errored(t, testCase.description, errs) {
863 continue
864 }
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500865 _, errs = ctx.ResolveDependencies(config)
Liz Kammer356f7d42021-01-26 09:18:53 -0500866 if Errored(t, testCase.description, errs) {
867 continue
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500868 }
869
Liz Kammer356f7d42021-01-26 09:18:53 -0500870 checkDir := dir
871 if testCase.dir != "" {
872 checkDir = testCase.dir
873 }
874 bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir]
875 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
876 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
877 } else {
878 for i, target := range bazelTargets {
879 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
880 t.Errorf(
881 "%s: Expected generated Bazel target to be '%s', got '%s'",
882 testCase.description,
883 w,
884 g,
885 )
886 }
887 }
Jingwen Chen32b4ece2021-01-21 03:20:18 -0500888 }
889 }
890}
Jingwen Chen041b1842021-02-01 00:23:25 -0500891
Liz Kammer356f7d42021-01-26 09:18:53 -0500892func Errored(t *testing.T, desc string, errs []error) bool {
893 t.Helper()
894 if len(errs) > 0 {
895 for _, err := range errs {
896 t.Errorf("%s: %s", desc, err)
897 }
898 return true
899 }
900 return false
901}
902
Jingwen Chen041b1842021-02-01 00:23:25 -0500903type bp2buildMutator = func(android.TopDownMutatorContext)
904
905func TestBp2BuildInlinesDefaults(t *testing.T) {
906 testCases := []struct {
907 moduleTypesUnderTest map[string]android.ModuleFactory
908 bp2buildMutatorsUnderTest map[string]bp2buildMutator
909 bp string
910 expectedBazelTarget string
911 description string
912 }{
913 {
914 moduleTypesUnderTest: map[string]android.ModuleFactory{
915 "genrule": genrule.GenRuleFactory,
916 "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() },
917 },
918 bp2buildMutatorsUnderTest: map[string]bp2buildMutator{
919 "genrule": genrule.GenruleBp2Build,
920 },
921 bp: `genrule_defaults {
922 name: "gen_defaults",
923 cmd: "do-something $(in) $(out)",
924}
925genrule {
926 name: "gen",
927 out: ["out"],
928 srcs: ["in1"],
929 defaults: ["gen_defaults"],
930}
931`,
932 expectedBazelTarget: `genrule(
933 name = "gen",
934 cmd = "do-something $(SRCS) $(OUTS)",
935 outs = [
936 "out",
937 ],
938 srcs = [
939 "in1",
940 ],
941)`,
942 description: "genrule applies properties from a genrule_defaults dependency if not specified",
943 },
944 {
945 moduleTypesUnderTest: map[string]android.ModuleFactory{
946 "genrule": genrule.GenRuleFactory,
947 "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() },
948 },
949 bp2buildMutatorsUnderTest: map[string]bp2buildMutator{
950 "genrule": genrule.GenruleBp2Build,
951 },
952 bp: `genrule_defaults {
953 name: "gen_defaults",
954 out: ["out-from-defaults"],
955 srcs: ["in-from-defaults"],
956 cmd: "cmd-from-defaults",
957}
958genrule {
959 name: "gen",
960 out: ["out"],
961 srcs: ["in1"],
962 defaults: ["gen_defaults"],
963 cmd: "do-something $(in) $(out)",
964}
965`,
966 expectedBazelTarget: `genrule(
967 name = "gen",
968 cmd = "do-something $(SRCS) $(OUTS)",
969 outs = [
970 "out-from-defaults",
971 "out",
972 ],
973 srcs = [
974 "in-from-defaults",
975 "in1",
976 ],
977)`,
978 description: "genrule does merges properties from a genrule_defaults dependency, latest-first",
979 },
980 {
981 moduleTypesUnderTest: map[string]android.ModuleFactory{
982 "genrule": genrule.GenRuleFactory,
983 "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() },
984 },
985 bp2buildMutatorsUnderTest: map[string]bp2buildMutator{
986 "genrule": genrule.GenruleBp2Build,
987 },
988 bp: `genrule_defaults {
989 name: "gen_defaults1",
990 cmd: "cp $(in) $(out)",
991}
992
993genrule_defaults {
994 name: "gen_defaults2",
995 srcs: ["in1"],
996}
997
998genrule {
999 name: "gen",
1000 out: ["out"],
1001 defaults: ["gen_defaults1", "gen_defaults2"],
1002}
1003`,
1004 expectedBazelTarget: `genrule(
1005 name = "gen",
1006 cmd = "cp $(SRCS) $(OUTS)",
1007 outs = [
1008 "out",
1009 ],
1010 srcs = [
1011 "in1",
1012 ],
1013)`,
1014 description: "genrule applies properties from list of genrule_defaults",
1015 },
1016 {
1017 moduleTypesUnderTest: map[string]android.ModuleFactory{
1018 "genrule": genrule.GenRuleFactory,
1019 "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() },
1020 },
1021 bp2buildMutatorsUnderTest: map[string]bp2buildMutator{
1022 "genrule": genrule.GenruleBp2Build,
1023 },
1024 bp: `genrule_defaults {
1025 name: "gen_defaults1",
1026 defaults: ["gen_defaults2"],
1027 cmd: "cmd1 $(in) $(out)", // overrides gen_defaults2's cmd property value.
1028}
1029
1030genrule_defaults {
1031 name: "gen_defaults2",
1032 defaults: ["gen_defaults3"],
1033 cmd: "cmd2 $(in) $(out)",
1034 out: ["out-from-2"],
1035 srcs: ["in1"],
1036}
1037
1038genrule_defaults {
1039 name: "gen_defaults3",
1040 out: ["out-from-3"],
1041 srcs: ["srcs-from-3"],
1042}
1043
1044genrule {
1045 name: "gen",
1046 out: ["out"],
1047 defaults: ["gen_defaults1"],
1048}
1049`,
1050 expectedBazelTarget: `genrule(
1051 name = "gen",
1052 cmd = "cmd1 $(SRCS) $(OUTS)",
1053 outs = [
1054 "out-from-3",
1055 "out-from-2",
1056 "out",
1057 ],
1058 srcs = [
1059 "srcs-from-3",
1060 "in1",
1061 ],
1062)`,
1063 description: "genrule applies properties from genrule_defaults transitively",
1064 },
1065 }
1066
1067 dir := "."
1068 for _, testCase := range testCases {
1069 config := android.TestConfig(buildDir, nil, testCase.bp, nil)
1070 ctx := android.NewTestContext(config)
1071 for m, factory := range testCase.moduleTypesUnderTest {
1072 ctx.RegisterModuleType(m, factory)
1073 }
1074 for mutator, f := range testCase.bp2buildMutatorsUnderTest {
1075 ctx.RegisterBp2BuildMutator(mutator, f)
1076 }
1077 ctx.RegisterForBazelConversion()
1078
1079 _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
1080 android.FailIfErrored(t, errs)
1081 _, errs = ctx.ResolveDependencies(config)
1082 android.FailIfErrored(t, errs)
1083
Jingwen Chen4d2c0872021-02-02 07:06:56 -05001084 bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
Jingwen Chen041b1842021-02-01 00:23:25 -05001085 if actualCount := len(bazelTargets); actualCount != 1 {
1086 t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount)
1087 }
1088
1089 actualBazelTarget := bazelTargets[0]
1090 if actualBazelTarget.content != testCase.expectedBazelTarget {
1091 t.Errorf(
1092 "%s: Expected generated Bazel target to be '%s', got '%s'",
1093 testCase.description,
1094 testCase.expectedBazelTarget,
1095 actualBazelTarget.content,
1096 )
1097 }
1098 }
1099}