blob: f51f1068baa3937f439609e443a61283c66edb56 [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 {
16 description string
17 filesystem map[string]string
18 blueprint string
19 expectedBazelTargets []testBazelTarget
Cole Faustb09da7e2022-05-18 10:57:33 -070020 dir string
21 expectedError error
Sam Delmerico75539d62022-01-31 14:37:29 +000022}
23
24func convertPythonLibTestCaseToBp2build_Host(tc pythonLibBp2BuildTestCase) bp2buildTestCase {
25 for i := range tc.expectedBazelTargets {
26 tc.expectedBazelTargets[i].attrs["target_compatible_with"] = `select({
27 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
28 "//conditions:default": [],
29 })`
30 }
31
32 return convertPythonLibTestCaseToBp2build(tc)
33}
34
35func convertPythonLibTestCaseToBp2build(tc pythonLibBp2BuildTestCase) bp2buildTestCase {
36 var bp2BuildTargets []string
37 for _, t := range tc.expectedBazelTargets {
38 bp2BuildTargets = append(bp2BuildTargets, makeBazelTarget(t.typ, t.name, t.attrs))
39 }
Cole Faustb09da7e2022-05-18 10:57:33 -070040 // Copy the filesystem so that we can change stuff in it later without it
41 // affecting the original pythonLibBp2BuildTestCase
42 filesystemCopy := make(map[string]string)
43 for k, v := range tc.filesystem {
44 filesystemCopy[k] = v
45 }
Sam Delmerico75539d62022-01-31 14:37:29 +000046 return bp2buildTestCase{
47 description: tc.description,
Cole Faustb09da7e2022-05-18 10:57:33 -070048 filesystem: filesystemCopy,
Sam Delmerico75539d62022-01-31 14:37:29 +000049 blueprint: tc.blueprint,
50 expectedBazelTargets: bp2BuildTargets,
Cole Faustb09da7e2022-05-18 10:57:33 -070051 dir: tc.dir,
52 expectedErr: tc.expectedError,
Sam Delmerico75539d62022-01-31 14:37:29 +000053 }
54}
55
56func runPythonLibraryTestCase(t *testing.T, tc pythonLibBp2BuildTestCase) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxdc212c02021-08-23 20:21:19 +000057 t.Helper()
Sam Delmerico75539d62022-01-31 14:37:29 +000058 testCase := convertPythonLibTestCaseToBp2build(tc)
Liz Kammer78cfdaa2021-11-08 12:56:31 -050059 testCase.description = fmt.Sprintf(testCase.description, "python_library")
60 testCase.blueprint = fmt.Sprintf(testCase.blueprint, "python_library")
Cole Faustb09da7e2022-05-18 10:57:33 -070061 for name, contents := range testCase.filesystem {
62 if strings.HasSuffix(name, "Android.bp") {
63 testCase.filesystem[name] = fmt.Sprintf(contents, "python_library")
64 }
65 }
Liz Kammer78cfdaa2021-11-08 12:56:31 -050066 testCase.moduleTypeUnderTest = "python_library"
67 testCase.moduleTypeUnderTestFactory = python.PythonLibraryFactory
Sam Delmerico75539d62022-01-31 14:37:29 +000068
Liz Kammer78cfdaa2021-11-08 12:56:31 -050069 runBp2BuildTestCaseSimple(t, testCase)
70}
71
Sam Delmerico75539d62022-01-31 14:37:29 +000072func runPythonLibraryHostTestCase(t *testing.T, tc pythonLibBp2BuildTestCase) {
Liz Kammer78cfdaa2021-11-08 12:56:31 -050073 t.Helper()
Sam Delmerico75539d62022-01-31 14:37:29 +000074 testCase := convertPythonLibTestCaseToBp2build_Host(tc)
Liz Kammer78cfdaa2021-11-08 12:56:31 -050075 testCase.description = fmt.Sprintf(testCase.description, "python_library_host")
76 testCase.blueprint = fmt.Sprintf(testCase.blueprint, "python_library_host")
Cole Faustb09da7e2022-05-18 10:57:33 -070077 for name, contents := range testCase.filesystem {
78 if strings.HasSuffix(name, "Android.bp") {
79 testCase.filesystem[name] = fmt.Sprintf(contents, "python_library_host")
80 }
81 }
Liz Kammer78cfdaa2021-11-08 12:56:31 -050082 testCase.moduleTypeUnderTest = "python_library_host"
83 testCase.moduleTypeUnderTestFactory = python.PythonLibraryHostFactory
Liz Kammer78cfdaa2021-11-08 12:56:31 -050084 runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
85 ctx.RegisterModuleType("python_library", python.PythonLibraryFactory)
86 },
87 testCase)
88}
89
Sam Delmerico75539d62022-01-31 14:37:29 +000090func runPythonLibraryTestCases(t *testing.T, tc pythonLibBp2BuildTestCase) {
Liz Kammer78cfdaa2021-11-08 12:56:31 -050091 t.Helper()
92 runPythonLibraryTestCase(t, tc)
93 runPythonLibraryHostTestCase(t, tc)
94}
95
96func TestSimplePythonLib(t *testing.T) {
Sam Delmerico75539d62022-01-31 14:37:29 +000097 testCases := []pythonLibBp2BuildTestCase{
Liz Kammer78cfdaa2021-11-08 12:56:31 -050098 {
99 description: "simple %s converts to a native py_library",
100 filesystem: map[string]string{
101 "a.py": "",
102 "b/c.py": "",
103 "b/d.py": "",
104 "b/e.py": "",
105 "files/data.txt": "",
106 },
107 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000108 name: "foo",
109 srcs: ["**/*.py"],
110 exclude_srcs: ["b/e.py"],
111 data: ["files/data.txt",],
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux560cb662021-08-26 20:13:29 +0000112 libs: ["bar"],
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000113 bazel_module: { bp2build_available: true },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux560cb662021-08-26 20:13:29 +0000114}
115 python_library {
116 name: "bar",
117 srcs: ["b/e.py"],
118 bazel_module: { bp2build_available: false },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500119 }`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000120 expectedBazelTargets: []testBazelTarget{
121 {
122 typ: "py_library",
123 name: "foo",
124 attrs: attrNameToString{
125 "data": `["files/data.txt"]`,
126 "deps": `[":bar"]`,
127 "srcs": `[
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000128 "a.py",
129 "b/c.py",
130 "b/d.py",
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500131 ]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000132 "srcs_version": `"PY3"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700133 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000134 },
135 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500136 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000137 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500138 {
139 description: "py2 %s converts to a native py_library",
140 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000141 name: "foo",
142 srcs: ["a.py"],
143 version: {
144 py2: {
145 enabled: true,
146 },
147 py3: {
148 enabled: false,
149 },
150 },
151
152 bazel_module: { bp2build_available: true },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500153}`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000154 expectedBazelTargets: []testBazelTarget{
155 {
156 typ: "py_library",
157 name: "foo",
158 attrs: attrNameToString{
159 "srcs": `["a.py"]`,
160 "srcs_version": `"PY2"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700161 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000162 },
163 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500164 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000165 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500166 {
167 description: "py3 %s converts to a native py_library",
168 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000169 name: "foo",
170 srcs: ["a.py"],
171 version: {
172 py2: {
173 enabled: false,
174 },
175 py3: {
176 enabled: true,
177 },
178 },
179
180 bazel_module: { bp2build_available: true },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500181}`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000182 expectedBazelTargets: []testBazelTarget{
183 {
184 typ: "py_library",
185 name: "foo",
186 attrs: attrNameToString{
187 "srcs": `["a.py"]`,
188 "srcs_version": `"PY3"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700189 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000190 },
191 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500192 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000193 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500194 {
195 description: "py2&3 %s converts to a native py_library",
196 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000197 name: "foo",
198 srcs: ["a.py"],
199 version: {
200 py2: {
201 enabled: true,
202 },
203 py3: {
204 enabled: true,
205 },
206 },
207
208 bazel_module: { bp2build_available: true },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500209}`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000210 expectedBazelTargets: []testBazelTarget{
211 {
212 // srcs_version is PY2ANDPY3 by default.
213 typ: "py_library",
214 name: "foo",
215 attrs: attrNameToString{
Cole Faustb09da7e2022-05-18 10:57:33 -0700216 "srcs": `["a.py"]`,
217 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000218 },
219 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500220 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000221 },
Cole Faustb09da7e2022-05-18 10:57:33 -0700222 {
223 description: "%s: pkg_path in a subdirectory of the same name converts correctly",
224 dir: "mylib/subpackage",
225 filesystem: map[string]string{
226 "mylib/subpackage/a.py": "",
227 "mylib/subpackage/Android.bp": `%s {
228 name: "foo",
229 srcs: ["a.py"],
230 pkg_path: "mylib/subpackage",
231
232 bazel_module: { bp2build_available: true },
233 }`,
234 },
235 blueprint: `%s {name: "bar"}`,
236 expectedBazelTargets: []testBazelTarget{
237 {
238 // srcs_version is PY2ANDPY3 by default.
239 typ: "py_library",
240 name: "foo",
241 attrs: attrNameToString{
242 "srcs": `["a.py"]`,
243 "imports": `["../.."]`,
244 "srcs_version": `"PY3"`,
245 },
246 },
247 },
248 },
249 {
250 description: "%s: pkg_path in a subdirectory of a different name fails",
251 dir: "mylib/subpackage",
252 filesystem: map[string]string{
253 "mylib/subpackage/a.py": "",
254 "mylib/subpackage/Android.bp": `%s {
255 name: "foo",
256 srcs: ["a.py"],
257 pkg_path: "mylib/subpackage2",
258 bazel_module: { bp2build_available: true },
259 }`,
260 },
261 blueprint: `%s {name: "bar"}`,
262 expectedError: fmt.Errorf("Currently, bp2build only supports pkg_paths that are the same as the folders the Android.bp file is in."),
263 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500264 }
265
266 for _, tc := range testCases {
267 t.Run(tc.description, func(t *testing.T) {
268 runPythonLibraryTestCases(t, tc)
269 })
270 }
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0fc781c2021-08-19 19:21:30 +0000271}
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000272
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500273func TestPythonArchVariance(t *testing.T) {
Sam Delmerico75539d62022-01-31 14:37:29 +0000274 runPythonLibraryTestCases(t, pythonLibBp2BuildTestCase{
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500275 description: "test %s arch variants",
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000276 filesystem: map[string]string{
277 "dir/arm.py": "",
278 "dir/x86.py": "",
279 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500280 blueprint: `%s {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000281 name: "foo",
282 arch: {
283 arm: {
284 srcs: ["arm.py"],
285 },
286 x86: {
287 srcs: ["x86.py"],
288 },
289 },
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500290 }`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000291 expectedBazelTargets: []testBazelTarget{
292 {
293 typ: "py_library",
294 name: "foo",
295 attrs: attrNameToString{
296 "srcs": `select({
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000297 "//build/bazel/platforms/arch:arm": ["arm.py"],
298 "//build/bazel/platforms/arch:x86": ["x86.py"],
299 "//conditions:default": [],
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500300 })`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000301 "srcs_version": `"PY3"`,
Cole Faustb09da7e2022-05-18 10:57:33 -0700302 "imports": `["."]`,
Sam Delmerico75539d62022-01-31 14:37:29 +0000303 },
304 },
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux19d399d2021-09-17 20:30:21 +0000305 },
306 })
307}
Cole Faust53b62092022-05-12 15:37:02 -0700308
309func TestPythonLibraryWithProtobufs(t *testing.T) {
310 runPythonLibraryTestCases(t, pythonLibBp2BuildTestCase{
311 description: "test %s protobuf",
312 filesystem: map[string]string{
313 "dir/mylib.py": "",
314 "dir/myproto.proto": "",
315 },
316 blueprint: `%s {
317 name: "foo",
318 srcs: [
319 "dir/mylib.py",
320 "dir/myproto.proto",
321 ],
322 }`,
323 expectedBazelTargets: []testBazelTarget{
324 {
325 typ: "proto_library",
326 name: "foo_proto",
327 attrs: attrNameToString{
328 "srcs": `["dir/myproto.proto"]`,
329 },
330 },
331 {
332 typ: "py_proto_library",
333 name: "foo_py_proto",
334 attrs: attrNameToString{
335 "deps": `[":foo_proto"]`,
336 },
337 },
338 {
339 typ: "py_library",
340 name: "foo",
341 attrs: attrNameToString{
342 "srcs": `["dir/mylib.py"]`,
343 "srcs_version": `"PY3"`,
344 "imports": `["."]`,
345 "deps": `[":foo_py_proto"]`,
346 },
347 },
348 },
349 })
350}