1package bp2build 2 3import ( 4 "testing" 5 6 "android/soong/android" 7 "android/soong/genrule" 8 "android/soong/python" 9) 10 11func runBp2BuildTestCaseWithPythonLibraries(t *testing.T, tc Bp2buildTestCase) { 12 t.Helper() 13 RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) { 14 ctx.RegisterModuleType("python_library", python.PythonLibraryFactory) 15 ctx.RegisterModuleType("python_library_host", python.PythonLibraryHostFactory) 16 ctx.RegisterModuleType("genrule", genrule.GenRuleFactory) 17 ctx.RegisterModuleType("python_defaults", python.DefaultsFactory) 18 }, tc) 19} 20 21func TestPythonBinaryHostSimple(t *testing.T) { 22 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ 23 Description: "simple python_binary_host converts to a native py_binary", 24 ModuleTypeUnderTest: "python_binary_host", 25 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 26 Filesystem: map[string]string{ 27 "a.py": "", 28 "b/c.py": "", 29 "b/d.py": "", 30 "b/e.py": "", 31 "files/data.txt": "", 32 }, 33 Blueprint: `python_binary_host { 34 name: "foo", 35 main: "a.py", 36 srcs: ["**/*.py"], 37 exclude_srcs: ["b/e.py"], 38 data: ["files/data.txt",], 39 libs: ["bar"], 40 bazel_module: { bp2build_available: true }, 41} 42 python_library_host { 43 name: "bar", 44 srcs: ["b/e.py"], 45 bazel_module: { bp2build_available: false }, 46 }`, 47 ExpectedBazelTargets: []string{ 48 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 49 "data": `["files/data.txt"]`, 50 "deps": `[":bar"]`, 51 "main": `"a.py"`, 52 "imports": `["."]`, 53 "srcs": `[ 54 "a.py", 55 "b/c.py", 56 "b/d.py", 57 ]`, 58 "target_compatible_with": `select({ 59 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 60 "//conditions:default": [], 61 })`, 62 }), 63 }, 64 }) 65} 66 67func TestPythonBinaryHostPy2(t *testing.T) { 68 RunBp2BuildTestCaseSimple(t, Bp2buildTestCase{ 69 Description: "py2 python_binary_host", 70 ModuleTypeUnderTest: "python_binary_host", 71 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 72 Blueprint: `python_binary_host { 73 name: "foo", 74 srcs: ["a.py"], 75 version: { 76 py2: { 77 enabled: true, 78 }, 79 py3: { 80 enabled: false, 81 }, 82 }, 83 84 bazel_module: { bp2build_available: true }, 85} 86`, 87 ExpectedBazelTargets: []string{ 88 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 89 "python_version": `"PY2"`, 90 "imports": `["."]`, 91 "srcs": `["a.py"]`, 92 "target_compatible_with": `select({ 93 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 94 "//conditions:default": [], 95 })`, 96 }), 97 }, 98 }) 99} 100 101func TestPythonBinaryHostPy3(t *testing.T) { 102 RunBp2BuildTestCaseSimple(t, Bp2buildTestCase{ 103 Description: "py3 python_binary_host", 104 ModuleTypeUnderTest: "python_binary_host", 105 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 106 Blueprint: `python_binary_host { 107 name: "foo", 108 srcs: ["a.py"], 109 version: { 110 py2: { 111 enabled: false, 112 }, 113 py3: { 114 enabled: true, 115 }, 116 }, 117 118 bazel_module: { bp2build_available: true }, 119} 120`, 121 ExpectedBazelTargets: []string{ 122 // python_version is PY3 by default. 123 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 124 "imports": `["."]`, 125 "srcs": `["a.py"]`, 126 "target_compatible_with": `select({ 127 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 128 "//conditions:default": [], 129 })`, 130 }), 131 }, 132 }) 133} 134 135func TestPythonBinaryHostArchVariance(t *testing.T) { 136 RunBp2BuildTestCaseSimple(t, Bp2buildTestCase{ 137 Description: "test arch variants", 138 ModuleTypeUnderTest: "python_binary_host", 139 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 140 Filesystem: map[string]string{ 141 "dir/arm.py": "", 142 "dir/x86.py": "", 143 }, 144 Blueprint: `python_binary_host { 145 name: "foo-arm", 146 arch: { 147 arm: { 148 srcs: ["arm.py"], 149 }, 150 x86: { 151 srcs: ["x86.py"], 152 }, 153 }, 154 }`, 155 ExpectedBazelTargets: []string{ 156 MakeBazelTarget("py_binary", "foo-arm", AttrNameToString{ 157 "imports": `["."]`, 158 "srcs": `select({ 159 "//build/bazel/platforms/arch:arm": ["arm.py"], 160 "//build/bazel/platforms/arch:x86": ["x86.py"], 161 "//conditions:default": [], 162 })`, 163 "target_compatible_with": `select({ 164 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 165 "//conditions:default": [], 166 })`, 167 }), 168 }, 169 }) 170} 171 172func TestPythonBinaryMainIsNotSpecified(t *testing.T) { 173 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ 174 Description: "python_binary_host main label in same package", 175 ModuleTypeUnderTest: "python_binary_host", 176 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 177 Blueprint: `python_binary_host { 178 name: "foo", 179 bazel_module: { bp2build_available: true }, 180} 181`, 182 ExpectedBazelTargets: []string{ 183 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 184 "imports": `["."]`, 185 "target_compatible_with": `select({ 186 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 187 "//conditions:default": [], 188 })`, 189 }), 190 }, 191 }) 192} 193 194func TestPythonBinaryMainIsLabel(t *testing.T) { 195 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ 196 Description: "python_binary_host main label in same package", 197 ModuleTypeUnderTest: "python_binary_host", 198 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 199 Blueprint: `python_binary_host { 200 name: "foo", 201 main: ":a", 202 bazel_module: { bp2build_available: true }, 203} 204 205genrule { 206 name: "a", 207 bazel_module: { bp2build_available: false }, 208} 209`, 210 ExpectedBazelTargets: []string{ 211 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 212 "main": `":a"`, 213 "imports": `["."]`, 214 "target_compatible_with": `select({ 215 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 216 "//conditions:default": [], 217 })`, 218 }), 219 }, 220 }) 221} 222 223func TestPythonBinaryMainIsSubpackageFile(t *testing.T) { 224 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ 225 Description: "python_binary_host main is subpackage file", 226 ModuleTypeUnderTest: "python_binary_host", 227 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 228 Filesystem: map[string]string{ 229 "a/Android.bp": "", 230 "a/b.py": "", 231 }, 232 Blueprint: `python_binary_host { 233 name: "foo", 234 main: "a/b.py", 235 bazel_module: { bp2build_available: true }, 236} 237 238`, 239 ExpectedBazelTargets: []string{ 240 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 241 "main": `"//a:b.py"`, 242 "imports": `["."]`, 243 "target_compatible_with": `select({ 244 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 245 "//conditions:default": [], 246 })`, 247 }), 248 }, 249 }) 250} 251 252func TestPythonBinaryMainIsSubDirFile(t *testing.T) { 253 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ 254 Description: "python_binary_host main is file in sub directory that is not Bazel package", 255 ModuleTypeUnderTest: "python_binary_host", 256 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 257 Filesystem: map[string]string{ 258 "a/b.py": "", 259 }, 260 Blueprint: `python_binary_host { 261 name: "foo", 262 main: "a/b.py", 263 bazel_module: { bp2build_available: true }, 264} 265 266`, 267 ExpectedBazelTargets: []string{ 268 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 269 "main": `"a/b.py"`, 270 "imports": `["."]`, 271 "target_compatible_with": `select({ 272 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 273 "//conditions:default": [], 274 })`, 275 }), 276 }, 277 }) 278} 279 280func TestPythonBinaryDuplicatesInRequired(t *testing.T) { 281 runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ 282 Description: "python_binary_host duplicates in required attribute of the module and its defaults", 283 ModuleTypeUnderTest: "python_binary_host", 284 ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory, 285 Blueprint: `python_binary_host { 286 name: "foo", 287 main: "a.py", 288 defaults: ["d"], 289 required: [ 290 "r1", 291 ], 292 bazel_module: { bp2build_available: true }, 293} 294 295python_defaults { 296 name: "d", 297 required: [ 298 "r1", 299 "r2", 300 ], 301}` + simpleModuleDoNotConvertBp2build("genrule", "r1") + 302 simpleModuleDoNotConvertBp2build("genrule", "r2"), 303 304 ExpectedBazelTargets: []string{ 305 MakeBazelTarget("py_binary", "foo", AttrNameToString{ 306 "main": `"a.py"`, 307 "imports": `["."]`, 308 "data": `[ 309 ":r1", 310 ":r2", 311 ]`, 312 "target_compatible_with": `select({ 313 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], 314 "//conditions:default": [], 315 })`, 316 }), 317 }, 318 }) 319} 320