diff options
Diffstat (limited to 'bp2build')
| -rw-r--r-- | bp2build/Android.bp | 2 | ||||
| -rw-r--r-- | bp2build/build_conversion_test.go | 528 | ||||
| -rw-r--r-- | bp2build/filegroup_conversion_test.go | 62 | ||||
| -rw-r--r-- | bp2build/genrule_conversion_test.go | 479 | ||||
| -rw-r--r-- | bp2build/testing.go | 44 |
5 files changed, 622 insertions, 493 deletions
diff --git a/bp2build/Android.bp b/bp2build/Android.bp index b1ccc963c..5ee04f989 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -39,6 +39,8 @@ bootstrap_go_package { "cc_library_static_conversion_test.go", "cc_object_conversion_test.go", "conversion_test.go", + "filegroup_conversion_test.go", + "genrule_conversion_test.go", "performance_test.go", "prebuilt_etc_conversion_test.go", "python_binary_conversion_test.go", diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index 0d9106c96..ecea6b2d5 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -16,7 +16,6 @@ package bp2build import ( "android/soong/android" - "android/soong/genrule" "strings" "testing" ) @@ -218,13 +217,9 @@ func TestGenerateSoongModuleTargets(t *testing.T) { } func TestGenerateBazelTargetModules(t *testing.T) { - testCases := []struct { - name string - bp string - expectedBazelTargets []string - }{ + testCases := []bp2buildTestCase{ { - bp: `custom { + blueprint: `custom { name: "foo", string_list_prop: ["a", "b"], string_prop: "a", @@ -241,7 +236,7 @@ func TestGenerateBazelTargetModules(t *testing.T) { }, }, { - bp: `custom { + blueprint: `custom { name: "control_characters", string_list_prop: ["\t", "\n"], string_prop: "a\t\n\r", @@ -258,7 +253,7 @@ func TestGenerateBazelTargetModules(t *testing.T) { }, }, { - bp: `custom { + blueprint: `custom { name: "has_dep", arch_paths: [":dep"], bazel_module: { bp2build_available: true }, @@ -280,7 +275,7 @@ custom { }, }, { - bp: `custom { + blueprint: `custom { name: "arch_paths", arch: { x86: { @@ -299,7 +294,7 @@ custom { }, }, { - bp: `custom { + blueprint: `custom { name: "has_dep", arch: { x86: { @@ -331,17 +326,17 @@ custom { dir := "." for _, testCase := range testCases { - config := android.TestConfig(buildDir, nil, testCase.bp, nil) + config := android.TestConfig(buildDir, nil, testCase.blueprint, nil) ctx := android.NewTestContext(config) registerCustomModuleForBp2buildConversion(ctx) _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) - if errored(t, "", errs) { + if errored(t, testCase, errs) { continue } _, errs = ctx.ResolveDependencies(config) - if errored(t, "", errs) { + if errored(t, testCase, errs) { continue } @@ -533,38 +528,13 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, } func TestModuleTypeBp2Build(t *testing.T) { - otherGenruleBp := map[string]string{ - "other/Android.bp": `genrule { - name: "foo.tool", - out: ["foo_tool.out"], - srcs: ["foo_tool.in"], - cmd: "cp $(in) $(out)", -} -genrule { - name: "other.tool", - out: ["other_tool.out"], - srcs: ["other_tool.in"], - cmd: "cp $(in) $(out)", -}`, - } - - testCases := []struct { - description string - moduleTypeUnderTest string - moduleTypeUnderTestFactory android.ModuleFactory - moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext) - preArchMutators []android.RegisterMutatorFunc - bp string - expectedBazelTargets []string - fs map[string]string - dir string - }{ + testCases := []bp2buildTestCase{ { description: "filegroup with does not specify srcs", moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", bazel_module: { bp2build_available: true }, }`, @@ -579,7 +549,7 @@ genrule { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", srcs: [], bazel_module: { bp2build_available: true }, @@ -595,7 +565,7 @@ genrule { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", srcs: ["a", "b"], bazel_module: { bp2build_available: true }, @@ -614,7 +584,7 @@ genrule { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", srcs: ["a", "b"], exclude_srcs: ["a"], @@ -631,7 +601,7 @@ genrule { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "foo", srcs: ["**/*.txt"], bazel_module: { bp2build_available: true }, @@ -645,7 +615,7 @@ genrule { ], )`, }, - fs: map[string]string{ + filesystem: map[string]string{ "other/a.txt": "", "other/b.txt": "", "other/subdir/a.txt": "", @@ -657,7 +627,7 @@ genrule { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "foo", srcs: ["a.txt"], bazel_module: { bp2build_available: true }, @@ -672,7 +642,7 @@ genrule { ], )`, }, - fs: map[string]string{ + filesystem: map[string]string{ "other/Android.bp": `filegroup { name: "fg_foo", srcs: ["**/*.txt"], @@ -689,7 +659,7 @@ genrule { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "foobar", srcs: [ ":foo", @@ -705,207 +675,13 @@ genrule { ], )`, }, - fs: map[string]string{ + filesystem: map[string]string{ "other/Android.bp": `filegroup { name: "foo", srcs: ["a", "b"], }`, }, }, - { - description: "genrule with command line variable replacements", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo.tool", - out: ["foo_tool.out"], - srcs: ["foo_tool.in"], - cmd: "cp $(in) $(out)", - bazel_module: { bp2build_available: true }, -} - -genrule { - name: "foo", - out: ["foo.out"], - srcs: ["foo.in"], - tools: [":foo.tool"], - cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{ - `genrule( - name = "foo", - cmd = "$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)", - outs = ["foo.out"], - srcs = ["foo.in"], - tools = [":foo.tool"], -)`, - `genrule( - name = "foo.tool", - cmd = "cp $(SRCS) $(OUTS)", - outs = ["foo_tool.out"], - srcs = ["foo_tool.in"], -)`, - }, - }, - { - description: "genrule using $(locations :label)", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo.tools", - out: ["foo_tool.out", "foo_tool2.out"], - srcs: ["foo_tool.in"], - cmd: "cp $(in) $(out)", - bazel_module: { bp2build_available: true }, -} - -genrule { - name: "foo", - out: ["foo.out"], - srcs: ["foo.in"], - tools: [":foo.tools"], - cmd: "$(locations :foo.tools) -s $(out) $(in)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`genrule( - name = "foo", - cmd = "$(locations :foo.tools) -s $(OUTS) $(SRCS)", - outs = ["foo.out"], - srcs = ["foo.in"], - tools = [":foo.tools"], -)`, - `genrule( - name = "foo.tools", - cmd = "cp $(SRCS) $(OUTS)", - outs = [ - "foo_tool.out", - "foo_tool2.out", - ], - srcs = ["foo_tool.in"], -)`, - }, - }, - { - description: "genrule using $(locations //absolute:label)", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo", - out: ["foo.out"], - srcs: ["foo.in"], - tool_files: [":foo.tool"], - cmd: "$(locations :foo.tool) -s $(out) $(in)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`genrule( - name = "foo", - cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)", - outs = ["foo.out"], - srcs = ["foo.in"], - tools = ["//other:foo.tool"], -)`, - }, - fs: otherGenruleBp, - }, - { - description: "genrule srcs using $(locations //absolute:label)", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo", - out: ["foo.out"], - srcs: [":other.tool"], - tool_files: [":foo.tool"], - cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`genrule( - name = "foo", - cmd = "$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)", - outs = ["foo.out"], - srcs = ["//other:other.tool"], - tools = ["//other:foo.tool"], -)`, - }, - fs: otherGenruleBp, - }, - { - description: "genrule using $(location) label should substitute first tool label automatically", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo", - out: ["foo.out"], - srcs: ["foo.in"], - tool_files: [":foo.tool", ":other.tool"], - cmd: "$(location) -s $(out) $(in)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`genrule( - name = "foo", - cmd = "$(location //other:foo.tool) -s $(OUTS) $(SRCS)", - outs = ["foo.out"], - srcs = ["foo.in"], - tools = [ - "//other:foo.tool", - "//other:other.tool", - ], -)`, - }, - fs: otherGenruleBp, - }, - { - description: "genrule using $(locations) label should substitute first tool label automatically", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo", - out: ["foo.out"], - srcs: ["foo.in"], - tools: [":foo.tool", ":other.tool"], - cmd: "$(locations) -s $(out) $(in)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`genrule( - name = "foo", - cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)", - outs = ["foo.out"], - srcs = ["foo.in"], - tools = [ - "//other:foo.tool", - "//other:other.tool", - ], -)`, - }, - fs: otherGenruleBp, - }, - { - description: "genrule without tools or tool_files can convert successfully", - moduleTypeUnderTest: "genrule", - moduleTypeUnderTestFactory: genrule.GenRuleFactory, - moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, - bp: `genrule { - name: "foo", - out: ["foo.out"], - srcs: ["foo.in"], - cmd: "cp $(in) $(out)", - bazel_module: { bp2build_available: true }, -}`, - expectedBazelTargets: []string{`genrule( - name = "foo", - cmd = "cp $(SRCS) $(OUTS)", - outs = ["foo.out"], - srcs = ["foo.in"], -)`, - }, - }, } dir := "." @@ -914,24 +690,24 @@ genrule { toParse := []string{ "Android.bp", } - for f, content := range testCase.fs { + for f, content := range testCase.filesystem { if strings.HasSuffix(f, "Android.bp") { toParse = append(toParse, f) } fs[f] = []byte(content) } - config := android.TestConfig(buildDir, nil, testCase.bp, fs) + config := android.TestConfig(buildDir, nil, testCase.blueprint, fs) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, toParse) - if errored(t, testCase.description, errs) { + if errored(t, testCase, errs) { continue } _, errs = ctx.ResolveDependencies(config) - if errored(t, testCase.description, errs) { + if errored(t, testCase, errs) { continue } @@ -961,199 +737,6 @@ genrule { type bp2buildMutator = func(android.TopDownMutatorContext) -func TestBp2BuildInlinesDefaults(t *testing.T) { - testCases := []struct { - moduleTypesUnderTest map[string]android.ModuleFactory - bp2buildMutatorsUnderTest map[string]bp2buildMutator - bp string - expectedBazelTarget string - description string - }{ - { - moduleTypesUnderTest: map[string]android.ModuleFactory{ - "genrule": genrule.GenRuleFactory, - "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, - }, - bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ - "genrule": genrule.GenruleBp2Build, - }, - bp: `genrule_defaults { - name: "gen_defaults", - cmd: "do-something $(in) $(out)", -} -genrule { - name: "gen", - out: ["out"], - srcs: ["in1"], - defaults: ["gen_defaults"], - bazel_module: { bp2build_available: true }, -} -`, - expectedBazelTarget: `genrule( - name = "gen", - cmd = "do-something $(SRCS) $(OUTS)", - outs = ["out"], - srcs = ["in1"], -)`, - description: "genrule applies properties from a genrule_defaults dependency if not specified", - }, - { - moduleTypesUnderTest: map[string]android.ModuleFactory{ - "genrule": genrule.GenRuleFactory, - "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, - }, - bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ - "genrule": genrule.GenruleBp2Build, - }, - bp: `genrule_defaults { - name: "gen_defaults", - out: ["out-from-defaults"], - srcs: ["in-from-defaults"], - cmd: "cmd-from-defaults", -} -genrule { - name: "gen", - out: ["out"], - srcs: ["in1"], - defaults: ["gen_defaults"], - cmd: "do-something $(in) $(out)", - bazel_module: { bp2build_available: true }, -} -`, - expectedBazelTarget: `genrule( - name = "gen", - cmd = "do-something $(SRCS) $(OUTS)", - outs = [ - "out-from-defaults", - "out", - ], - srcs = [ - "in-from-defaults", - "in1", - ], -)`, - description: "genrule does merges properties from a genrule_defaults dependency, latest-first", - }, - { - moduleTypesUnderTest: map[string]android.ModuleFactory{ - "genrule": genrule.GenRuleFactory, - "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, - }, - bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ - "genrule": genrule.GenruleBp2Build, - }, - bp: `genrule_defaults { - name: "gen_defaults1", - cmd: "cp $(in) $(out)", -} - -genrule_defaults { - name: "gen_defaults2", - srcs: ["in1"], -} - -genrule { - name: "gen", - out: ["out"], - defaults: ["gen_defaults1", "gen_defaults2"], - bazel_module: { bp2build_available: true }, -} -`, - expectedBazelTarget: `genrule( - name = "gen", - cmd = "cp $(SRCS) $(OUTS)", - outs = ["out"], - srcs = ["in1"], -)`, - description: "genrule applies properties from list of genrule_defaults", - }, - { - moduleTypesUnderTest: map[string]android.ModuleFactory{ - "genrule": genrule.GenRuleFactory, - "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, - }, - bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ - "genrule": genrule.GenruleBp2Build, - }, - bp: `genrule_defaults { - name: "gen_defaults1", - defaults: ["gen_defaults2"], - cmd: "cmd1 $(in) $(out)", // overrides gen_defaults2's cmd property value. -} - -genrule_defaults { - name: "gen_defaults2", - defaults: ["gen_defaults3"], - cmd: "cmd2 $(in) $(out)", - out: ["out-from-2"], - srcs: ["in1"], -} - -genrule_defaults { - name: "gen_defaults3", - out: ["out-from-3"], - srcs: ["srcs-from-3"], -} - -genrule { - name: "gen", - out: ["out"], - defaults: ["gen_defaults1"], - bazel_module: { bp2build_available: true }, -} -`, - expectedBazelTarget: `genrule( - name = "gen", - cmd = "cmd1 $(SRCS) $(OUTS)", - outs = [ - "out-from-3", - "out-from-2", - "out", - ], - srcs = [ - "srcs-from-3", - "in1", - ], -)`, - description: "genrule applies properties from genrule_defaults transitively", - }, - } - - dir := "." - for _, testCase := range testCases { - config := android.TestConfig(buildDir, nil, testCase.bp, nil) - ctx := android.NewTestContext(config) - for m, factory := range testCase.moduleTypesUnderTest { - ctx.RegisterModuleType(m, factory) - } - for mutator, f := range testCase.bp2buildMutatorsUnderTest { - ctx.RegisterBp2BuildMutator(mutator, f) - } - ctx.RegisterForBazelConversion() - - _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) - android.FailIfErrored(t, errs) - _, errs = ctx.ResolveDependencies(config) - android.FailIfErrored(t, errs) - - codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) - bazelTargets := generateBazelTargetsForDir(codegenCtx, dir) - if actualCount := len(bazelTargets); actualCount != 1 { - t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount) - } - - actualBazelTarget := bazelTargets[0] - if actualBazelTarget.content != testCase.expectedBazelTarget { - t.Errorf( - "%s: Expected generated Bazel target to be '%s', got '%s'", - testCase.description, - testCase.expectedBazelTarget, - actualBazelTarget.content, - ) - } - } -} - func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { testCases := []struct { moduleTypeUnderTest string @@ -1353,30 +936,20 @@ filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } } } func TestCombineBuildFilesBp2buildTargets(t *testing.T) { - testCases := []struct { - description string - moduleTypeUnderTest string - moduleTypeUnderTestFactory android.ModuleFactory - moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext) - preArchMutators []android.RegisterMutatorFunc - bp string - expectedBazelTargets []string - fs map[string]string - dir string - }{ + testCases := []bp2buildTestCase{ { description: "filegroup bazel_module.label", moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", bazel_module: { label: "//other:fg_foo" }, }`, expectedBazelTargets: []string{ `// BUILD file`, }, - fs: map[string]string{ + filesystem: map[string]string{ "other/BUILD.bazel": `// BUILD file`, }, }, @@ -1385,7 +958,7 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", bazel_module: { label: "//other:fg_foo" }, } @@ -1397,7 +970,7 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { expectedBazelTargets: []string{ `// BUILD file`, }, - fs: map[string]string{ + filesystem: map[string]string{ "other/BUILD.bazel": `// BUILD file`, }, }, @@ -1407,8 +980,8 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, dir: "other", - bp: ``, - fs: map[string]string{ + blueprint: ``, + filesystem: map[string]string{ "other/Android.bp": `filegroup { name: "fg_foo", bazel_module: { @@ -1434,7 +1007,7 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", bazel_module: { label: "//other:fg_foo", @@ -1453,7 +1026,7 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { )`, `// BUILD file`, }, - fs: map[string]string{ + filesystem: map[string]string{ "other/BUILD.bazel": `// BUILD file`, }, }, @@ -1466,24 +1039,24 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { toParse := []string{ "Android.bp", } - for f, content := range testCase.fs { + for f, content := range testCase.filesystem { if strings.HasSuffix(f, "Android.bp") { toParse = append(toParse, f) } fs[f] = []byte(content) } - config := android.TestConfig(buildDir, nil, testCase.bp, fs) + config := android.TestConfig(buildDir, nil, testCase.blueprint, fs) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, toParse) - if errored(t, testCase.description, errs) { + if errored(t, testCase, errs) { return } _, errs = ctx.ResolveDependencies(config) - if errored(t, testCase.description, errs) { + if errored(t, testCase, errs) { return } @@ -1517,22 +1090,13 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { } func TestGlobExcludeSrcs(t *testing.T) { - testCases := []struct { - description string - moduleTypeUnderTest string - moduleTypeUnderTestFactory android.ModuleFactory - moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext) - bp string - expectedBazelTargets []string - fs map[string]string - dir string - }{ + testCases := []bp2buildTestCase{ { description: "filegroup top level exclude_srcs", moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: `filegroup { + blueprint: `filegroup { name: "fg_foo", srcs: ["**/*.txt"], exclude_srcs: ["c.txt"], @@ -1548,7 +1112,7 @@ func TestGlobExcludeSrcs(t *testing.T) { ], )`, }, - fs: map[string]string{ + filesystem: map[string]string{ "a.txt": "", "b.txt": "", "c.txt": "", @@ -1562,9 +1126,9 @@ func TestGlobExcludeSrcs(t *testing.T) { moduleTypeUnderTest: "filegroup", moduleTypeUnderTestFactory: android.FileGroupFactory, moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - bp: "", + blueprint: "", dir: "dir", - fs: map[string]string{ + filesystem: map[string]string{ "dir/Android.bp": `filegroup { name: "fg_foo", srcs: ["**/*.txt"], @@ -1596,24 +1160,24 @@ func TestGlobExcludeSrcs(t *testing.T) { toParse := []string{ "Android.bp", } - for f, content := range testCase.fs { + for f, content := range testCase.filesystem { if strings.HasSuffix(f, "Android.bp") { toParse = append(toParse, f) } fs[f] = []byte(content) } - config := android.TestConfig(buildDir, nil, testCase.bp, fs) + config := android.TestConfig(buildDir, nil, testCase.blueprint, fs) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, toParse) - if errored(t, testCase.description, errs) { + if errored(t, testCase, errs) { continue } _, errs = ctx.ResolveDependencies(config) - if errored(t, testCase.description, errs) { + if errored(t, testCase, errs) { continue } diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go new file mode 100644 index 000000000..ad9923610 --- /dev/null +++ b/bp2build/filegroup_conversion_test.go @@ -0,0 +1,62 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "fmt" + + "testing" +) + +func runFilegroupTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + runBp2BuildTestCase(t, registerFilegroupModuleTypes, tc) +} + +func registerFilegroupModuleTypes(ctx android.RegistrationContext) {} + +func TestFilegroupSameNameAsFile_OneFile(t *testing.T) { + runFilegroupTestCase(t, bp2buildTestCase{ + description: "filegroup - same name as file, with one file", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + filesystem: map[string]string{}, + blueprint: ` +filegroup { + name: "foo", + srcs: ["foo"], +} +`, + expectedBazelTargets: []string{}}) +} + +func TestFilegroupSameNameAsFile_MultipleFiles(t *testing.T) { + runFilegroupTestCase(t, bp2buildTestCase{ + description: "filegroup - same name as file, with multiple files", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + filesystem: map[string]string{}, + blueprint: ` +filegroup { + name: "foo", + srcs: ["foo", "bar"], +} +`, + expectedErr: fmt.Errorf("filegroup 'foo' cannot contain a file with the same name"), + }) +} diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go new file mode 100644 index 000000000..a9911808e --- /dev/null +++ b/bp2build/genrule_conversion_test.go @@ -0,0 +1,479 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "android/soong/genrule" + "strings" + "testing" +) + +func TestGenruleBp2Build(t *testing.T) { + otherGenruleBp := map[string]string{ + "other/Android.bp": `genrule { + name: "foo.tool", + out: ["foo_tool.out"], + srcs: ["foo_tool.in"], + cmd: "cp $(in) $(out)", +} +genrule { + name: "other.tool", + out: ["other_tool.out"], + srcs: ["other_tool.in"], + cmd: "cp $(in) $(out)", +}`, + } + + testCases := []bp2buildTestCase{ + { + description: "genrule with command line variable replacements", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo.tool", + out: ["foo_tool.out"], + srcs: ["foo_tool.in"], + cmd: "cp $(in) $(out)", + bazel_module: { bp2build_available: true }, +} + +genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tools: [":foo.tool"], + cmd: "$(location :foo.tool) --genDir=$(genDir) arg $(in) $(out)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + `genrule( + name = "foo", + cmd = "$(location :foo.tool) --genDir=$(GENDIR) arg $(SRCS) $(OUTS)", + outs = ["foo.out"], + srcs = ["foo.in"], + tools = [":foo.tool"], +)`, + `genrule( + name = "foo.tool", + cmd = "cp $(SRCS) $(OUTS)", + outs = ["foo_tool.out"], + srcs = ["foo_tool.in"], +)`, + }, + }, + { + description: "genrule using $(locations :label)", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo.tools", + out: ["foo_tool.out", "foo_tool2.out"], + srcs: ["foo_tool.in"], + cmd: "cp $(in) $(out)", + bazel_module: { bp2build_available: true }, +} + +genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tools: [":foo.tools"], + cmd: "$(locations :foo.tools) -s $(out) $(in)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(locations :foo.tools) -s $(OUTS) $(SRCS)", + outs = ["foo.out"], + srcs = ["foo.in"], + tools = [":foo.tools"], +)`, + `genrule( + name = "foo.tools", + cmd = "cp $(SRCS) $(OUTS)", + outs = [ + "foo_tool.out", + "foo_tool2.out", + ], + srcs = ["foo_tool.in"], +)`, + }, + }, + { + description: "genrule using $(locations //absolute:label)", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tool_files: [":foo.tool"], + cmd: "$(locations :foo.tool) -s $(out) $(in)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)", + outs = ["foo.out"], + srcs = ["foo.in"], + tools = ["//other:foo.tool"], +)`, + }, + filesystem: otherGenruleBp, + }, + { + description: "genrule srcs using $(locations //absolute:label)", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo", + out: ["foo.out"], + srcs: [":other.tool"], + tool_files: [":foo.tool"], + cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)", + outs = ["foo.out"], + srcs = ["//other:other.tool"], + tools = ["//other:foo.tool"], +)`, + }, + filesystem: otherGenruleBp, + }, + { + description: "genrule using $(location) label should substitute first tool label automatically", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tool_files: [":foo.tool", ":other.tool"], + cmd: "$(location) -s $(out) $(in)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(location //other:foo.tool) -s $(OUTS) $(SRCS)", + outs = ["foo.out"], + srcs = ["foo.in"], + tools = [ + "//other:foo.tool", + "//other:other.tool", + ], +)`, + }, + filesystem: otherGenruleBp, + }, + { + description: "genrule using $(locations) label should substitute first tool label automatically", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + tools: [":foo.tool", ":other.tool"], + cmd: "$(locations) -s $(out) $(in)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "$(locations //other:foo.tool) -s $(OUTS) $(SRCS)", + outs = ["foo.out"], + srcs = ["foo.in"], + tools = [ + "//other:foo.tool", + "//other:other.tool", + ], +)`, + }, + filesystem: otherGenruleBp, + }, + { + description: "genrule without tools or tool_files can convert successfully", + moduleTypeUnderTest: "genrule", + moduleTypeUnderTestFactory: genrule.GenRuleFactory, + moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build, + blueprint: `genrule { + name: "foo", + out: ["foo.out"], + srcs: ["foo.in"], + cmd: "cp $(in) $(out)", + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{`genrule( + name = "foo", + cmd = "cp $(SRCS) $(OUTS)", + outs = ["foo.out"], + srcs = ["foo.in"], +)`, + }, + }, + } + + dir := "." + for _, testCase := range testCases { + fs := make(map[string][]byte) + toParse := []string{ + "Android.bp", + } + for f, content := range testCase.filesystem { + if strings.HasSuffix(f, "Android.bp") { + toParse = append(toParse, f) + } + fs[f] = []byte(content) + } + config := android.TestConfig(buildDir, nil, testCase.blueprint, fs) + ctx := android.NewTestContext(config) + ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) + ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) + ctx.RegisterForBazelConversion() + + _, errs := ctx.ParseFileList(dir, toParse) + if errored(t, testCase, errs) { + continue + } + _, errs = ctx.ResolveDependencies(config) + if errored(t, testCase, errs) { + continue + } + + checkDir := dir + if testCase.dir != "" { + checkDir = testCase.dir + } + + codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) + bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir) + if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { + t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) + } else { + for i, target := range bazelTargets { + if w, g := testCase.expectedBazelTargets[i], target.content; w != g { + t.Errorf( + "%s: Expected generated Bazel target to be '%s', got '%s'", + testCase.description, + w, + g, + ) + } + } + } + } +} + +func TestBp2BuildInlinesDefaults(t *testing.T) { + testCases := []struct { + moduleTypesUnderTest map[string]android.ModuleFactory + bp2buildMutatorsUnderTest map[string]bp2buildMutator + bp string + expectedBazelTarget string + description string + }{ + { + moduleTypesUnderTest: map[string]android.ModuleFactory{ + "genrule": genrule.GenRuleFactory, + "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, + }, + bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ + "genrule": genrule.GenruleBp2Build, + }, + bp: `genrule_defaults { + name: "gen_defaults", + cmd: "do-something $(in) $(out)", +} +genrule { + name: "gen", + out: ["out"], + srcs: ["in1"], + defaults: ["gen_defaults"], + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTarget: `genrule( + name = "gen", + cmd = "do-something $(SRCS) $(OUTS)", + outs = ["out"], + srcs = ["in1"], +)`, + description: "genrule applies properties from a genrule_defaults dependency if not specified", + }, + { + moduleTypesUnderTest: map[string]android.ModuleFactory{ + "genrule": genrule.GenRuleFactory, + "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, + }, + bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ + "genrule": genrule.GenruleBp2Build, + }, + bp: `genrule_defaults { + name: "gen_defaults", + out: ["out-from-defaults"], + srcs: ["in-from-defaults"], + cmd: "cmd-from-defaults", +} +genrule { + name: "gen", + out: ["out"], + srcs: ["in1"], + defaults: ["gen_defaults"], + cmd: "do-something $(in) $(out)", + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTarget: `genrule( + name = "gen", + cmd = "do-something $(SRCS) $(OUTS)", + outs = [ + "out-from-defaults", + "out", + ], + srcs = [ + "in-from-defaults", + "in1", + ], +)`, + description: "genrule does merges properties from a genrule_defaults dependency, latest-first", + }, + { + moduleTypesUnderTest: map[string]android.ModuleFactory{ + "genrule": genrule.GenRuleFactory, + "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, + }, + bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ + "genrule": genrule.GenruleBp2Build, + }, + bp: `genrule_defaults { + name: "gen_defaults1", + cmd: "cp $(in) $(out)", +} + +genrule_defaults { + name: "gen_defaults2", + srcs: ["in1"], +} + +genrule { + name: "gen", + out: ["out"], + defaults: ["gen_defaults1", "gen_defaults2"], + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTarget: `genrule( + name = "gen", + cmd = "cp $(SRCS) $(OUTS)", + outs = ["out"], + srcs = ["in1"], +)`, + description: "genrule applies properties from list of genrule_defaults", + }, + { + moduleTypesUnderTest: map[string]android.ModuleFactory{ + "genrule": genrule.GenRuleFactory, + "genrule_defaults": func() android.Module { return genrule.DefaultsFactory() }, + }, + bp2buildMutatorsUnderTest: map[string]bp2buildMutator{ + "genrule": genrule.GenruleBp2Build, + }, + bp: `genrule_defaults { + name: "gen_defaults1", + defaults: ["gen_defaults2"], + cmd: "cmd1 $(in) $(out)", // overrides gen_defaults2's cmd property value. +} + +genrule_defaults { + name: "gen_defaults2", + defaults: ["gen_defaults3"], + cmd: "cmd2 $(in) $(out)", + out: ["out-from-2"], + srcs: ["in1"], +} + +genrule_defaults { + name: "gen_defaults3", + out: ["out-from-3"], + srcs: ["srcs-from-3"], +} + +genrule { + name: "gen", + out: ["out"], + defaults: ["gen_defaults1"], + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTarget: `genrule( + name = "gen", + cmd = "cmd1 $(SRCS) $(OUTS)", + outs = [ + "out-from-3", + "out-from-2", + "out", + ], + srcs = [ + "srcs-from-3", + "in1", + ], +)`, + description: "genrule applies properties from genrule_defaults transitively", + }, + } + + dir := "." + for _, testCase := range testCases { + config := android.TestConfig(buildDir, nil, testCase.bp, nil) + ctx := android.NewTestContext(config) + for m, factory := range testCase.moduleTypesUnderTest { + ctx.RegisterModuleType(m, factory) + } + for mutator, f := range testCase.bp2buildMutatorsUnderTest { + ctx.RegisterBp2BuildMutator(mutator, f) + } + ctx.RegisterForBazelConversion() + + _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) + android.FailIfErrored(t, errs) + _, errs = ctx.ResolveDependencies(config) + android.FailIfErrored(t, errs) + + codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) + bazelTargets := generateBazelTargetsForDir(codegenCtx, dir) + if actualCount := len(bazelTargets); actualCount != 1 { + t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount) + } + + actualBazelTarget := bazelTargets[0] + if actualBazelTarget.content != testCase.expectedBazelTarget { + t.Errorf( + "%s: Expected generated Bazel target to be '%s', got '%s'", + testCase.description, + testCase.expectedBazelTarget, + actualBazelTarget.content, + ) + } + } +} diff --git a/bp2build/testing.go b/bp2build/testing.go index a549a9369..3ebe63d5a 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -36,14 +36,35 @@ var ( buildDir string ) -func errored(t *testing.T, desc string, errs []error) bool { +func checkError(t *testing.T, errs []error, expectedErr error) bool { t.Helper() + + // expectedErr is not nil, find it in the list of errors + if len(errs) != 1 { + t.Errorf("Expected only 1 error, got %d: %q", len(errs), errs) + } + if errs[0].Error() == expectedErr.Error() { + return true + } + + return false +} + +func errored(t *testing.T, tc bp2buildTestCase, errs []error) bool { + t.Helper() + if tc.expectedErr != nil { + // Rely on checkErrors, as this test case is expected to have an error. + return false + } + if len(errs) > 0 { for _, err := range errs { - t.Errorf("%s: %s", desc, err) + t.Errorf("%s: %s", tc.description, err) } return true } + + // All good, continue execution. return false } @@ -61,6 +82,7 @@ type bp2buildTestCase struct { expectedBazelTargets []string filesystem map[string]string dir string + expectedErr error } func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) { @@ -85,12 +107,17 @@ func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.Regi ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() - _, errs := ctx.ParseFileList(dir, toParse) - if errored(t, tc.description, errs) { + _, parseErrs := ctx.ParseFileList(dir, toParse) + if errored(t, tc, parseErrs) { + return + } + _, resolveDepsErrs := ctx.ResolveDependencies(config) + if errored(t, tc, resolveDepsErrs) { return } - _, errs = ctx.ResolveDependencies(config) - if errored(t, tc.description, errs) { + + errs := append(parseErrs, resolveDepsErrs...) + if tc.expectedErr != nil && checkError(t, errs, tc.expectedErr) { return } @@ -225,11 +252,6 @@ type customBazelModuleAttributes struct { Arch_paths bazel.LabelListAttribute } -type customBazelModule struct { - android.BazelTargetModuleBase - customBazelModuleAttributes -} - func customBp2BuildMutator(ctx android.TopDownMutatorContext) { if m, ok := ctx.Module().(*customModule); ok { if !m.ConvertWithBp2build(ctx) { |