blob: d8e572d66e62cb60932e89fb6600ea79e8b5d52f [file] [log] [blame]
Liz Kammer2dd9ca42020-11-25 16:06:39 -08001package bp2build
2
3import (
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +00004 "strings"
Rupert Shuttleworth06559d02021-05-19 09:14:26 -04005 "testing"
6
Liz Kammer2dd9ca42020-11-25 16:06:39 -08007 "android/soong/android"
Jingwen Chen73850672020-12-14 08:25:34 -05008 "android/soong/bazel"
Liz Kammer2dd9ca42020-11-25 16:06:39 -08009)
10
Jingwen Chen91220d72021-03-24 02:18:33 -040011var (
12 // A default configuration for tests to not have to specify bp2build_available on top level targets.
13 bp2buildConfig = android.Bp2BuildConfig{
14 android.BP2BUILD_TOPLEVEL: android.Bp2BuildDefaultTrueRecursively,
15 }
Rupert Shuttleworth06559d02021-05-19 09:14:26 -040016
17 buildDir string
Jingwen Chen91220d72021-03-24 02:18:33 -040018)
19
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000020func errored(t *testing.T, desc string, errs []error) bool {
21 t.Helper()
22 if len(errs) > 0 {
23 for _, err := range errs {
24 t.Errorf("%s: %s", desc, err)
25 }
26 return true
27 }
28 return false
29}
30
31func runPythonTestCase(t *testing.T, tc bp2buildTestCase) {
32 t.Helper()
33 runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
34}
35
36type bp2buildTestCase struct {
37 description string
38 moduleTypeUnderTest string
39 moduleTypeUnderTestFactory android.ModuleFactory
40 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
41 blueprint string
42 expectedBazelTargets []string
43 filesystem map[string]string
44 dir string
45}
46
47func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
48 t.Helper()
49 dir := "."
50 filesystem := make(map[string][]byte)
51 toParse := []string{
52 "Android.bp",
53 }
54 for f, content := range tc.filesystem {
55 if strings.HasSuffix(f, "Android.bp") {
56 toParse = append(toParse, f)
57 }
58 filesystem[f] = []byte(content)
59 }
60 config := android.TestConfig(buildDir, nil, tc.blueprint, filesystem)
61 ctx := android.NewTestContext(config)
62
63 registerModuleTypes(ctx)
64 ctx.RegisterModuleType(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestFactory)
65 ctx.RegisterBp2BuildConfig(bp2buildConfig)
66 ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator)
67 ctx.RegisterForBazelConversion()
68
69 _, errs := ctx.ParseFileList(dir, toParse)
70 if errored(t, tc.description, errs) {
71 return
72 }
73 _, errs = ctx.ResolveDependencies(config)
74 if errored(t, tc.description, errs) {
75 return
76 }
77
78 checkDir := dir
79 if tc.dir != "" {
80 checkDir = tc.dir
81 }
82 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
83 bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
84 if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
85 t.Errorf("%s: Expected %d bazel target, got %d", tc.description, expectedCount, actualCount)
86 } else {
87 for i, target := range bazelTargets {
88 if w, g := tc.expectedBazelTargets[i], target.content; w != g {
89 t.Errorf(
90 "%s: Expected generated Bazel target to be '%s', got '%s'",
91 tc.description,
92 w,
93 g,
94 )
95 }
96 }
97 }
98}
99
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800100type nestedProps struct {
101 Nested_prop string
102}
103
104type customProps struct {
105 Bool_prop bool
106 Bool_ptr_prop *bool
107 // Ensure that properties tagged `blueprint:mutated` are omitted
108 Int_prop int `blueprint:"mutated"`
109 Int64_ptr_prop *int64
110 String_prop string
111 String_ptr_prop *string
112 String_list_prop []string
113
114 Nested_props nestedProps
115 Nested_props_ptr *nestedProps
Liz Kammer4562a3b2021-04-21 18:15:34 -0400116
Liz Kammer32b77cf2021-08-04 15:17:02 -0400117 Arch_paths []string `android:"path,arch_variant"`
118 Arch_paths_exclude []string `android:"path,arch_variant"`
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800119}
120
121type customModule struct {
122 android.ModuleBase
Liz Kammerea6666f2021-02-17 10:17:28 -0500123 android.BazelModuleBase
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800124
125 props customProps
126}
127
128// OutputFiles is needed because some instances of this module use dist with a
129// tag property which requires the module implements OutputFileProducer.
130func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
131 return android.PathsForTesting("path" + tag), nil
132}
133
134func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
135 // nothing for now.
136}
137
138func customModuleFactoryBase() android.Module {
139 module := &customModule{}
140 module.AddProperties(&module.props)
Liz Kammerea6666f2021-02-17 10:17:28 -0500141 android.InitBazelModule(module)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800142 return module
143}
144
145func customModuleFactory() android.Module {
146 m := customModuleFactoryBase()
Liz Kammer4562a3b2021-04-21 18:15:34 -0400147 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800148 return m
149}
150
151type testProps struct {
152 Test_prop struct {
153 Test_string_prop string
154 }
155}
156
157type customTestModule struct {
158 android.ModuleBase
159
160 props customProps
161 test_props testProps
162}
163
164func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
165 // nothing for now.
166}
167
168func customTestModuleFactoryBase() android.Module {
169 m := &customTestModule{}
170 m.AddProperties(&m.props)
171 m.AddProperties(&m.test_props)
172 return m
173}
174
175func customTestModuleFactory() android.Module {
176 m := customTestModuleFactoryBase()
177 android.InitAndroidModule(m)
178 return m
179}
180
181type customDefaultsModule struct {
182 android.ModuleBase
183 android.DefaultsModuleBase
184}
185
186func customDefaultsModuleFactoryBase() android.DefaultsModule {
187 module := &customDefaultsModule{}
188 module.AddProperties(&customProps{})
189 return module
190}
191
192func customDefaultsModuleFactoryBasic() android.Module {
193 return customDefaultsModuleFactoryBase()
194}
195
196func customDefaultsModuleFactory() android.Module {
197 m := customDefaultsModuleFactoryBase()
198 android.InitDefaultsModule(m)
199 return m
200}
Jingwen Chen73850672020-12-14 08:25:34 -0500201
202type customBazelModuleAttributes struct {
Jingwen Chen73850672020-12-14 08:25:34 -0500203 String_prop string
204 String_list_prop []string
Liz Kammer4562a3b2021-04-21 18:15:34 -0400205 Arch_paths bazel.LabelListAttribute
Jingwen Chen73850672020-12-14 08:25:34 -0500206}
207
208type customBazelModule struct {
209 android.BazelTargetModuleBase
210 customBazelModuleAttributes
211}
212
Jingwen Chen73850672020-12-14 08:25:34 -0500213func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
214 if m, ok := ctx.Module().(*customModule); ok {
Jingwen Chen12b4c272021-03-10 02:05:59 -0500215 if !m.ConvertWithBp2build(ctx) {
Jingwen Chen77e8b7b2021-02-05 03:03:24 -0500216 return
217 }
218
Liz Kammer32b77cf2021-08-04 15:17:02 -0400219 paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.props.Arch_paths, m.props.Arch_paths_exclude))
Liz Kammer4562a3b2021-04-21 18:15:34 -0400220
Liz Kammer9abd62d2021-05-21 08:37:59 -0400221 for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
222 for config, props := range configToProps {
223 if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
Liz Kammer32b77cf2021-08-04 15:17:02 -0400224 paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude))
Liz Kammer9abd62d2021-05-21 08:37:59 -0400225 }
Liz Kammer4562a3b2021-04-21 18:15:34 -0400226 }
227 }
228
Liz Kammer32b77cf2021-08-04 15:17:02 -0400229 paths.ResolveExcludes()
230
Jingwen Chen1fd14692021-02-05 03:01:50 -0500231 attrs := &customBazelModuleAttributes{
Jingwen Chen73850672020-12-14 08:25:34 -0500232 String_prop: m.props.String_prop,
233 String_list_prop: m.props.String_list_prop,
Liz Kammer4562a3b2021-04-21 18:15:34 -0400234 Arch_paths: paths,
Jingwen Chen1fd14692021-02-05 03:01:50 -0500235 }
236
Liz Kammerfc46bc12021-02-19 11:06:17 -0500237 props := bazel.BazelTargetModuleProperties{
238 Rule_class: "custom",
239 }
Jingwen Chen1fd14692021-02-05 03:01:50 -0500240
Liz Kammer2ada09a2021-08-11 00:17:36 -0400241 ctx.CreateBazelTargetModule(m.Name(), props, attrs)
Jingwen Chen73850672020-12-14 08:25:34 -0500242 }
243}
Jingwen Chen40067de2021-01-26 21:58:43 -0500244
245// A bp2build mutator that uses load statements and creates a 1:M mapping from
246// module to target.
247func customBp2BuildMutatorFromStarlark(ctx android.TopDownMutatorContext) {
248 if m, ok := ctx.Module().(*customModule); ok {
Jingwen Chen12b4c272021-03-10 02:05:59 -0500249 if !m.ConvertWithBp2build(ctx) {
Jingwen Chen77e8b7b2021-02-05 03:03:24 -0500250 return
251 }
252
Jingwen Chen1fd14692021-02-05 03:01:50 -0500253 baseName := m.Name()
254 attrs := &customBazelModuleAttributes{}
255
Liz Kammerfc46bc12021-02-19 11:06:17 -0500256 myLibraryProps := bazel.BazelTargetModuleProperties{
257 Rule_class: "my_library",
258 Bzl_load_location: "//build/bazel/rules:rules.bzl",
259 }
Liz Kammer2ada09a2021-08-11 00:17:36 -0400260 ctx.CreateBazelTargetModule(baseName, myLibraryProps, attrs)
Jingwen Chen1fd14692021-02-05 03:01:50 -0500261
Liz Kammerfc46bc12021-02-19 11:06:17 -0500262 protoLibraryProps := bazel.BazelTargetModuleProperties{
263 Rule_class: "proto_library",
264 Bzl_load_location: "//build/bazel/rules:proto.bzl",
265 }
Liz Kammer2ada09a2021-08-11 00:17:36 -0400266 ctx.CreateBazelTargetModule(baseName+"_proto_library_deps", protoLibraryProps, attrs)
Jingwen Chen1fd14692021-02-05 03:01:50 -0500267
Liz Kammerfc46bc12021-02-19 11:06:17 -0500268 myProtoLibraryProps := bazel.BazelTargetModuleProperties{
269 Rule_class: "my_proto_library",
270 Bzl_load_location: "//build/bazel/rules:proto.bzl",
271 }
Liz Kammer2ada09a2021-08-11 00:17:36 -0400272 ctx.CreateBazelTargetModule(baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
Jingwen Chen40067de2021-01-26 21:58:43 -0500273 }
274}
Jingwen Chenba369ad2021-02-22 10:19:34 -0500275
276// Helper method for tests to easily access the targets in a dir.
Liz Kammerba3ea162021-02-17 13:22:03 -0500277func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
Rupert Shuttleworth2a4fc3e2021-04-21 07:10:09 -0400278 // TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
Jingwen Chenc63677b2021-06-17 05:43:19 +0000279 buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500280 return buildFileToTargets[dir]
281}
Liz Kammer32b77cf2021-08-04 15:17:02 -0400282
283func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
284 ctx.RegisterModuleType("custom", customModuleFactory)
285 ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator)
286 ctx.RegisterForBazelConversion()
287}