blob: ad6a27be4c01e85ceb2aaef5c3cdc0e694a0a2f6 [file] [log] [blame]
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +00001package bp2build
2
3import (
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxdc212c02021-08-23 20:21:19 +00004 "fmt"
Cole Faustb09da7e2022-05-18 10:57:33 -07005 "strings"
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +00006 "testing"
7
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxdc212c02021-08-23 20:21:19 +00008 "android/soong/android"
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +00009 "android/soong/python"
10)
11
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxdc212c02021-08-23 20:21:19 +000012// TODO(alexmarquez): Should be lifted into a generic Bp2Build file
13type PythonLibBp2Build func(ctx android.TopDownMutatorContext)
14
Sam Delmerico75539d62022-01-31 14:37:29 +000015type pythonLibBp2BuildTestCase struct {
Chris Parsonscd209032023-09-19 01:12:48 +000016 description string
17 filesystem map[string]string
18 blueprint string
19 expectedBazelTargets []testBazelTarget
20 dir string
21 expectedError error
22 stubbedBuildDefinitions []string
Sam Delmerico75539d62022-01-31 14:37:29 +000023}
24
Sam Delmerico3177a6e2022-06-21 19:28:33 +000025func convertPythonLibTestCaseToBp2build_Host(tc pythonLibBp2BuildTestCase) Bp2buildTestCase {
Sam Delmerico75539d62022-01-31 14:37:29 +000026 for i := range tc.expectedBazelTargets {
27 tc.expectedBazelTargets[i].attrs["target_compatible_with"] = `select({
Jingwen Chen9c2e3ee2023-10-11 10:51:28 +000028 "//build/bazel_common_rules/platforms/os:android": ["@platforms//:incompatible"],
Sam Delmerico75539d62022-01-31 14:37:29 +000029 "//conditions:default": [],
30 })`
31 }
32
33 return convertPythonLibTestCaseToBp2build(tc)
34}
35
Sam Delmerico3177a6e2022-06-21 19:28:33 +000036func convertPythonLibTestCaseToBp2build(tc pythonLibBp2BuildTestCase) Bp2buildTestCase {
Sam Delmerico75539d62022-01-31 14:37:29 +000037 var bp2BuildTargets []string
38 for _, t := range tc.expectedBazelTargets {
Alixe06d75b2022-08-31 18:28:19 +000039 bp2BuildTargets = append(bp2BuildTargets, MakeBazelTarget(t.typ, t.name, t.attrs))
Sam Delmerico75539d62022-01-31 14:37:29 +000040 }
Cole Faustb09da7e2022-05-18 10:57:33 -070041 // Copy the filesystem so that we can change stuff in it later without it
42 // affecting the original pythonLibBp2BuildTestCase
43 filesystemCopy := make(map[string]string)
44 for k, v := range tc.filesystem {
45 filesystemCopy[k] = v
46 }
Sam Delmerico3177a6e2022-06-21 19:28:33 +000047 return Bp2buildTestCase{
Chris Parsonscd209032023-09-19 01:12:48 +000048 Description: tc.description,
49 Filesystem: filesystemCopy,
50 Blueprint: tc.blueprint,
51 ExpectedBazelTargets: bp2BuildTargets,
52 Dir: tc.dir,
53 ExpectedErr: tc.expectedError,
54 StubbedBuildDefinitions: tc.stubbedBuildDefinitions,
Sam Delmerico75539d62022-01-31 14:37:29 +000055 }
56}
57
58func runPythonLibraryTestCase(t *testing.T, tc pythonLibBp2BuildTestCase) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxdc212c02021-08-23 20:21:19 +000059 t.Helper()
Sam Delmerico75539d62022-01-31 14:37:29 +000060 testCase := convertPythonLibTestCaseToBp2build(tc)
Sam Delmerico3177a6e2022-06-21 19:28:33 +000061 testCase.Description = fmt.Sprintf(testCase.Description, "python_library")
62 testCase.Blueprint = fmt.Sprintf(testCase.Blueprint, "python_library")
63 for name, contents := range testCase.Filesystem {
Cole Faustb09da7e2022-05-18 10:57:33 -070064 if strings.HasSuffix(name, "Android.bp") {
Sam Delmerico3177a6e2022-06-21 19:28:33 +000065 testCase.Filesystem[name] = fmt.Sprintf(contents, "python_library")
Cole Faustb09da7e2022-05-18 10:57:33 -070066 }
67 }
Sam Delmerico3177a6e2022-06-21 19:28:33 +000068 testCase.ModuleTypeUnderTest = "python_library"
69 testCase.ModuleTypeUnderTestFactory = python.PythonLibraryFactory
Sam Delmerico75539d62022-01-31 14:37:29 +000070
Trevor Radcliffe1b4b2d92022-09-01 18:57:01 +000071 RunBp2BuildTestCaseSimple(t, testCase)
Liz Kammer78cfdaa2021-11-08 12:56:31 -050072}
73
Sam Delmerico75539d62022-01-31 14:37:29 +000074func runPythonLibraryHostTestCase(t *testing.T, tc pythonLibBp2BuildTestCase) {
Liz Kammer78cfdaa2021-11-08 12:56:31 -050075 t.Helper()
Sam Delmerico75539d62022-01-31 14:37:29 +000076 testCase := convertPythonLibTestCaseToBp2build_Host(tc)
Sam Delmerico3177a6e2022-06-21 19:28:33 +000077 testCase.Description = fmt.Sprintf(testCase.Description, "python_library_host")
78 testCase.Blueprint = fmt.Sprintf(testCase.Blueprint, "python_library_host")
79 for name, contents := range testCase.Filesystem {
Cole Faustb09da7e2022-05-18 10:57:33 -070080 if strings.HasSuffix(name, "Android.bp") {
Sam Delmerico3177a6e2022-06-21 19:28:33 +000081 testCase.Filesystem[name] = fmt.Sprintf(contents, "python_library_host")
Cole Faustb09da7e2022-05-18 10:57:33 -070082 }
83 }
Sam Delmerico3177a6e2022-06-21 19:28:33 +000084 testCase.ModuleTypeUnderTest = "python_library_host"
85 testCase.ModuleTypeUnderTestFactory = python.PythonLibraryHostFactory
86 RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
Liz Kammer78cfdaa2021-11-08 12:56:31 -050087 ctx.RegisterModuleType("python_library", python.PythonLibraryFactory)
88 },
89 testCase)
90}
91
Sam Delmerico75539d62022-01-31 14:37:29 +000092func runPythonLibraryTestCases(t *testing.T, tc pythonLibBp2BuildTestCase) {
Liz Kammer78cfdaa2021-11-08 12:56:31 -050093 t.Helper()
94 runPythonLibraryTestCase(t, tc)
95 runPythonLibraryHostTestCase(t, tc)
96}
97
98func TestSimplePythonLib(t *testing.T) {
Sam Delmerico75539d62022-01-31 14:37:29 +000099 testCases := []pythonLibBp2BuildTestCase{
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500100 {
101 description: "simple %s converts to a native py_library",
102 filesystem: map[string]string{
103 "a.py": "",
104 "b/c.py": "",
105 "b/d.py": "",
106 "b/e.py": "",
107 "files/data.txt": "",
108 },
Chris Parsonscd209032023-09-19 01:12:48 +0000109 stubbedBuildDefinitions: []string{"bar"},
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500110 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000111 name: "foo",
112 srcs: ["**/*.py"],
113 exclude_srcs: ["b/e.py"],
114 data: ["files/data.txt",],
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux560cb662021-08-26 20:13:29 +0000115 libs: ["bar"],
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000116 bazel_module: { bp2build_available: true },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux560cb662021-08-26 20:13:29 +0000117}
118 python_library {
119 name: "bar",
120 srcs: ["b/e.py"],
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500121 }`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000122 expectedBazelTargets: []testBazelTarget{
123 {
124 typ: "py_library",
125 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000126 attrs: AttrNameToString{
Sam Delmerico75539d62022-01-31 14:37:29 +0000127 "data": `["files/data.txt"]`,
128 "deps": `[":bar"]`,
129 "srcs": `[
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000130 "a.py",
131 "b/c.py",
132 "b/d.py",
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500133 ]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000134 "srcs_version": `"PY3"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700135 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000136 },
137 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500138 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000139 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500140 {
141 description: "py2 %s converts to a native py_library",
142 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000143 name: "foo",
144 srcs: ["a.py"],
145 version: {
146 py2: {
147 enabled: true,
148 },
149 py3: {
150 enabled: false,
151 },
152 },
153
154 bazel_module: { bp2build_available: true },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500155}`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000156 expectedBazelTargets: []testBazelTarget{
157 {
158 typ: "py_library",
159 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000160 attrs: AttrNameToString{
Sam Delmerico75539d62022-01-31 14:37:29 +0000161 "srcs": `["a.py"]`,
162 "srcs_version": `"PY2"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700163 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000164 },
165 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500166 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000167 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500168 {
169 description: "py3 %s converts to a native py_library",
170 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000171 name: "foo",
172 srcs: ["a.py"],
173 version: {
174 py2: {
175 enabled: false,
176 },
177 py3: {
178 enabled: true,
179 },
180 },
181
182 bazel_module: { bp2build_available: true },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500183}`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000184 expectedBazelTargets: []testBazelTarget{
185 {
186 typ: "py_library",
187 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000188 attrs: AttrNameToString{
Sam Delmerico75539d62022-01-31 14:37:29 +0000189 "srcs": `["a.py"]`,
190 "srcs_version": `"PY3"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700191 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000192 },
193 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500194 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000195 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500196 {
197 description: "py2&3 %s converts to a native py_library",
198 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000199 name: "foo",
200 srcs: ["a.py"],
201 version: {
202 py2: {
203 enabled: true,
204 },
205 py3: {
206 enabled: true,
207 },
208 },
209
210 bazel_module: { bp2build_available: true },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500211}`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000212 expectedBazelTargets: []testBazelTarget{
213 {
214 // srcs_version is PY2ANDPY3 by default.
215 typ: "py_library",
216 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000217 attrs: AttrNameToString{
Cole Faustb09da7e2022-05-18 10:57:33 -0700218 "srcs": `["a.py"]`,
219 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000220 },
221 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500222 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000223 },
Cole Faustb09da7e2022-05-18 10:57:33 -0700224 {
225 description: "%s: pkg_path in a subdirectory of the same name converts correctly",
226 dir: "mylib/subpackage",
227 filesystem: map[string]string{
228 "mylib/subpackage/a.py": "",
229 "mylib/subpackage/Android.bp": `%s {
230 name: "foo",
231 srcs: ["a.py"],
232 pkg_path: "mylib/subpackage",
233
234 bazel_module: { bp2build_available: true },
235 }`,
236 },
237 blueprint: `%s {name: "bar"}`,
238 expectedBazelTargets: []testBazelTarget{
239 {
240 // srcs_version is PY2ANDPY3 by default.
241 typ: "py_library",
242 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000243 attrs: AttrNameToString{
Cole Faustb09da7e2022-05-18 10:57:33 -0700244 "srcs": `["a.py"]`,
245 "imports": `["../.."]`,
246 "srcs_version": `"PY3"`,
247 },
248 },
249 },
250 },
251 {
252 description: "%s: pkg_path in a subdirectory of a different name fails",
253 dir: "mylib/subpackage",
254 filesystem: map[string]string{
255 "mylib/subpackage/a.py": "",
256 "mylib/subpackage/Android.bp": `%s {
257 name: "foo",
258 srcs: ["a.py"],
259 pkg_path: "mylib/subpackage2",
260 bazel_module: { bp2build_available: true },
261 }`,
262 },
263 blueprint: `%s {name: "bar"}`,
264 expectedError: fmt.Errorf("Currently, bp2build only supports pkg_paths that are the same as the folders the Android.bp file is in."),
265 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500266 }
267
268 for _, tc := range testCases {
269 t.Run(tc.description, func(t *testing.T) {
270 runPythonLibraryTestCases(t, tc)
271 })
272 }
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000273}
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000274
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500275func TestPythonArchVariance(t *testing.T) {
Sam Delmerico75539d62022-01-31 14:37:29 +0000276 runPythonLibraryTestCases(t, pythonLibBp2BuildTestCase{
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500277 description: "test %s arch variants",
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000278 filesystem: map[string]string{
279 "dir/arm.py": "",
280 "dir/x86.py": "",
281 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500282 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000283 name: "foo",
284 arch: {
285 arm: {
286 srcs: ["arm.py"],
287 },
288 x86: {
289 srcs: ["x86.py"],
290 },
291 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500292 }`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000293 expectedBazelTargets: []testBazelTarget{
294 {
295 typ: "py_library",
296 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000297 attrs: AttrNameToString{
Sam Delmerico75539d62022-01-31 14:37:29 +0000298 "srcs": `select({
Jingwen Chen9c2e3ee2023-10-11 10:51:28 +0000299 "//build/bazel_common_rules/platforms/arch:arm": ["arm.py"],
300 "//build/bazel_common_rules/platforms/arch:x86": ["x86.py"],
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000301 "//conditions:default": [],
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500302 })`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000303 "srcs_version": `"PY3"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700304 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000305 },
306 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000307 },
308 })
309}
Cole Faust53b62092022-05-12 15:37:02 -0700310
311func TestPythonLibraryWithProtobufs(t *testing.T) {
312 runPythonLibraryTestCases(t, pythonLibBp2BuildTestCase{
313 description: "test %s protobuf",
314 filesystem: map[string]string{
315 "dir/mylib.py": "",
316 "dir/myproto.proto": "",
317 },
318 blueprint: `%s {
319 name: "foo",
320 srcs: [
321 "dir/mylib.py",
322 "dir/myproto.proto",
323 ],
324 }`,
325 expectedBazelTargets: []testBazelTarget{
326 {
327 typ: "proto_library",
328 name: "foo_proto",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000329 attrs: AttrNameToString{
Cole Faust53b62092022-05-12 15:37:02 -0700330 "srcs": `["dir/myproto.proto"]`,
331 },
332 },
333 {
334 typ: "py_proto_library",
335 name: "foo_py_proto",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000336 attrs: AttrNameToString{
Cole Faust53b62092022-05-12 15:37:02 -0700337 "deps": `[":foo_proto"]`,
338 },
339 },
340 {
341 typ: "py_library",
342 name: "foo",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000343 attrs: AttrNameToString{
Cole Faust53b62092022-05-12 15:37:02 -0700344 "srcs": `["dir/mylib.py"]`,
345 "srcs_version": `"PY3"`,
346 "imports": `["."]`,
347 "deps": `[":foo_py_proto"]`,
348 },
349 },
350 },
351 })
352}
Spandan Dascb847632023-08-22 19:24:07 +0000353
354func TestPythonLibraryWithProtobufsAndPkgPath(t *testing.T) {
355 t.Parallel()
356 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{
357 Description: "test python_library protobuf with pkg_path",
358 Filesystem: map[string]string{
359 "dir/foo.proto": "",
360 "dir/bar.proto": "", // bar contains "import dir/foo.proto"
361 "dir/Android.bp": `
362python_library {
363 name: "foo",
364 pkg_path: "dir",
365 srcs: [
366 "foo.proto",
367 "bar.proto",
368 ],
369 bazel_module: {bp2build_available: true},
370}`,
371 },
372 Dir: "dir",
373 ExpectedBazelTargets: []string{
374 MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
375 "import_prefix": `"dir"`,
376 "strip_import_prefix": `""`,
377 "srcs": `[
378 "foo.proto",
379 "bar.proto",
380 ]`,
381 }),
382 MakeBazelTarget("py_proto_library", "foo_py_proto", AttrNameToString{
383 "deps": `[":foo_proto"]`,
384 }),
385 MakeBazelTarget("py_library", "foo", AttrNameToString{
386 "srcs_version": `"PY3"`,
387 "imports": `[".."]`,
388 "deps": `[":foo_py_proto"]`,
389 }),
390 },
391 })
392}