build_conversion_test.go 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802
  1. // Copyright 2020 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package bp2build
  15. import (
  16. "fmt"
  17. "strings"
  18. "testing"
  19. "android/soong/android"
  20. "android/soong/android/allowlists"
  21. "android/soong/python"
  22. )
  23. func TestGenerateSoongModuleTargets(t *testing.T) {
  24. testCases := []struct {
  25. description string
  26. bp string
  27. expectedBazelTarget string
  28. }{
  29. {
  30. description: "only name",
  31. bp: `custom { name: "foo" }
  32. `,
  33. expectedBazelTarget: `soong_module(
  34. name = "foo",
  35. soong_module_name = "foo",
  36. soong_module_type = "custom",
  37. soong_module_variant = "",
  38. soong_module_deps = [
  39. ],
  40. bool_prop = False,
  41. string_prop = "",
  42. )`,
  43. },
  44. {
  45. description: "handles bool",
  46. bp: `custom {
  47. name: "foo",
  48. bool_prop: true,
  49. }
  50. `,
  51. expectedBazelTarget: `soong_module(
  52. name = "foo",
  53. soong_module_name = "foo",
  54. soong_module_type = "custom",
  55. soong_module_variant = "",
  56. soong_module_deps = [
  57. ],
  58. bool_prop = True,
  59. string_prop = "",
  60. )`,
  61. },
  62. {
  63. description: "string escaping",
  64. bp: `custom {
  65. name: "foo",
  66. owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
  67. }
  68. `,
  69. expectedBazelTarget: `soong_module(
  70. name = "foo",
  71. soong_module_name = "foo",
  72. soong_module_type = "custom",
  73. soong_module_variant = "",
  74. soong_module_deps = [
  75. ],
  76. bool_prop = False,
  77. owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
  78. string_prop = "",
  79. )`,
  80. },
  81. {
  82. description: "single item string list",
  83. bp: `custom {
  84. name: "foo",
  85. required: ["bar"],
  86. }
  87. `,
  88. expectedBazelTarget: `soong_module(
  89. name = "foo",
  90. soong_module_name = "foo",
  91. soong_module_type = "custom",
  92. soong_module_variant = "",
  93. soong_module_deps = [
  94. ],
  95. bool_prop = False,
  96. required = ["bar"],
  97. string_prop = "",
  98. )`,
  99. },
  100. {
  101. description: "list of strings",
  102. bp: `custom {
  103. name: "foo",
  104. target_required: ["qux", "bazqux"],
  105. }
  106. `,
  107. expectedBazelTarget: `soong_module(
  108. name = "foo",
  109. soong_module_name = "foo",
  110. soong_module_type = "custom",
  111. soong_module_variant = "",
  112. soong_module_deps = [
  113. ],
  114. bool_prop = False,
  115. string_prop = "",
  116. target_required = [
  117. "qux",
  118. "bazqux",
  119. ],
  120. )`,
  121. },
  122. {
  123. description: "dist/dists",
  124. bp: `custom {
  125. name: "foo",
  126. dist: {
  127. targets: ["goal_foo"],
  128. tag: ".foo",
  129. },
  130. dists: [{
  131. targets: ["goal_bar"],
  132. tag: ".bar",
  133. }],
  134. }
  135. `,
  136. expectedBazelTarget: `soong_module(
  137. name = "foo",
  138. soong_module_name = "foo",
  139. soong_module_type = "custom",
  140. soong_module_variant = "",
  141. soong_module_deps = [
  142. ],
  143. bool_prop = False,
  144. dist = {
  145. "tag": ".foo",
  146. "targets": ["goal_foo"],
  147. },
  148. dists = [{
  149. "tag": ".bar",
  150. "targets": ["goal_bar"],
  151. }],
  152. string_prop = "",
  153. )`,
  154. },
  155. {
  156. description: "put it together",
  157. bp: `custom {
  158. name: "foo",
  159. required: ["bar"],
  160. target_required: ["qux", "bazqux"],
  161. bool_prop: true,
  162. owner: "custom_owner",
  163. dists: [
  164. {
  165. tag: ".tag",
  166. targets: ["my_goal"],
  167. },
  168. ],
  169. }
  170. `,
  171. expectedBazelTarget: `soong_module(
  172. name = "foo",
  173. soong_module_name = "foo",
  174. soong_module_type = "custom",
  175. soong_module_variant = "",
  176. soong_module_deps = [
  177. ],
  178. bool_prop = True,
  179. dists = [{
  180. "tag": ".tag",
  181. "targets": ["my_goal"],
  182. }],
  183. owner = "custom_owner",
  184. required = ["bar"],
  185. string_prop = "",
  186. target_required = [
  187. "qux",
  188. "bazqux",
  189. ],
  190. )`,
  191. },
  192. }
  193. dir := "."
  194. for _, testCase := range testCases {
  195. t.Run(testCase.description, func(t *testing.T) {
  196. config := android.TestConfig(buildDir, nil, testCase.bp, nil)
  197. ctx := android.NewTestContext(config)
  198. ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
  199. ctx.Register()
  200. _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
  201. android.FailIfErrored(t, errs)
  202. _, errs = ctx.PrepareBuildActions(config)
  203. android.FailIfErrored(t, errs)
  204. codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
  205. bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
  206. android.FailIfErrored(t, err)
  207. if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
  208. t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
  209. }
  210. actualBazelTarget := bazelTargets[0]
  211. if actualBazelTarget.content != testCase.expectedBazelTarget {
  212. t.Errorf(
  213. "Expected generated Bazel target to be '%s', got '%s'",
  214. testCase.expectedBazelTarget,
  215. actualBazelTarget.content,
  216. )
  217. }
  218. })
  219. }
  220. }
  221. func TestGenerateBazelTargetModules(t *testing.T) {
  222. testCases := []Bp2buildTestCase{
  223. {
  224. Description: "string prop empty",
  225. Blueprint: `custom {
  226. name: "foo",
  227. string_literal_prop: "",
  228. bazel_module: { bp2build_available: true },
  229. }`,
  230. ExpectedBazelTargets: []string{
  231. MakeBazelTarget("custom", "foo", AttrNameToString{
  232. "string_literal_prop": `""`,
  233. }),
  234. },
  235. },
  236. {
  237. Description: `string prop "PROP"`,
  238. Blueprint: `custom {
  239. name: "foo",
  240. string_literal_prop: "PROP",
  241. bazel_module: { bp2build_available: true },
  242. }`,
  243. ExpectedBazelTargets: []string{
  244. MakeBazelTarget("custom", "foo", AttrNameToString{
  245. "string_literal_prop": `"PROP"`,
  246. }),
  247. },
  248. },
  249. {
  250. Description: `string prop arch variant`,
  251. Blueprint: `custom {
  252. name: "foo",
  253. arch: {
  254. arm: { string_literal_prop: "ARM" },
  255. arm64: { string_literal_prop: "ARM64" },
  256. },
  257. bazel_module: { bp2build_available: true },
  258. }`,
  259. ExpectedBazelTargets: []string{
  260. MakeBazelTarget("custom", "foo", AttrNameToString{
  261. "string_literal_prop": `select({
  262. "//build/bazel/platforms/arch:arm": "ARM",
  263. "//build/bazel/platforms/arch:arm64": "ARM64",
  264. "//conditions:default": None,
  265. })`,
  266. }),
  267. },
  268. },
  269. {
  270. Description: "string ptr props",
  271. Blueprint: `custom {
  272. name: "foo",
  273. string_ptr_prop: "",
  274. bazel_module: { bp2build_available: true },
  275. }`,
  276. ExpectedBazelTargets: []string{
  277. MakeBazelTarget("custom", "foo", AttrNameToString{
  278. "string_ptr_prop": `""`,
  279. }),
  280. },
  281. },
  282. {
  283. Description: "string list props",
  284. Blueprint: `custom {
  285. name: "foo",
  286. string_list_prop: ["a", "b"],
  287. string_ptr_prop: "a",
  288. bazel_module: { bp2build_available: true },
  289. }`,
  290. ExpectedBazelTargets: []string{
  291. MakeBazelTarget("custom", "foo", AttrNameToString{
  292. "string_list_prop": `[
  293. "a",
  294. "b",
  295. ]`,
  296. "string_ptr_prop": `"a"`,
  297. }),
  298. },
  299. },
  300. {
  301. Description: "control characters",
  302. Blueprint: `custom {
  303. name: "foo",
  304. string_list_prop: ["\t", "\n"],
  305. string_ptr_prop: "a\t\n\r",
  306. bazel_module: { bp2build_available: true },
  307. }`,
  308. ExpectedBazelTargets: []string{
  309. MakeBazelTarget("custom", "foo", AttrNameToString{
  310. "string_list_prop": `[
  311. "\t",
  312. "\n",
  313. ]`,
  314. "string_ptr_prop": `"a\t\n\r"`,
  315. }),
  316. },
  317. },
  318. {
  319. Description: "handles dep",
  320. Blueprint: `custom {
  321. name: "has_dep",
  322. arch_paths: [":dep"],
  323. bazel_module: { bp2build_available: true },
  324. }
  325. custom {
  326. name: "dep",
  327. arch_paths: ["abc"],
  328. bazel_module: { bp2build_available: true },
  329. }`,
  330. ExpectedBazelTargets: []string{
  331. MakeBazelTarget("custom", "dep", AttrNameToString{
  332. "arch_paths": `["abc"]`,
  333. }),
  334. MakeBazelTarget("custom", "has_dep", AttrNameToString{
  335. "arch_paths": `[":dep"]`,
  336. }),
  337. },
  338. },
  339. {
  340. Description: "non-existent dep",
  341. Blueprint: `custom {
  342. name: "has_dep",
  343. arch_paths: [":dep"],
  344. bazel_module: { bp2build_available: true },
  345. }`,
  346. ExpectedBazelTargets: []string{
  347. MakeBazelTarget("custom", "has_dep", AttrNameToString{
  348. "arch_paths": `[":dep__BP2BUILD__MISSING__DEP"]`,
  349. }),
  350. },
  351. },
  352. {
  353. Description: "arch-variant srcs",
  354. Blueprint: `custom {
  355. name: "arch_paths",
  356. arch: {
  357. x86: { arch_paths: ["x86.txt"] },
  358. x86_64: { arch_paths: ["x86_64.txt"] },
  359. arm: { arch_paths: ["arm.txt"] },
  360. arm64: { arch_paths: ["arm64.txt"] },
  361. },
  362. target: {
  363. linux: { arch_paths: ["linux.txt"] },
  364. bionic: { arch_paths: ["bionic.txt"] },
  365. host: { arch_paths: ["host.txt"] },
  366. not_windows: { arch_paths: ["not_windows.txt"] },
  367. android: { arch_paths: ["android.txt"] },
  368. linux_musl: { arch_paths: ["linux_musl.txt"] },
  369. musl: { arch_paths: ["musl.txt"] },
  370. linux_glibc: { arch_paths: ["linux_glibc.txt"] },
  371. glibc: { arch_paths: ["glibc.txt"] },
  372. linux_bionic: { arch_paths: ["linux_bionic.txt"] },
  373. darwin: { arch_paths: ["darwin.txt"] },
  374. windows: { arch_paths: ["windows.txt"] },
  375. },
  376. multilib: {
  377. lib32: { arch_paths: ["lib32.txt"] },
  378. lib64: { arch_paths: ["lib64.txt"] },
  379. },
  380. bazel_module: { bp2build_available: true },
  381. }`,
  382. ExpectedBazelTargets: []string{
  383. MakeBazelTarget("custom", "arch_paths", AttrNameToString{
  384. "arch_paths": `select({
  385. "//build/bazel/platforms/arch:arm": [
  386. "arm.txt",
  387. "lib32.txt",
  388. ],
  389. "//build/bazel/platforms/arch:arm64": [
  390. "arm64.txt",
  391. "lib64.txt",
  392. ],
  393. "//build/bazel/platforms/arch:x86": [
  394. "x86.txt",
  395. "lib32.txt",
  396. ],
  397. "//build/bazel/platforms/arch:x86_64": [
  398. "x86_64.txt",
  399. "lib64.txt",
  400. ],
  401. "//conditions:default": [],
  402. }) + select({
  403. "//build/bazel/platforms/os:android": [
  404. "linux.txt",
  405. "bionic.txt",
  406. "android.txt",
  407. ],
  408. "//build/bazel/platforms/os:darwin": [
  409. "host.txt",
  410. "darwin.txt",
  411. "not_windows.txt",
  412. ],
  413. "//build/bazel/platforms/os:linux": [
  414. "host.txt",
  415. "linux.txt",
  416. "glibc.txt",
  417. "linux_glibc.txt",
  418. "not_windows.txt",
  419. ],
  420. "//build/bazel/platforms/os:linux_bionic": [
  421. "host.txt",
  422. "linux.txt",
  423. "bionic.txt",
  424. "linux_bionic.txt",
  425. "not_windows.txt",
  426. ],
  427. "//build/bazel/platforms/os:linux_musl": [
  428. "host.txt",
  429. "linux.txt",
  430. "musl.txt",
  431. "linux_musl.txt",
  432. "not_windows.txt",
  433. ],
  434. "//build/bazel/platforms/os:windows": [
  435. "host.txt",
  436. "windows.txt",
  437. ],
  438. "//conditions:default": [],
  439. })`,
  440. }),
  441. },
  442. },
  443. {
  444. Description: "arch-variant deps",
  445. Blueprint: `custom {
  446. name: "has_dep",
  447. arch: {
  448. x86: {
  449. arch_paths: [":dep"],
  450. },
  451. },
  452. bazel_module: { bp2build_available: true },
  453. }
  454. custom {
  455. name: "dep",
  456. arch_paths: ["abc"],
  457. bazel_module: { bp2build_available: true },
  458. }`,
  459. ExpectedBazelTargets: []string{
  460. MakeBazelTarget("custom", "dep", AttrNameToString{
  461. "arch_paths": `["abc"]`,
  462. }),
  463. MakeBazelTarget("custom", "has_dep", AttrNameToString{
  464. "arch_paths": `select({
  465. "//build/bazel/platforms/arch:x86": [":dep"],
  466. "//conditions:default": [],
  467. })`,
  468. }),
  469. },
  470. },
  471. {
  472. Description: "embedded props",
  473. Blueprint: `custom {
  474. name: "embedded_props",
  475. embedded_prop: "abc",
  476. bazel_module: { bp2build_available: true },
  477. }`,
  478. ExpectedBazelTargets: []string{
  479. MakeBazelTarget("custom", "embedded_props", AttrNameToString{
  480. "embedded_attr": `"abc"`,
  481. }),
  482. },
  483. },
  484. {
  485. Description: "ptr to embedded props",
  486. Blueprint: `custom {
  487. name: "ptr_to_embedded_props",
  488. other_embedded_prop: "abc",
  489. bazel_module: { bp2build_available: true },
  490. }`,
  491. ExpectedBazelTargets: []string{
  492. MakeBazelTarget("custom", "ptr_to_embedded_props", AttrNameToString{
  493. "other_embedded_attr": `"abc"`,
  494. }),
  495. },
  496. },
  497. }
  498. dir := "."
  499. for _, testCase := range testCases {
  500. t.Run(testCase.Description, func(t *testing.T) {
  501. config := android.TestConfig(buildDir, nil, testCase.Blueprint, nil)
  502. ctx := android.NewTestContext(config)
  503. registerCustomModuleForBp2buildConversion(ctx)
  504. _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
  505. if errored(t, testCase, errs) {
  506. return
  507. }
  508. _, errs = ctx.ResolveDependencies(config)
  509. if errored(t, testCase, errs) {
  510. return
  511. }
  512. codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
  513. bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
  514. android.FailIfErrored(t, err)
  515. if actualCount, expectedCount := len(bazelTargets), len(testCase.ExpectedBazelTargets); actualCount != expectedCount {
  516. t.Errorf("Expected %d bazel target (%s),\ngot %d (%s)", expectedCount, testCase.ExpectedBazelTargets, actualCount, bazelTargets)
  517. } else {
  518. for i, expectedBazelTarget := range testCase.ExpectedBazelTargets {
  519. actualBazelTarget := bazelTargets[i]
  520. if actualBazelTarget.content != expectedBazelTarget {
  521. t.Errorf(
  522. "Expected generated Bazel target to be '%s', got '%s'",
  523. expectedBazelTarget,
  524. actualBazelTarget.content,
  525. )
  526. }
  527. }
  528. }
  529. })
  530. }
  531. }
  532. func TestBp2buildHostAndDevice(t *testing.T) {
  533. testCases := []Bp2buildTestCase{
  534. {
  535. Description: "host and device, device only",
  536. ModuleTypeUnderTest: "custom",
  537. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  538. Blueprint: `custom {
  539. name: "foo",
  540. bazel_module: { bp2build_available: true },
  541. }`,
  542. ExpectedBazelTargets: []string{
  543. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.DeviceSupported),
  544. },
  545. },
  546. {
  547. Description: "host and device, both",
  548. ModuleTypeUnderTest: "custom",
  549. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  550. Blueprint: `custom {
  551. name: "foo",
  552. host_supported: true,
  553. bazel_module: { bp2build_available: true },
  554. }`,
  555. ExpectedBazelTargets: []string{
  556. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{}),
  557. },
  558. },
  559. {
  560. Description: "host and device, host explicitly disabled",
  561. ModuleTypeUnderTest: "custom",
  562. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  563. Blueprint: `custom {
  564. name: "foo",
  565. host_supported: false,
  566. bazel_module: { bp2build_available: true },
  567. }`,
  568. ExpectedBazelTargets: []string{
  569. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.DeviceSupported),
  570. },
  571. },
  572. {
  573. Description: "host and device, neither",
  574. ModuleTypeUnderTest: "custom",
  575. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  576. Blueprint: `custom {
  577. name: "foo",
  578. host_supported: false,
  579. device_supported: false,
  580. bazel_module: { bp2build_available: true },
  581. }`,
  582. ExpectedBazelTargets: []string{
  583. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{
  584. "target_compatible_with": `["@platforms//:incompatible"]`,
  585. }),
  586. },
  587. },
  588. {
  589. Description: "host and device, neither, cannot override with product_var",
  590. ModuleTypeUnderTest: "custom",
  591. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  592. Blueprint: `custom {
  593. name: "foo",
  594. host_supported: false,
  595. device_supported: false,
  596. product_variables: { unbundled_build: { enabled: true } },
  597. bazel_module: { bp2build_available: true },
  598. }`,
  599. ExpectedBazelTargets: []string{
  600. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{
  601. "target_compatible_with": `["@platforms//:incompatible"]`,
  602. }),
  603. },
  604. },
  605. {
  606. Description: "host and device, both, disabled overrided with product_var",
  607. ModuleTypeUnderTest: "custom",
  608. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  609. Blueprint: `custom {
  610. name: "foo",
  611. host_supported: true,
  612. device_supported: true,
  613. enabled: false,
  614. product_variables: { unbundled_build: { enabled: true } },
  615. bazel_module: { bp2build_available: true },
  616. }`,
  617. ExpectedBazelTargets: []string{
  618. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{
  619. "target_compatible_with": `["//build/bazel/product_variables:unbundled_build"]`,
  620. }),
  621. },
  622. },
  623. {
  624. Description: "host and device, neither, cannot override with arch enabled",
  625. ModuleTypeUnderTest: "custom",
  626. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  627. Blueprint: `custom {
  628. name: "foo",
  629. host_supported: false,
  630. device_supported: false,
  631. arch: { x86: { enabled: true } },
  632. bazel_module: { bp2build_available: true },
  633. }`,
  634. ExpectedBazelTargets: []string{
  635. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{
  636. "target_compatible_with": `["@platforms//:incompatible"]`,
  637. }),
  638. },
  639. },
  640. {
  641. Description: "host and device, host only",
  642. ModuleTypeUnderTest: "custom",
  643. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  644. Blueprint: `custom {
  645. name: "foo",
  646. host_supported: true,
  647. device_supported: false,
  648. bazel_module: { bp2build_available: true },
  649. }`,
  650. ExpectedBazelTargets: []string{
  651. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.HostSupported),
  652. },
  653. },
  654. {
  655. Description: "host only",
  656. ModuleTypeUnderTest: "custom",
  657. ModuleTypeUnderTestFactory: customModuleFactoryHostSupported,
  658. Blueprint: `custom {
  659. name: "foo",
  660. bazel_module: { bp2build_available: true },
  661. }`,
  662. ExpectedBazelTargets: []string{
  663. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.HostSupported),
  664. },
  665. },
  666. {
  667. Description: "device only",
  668. ModuleTypeUnderTest: "custom",
  669. ModuleTypeUnderTestFactory: customModuleFactoryDeviceSupported,
  670. Blueprint: `custom {
  671. name: "foo",
  672. bazel_module: { bp2build_available: true },
  673. }`,
  674. ExpectedBazelTargets: []string{
  675. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.DeviceSupported),
  676. },
  677. },
  678. {
  679. Description: "host and device default, default",
  680. ModuleTypeUnderTest: "custom",
  681. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault,
  682. Blueprint: `custom {
  683. name: "foo",
  684. bazel_module: { bp2build_available: true },
  685. }`,
  686. ExpectedBazelTargets: []string{
  687. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{}),
  688. },
  689. },
  690. {
  691. Description: "host and device default, device only",
  692. ModuleTypeUnderTest: "custom",
  693. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault,
  694. Blueprint: `custom {
  695. name: "foo",
  696. host_supported: false,
  697. bazel_module: { bp2build_available: true },
  698. }`,
  699. ExpectedBazelTargets: []string{
  700. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.DeviceSupported),
  701. },
  702. },
  703. {
  704. Description: "host and device default, host only",
  705. ModuleTypeUnderTest: "custom",
  706. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault,
  707. Blueprint: `custom {
  708. name: "foo",
  709. device_supported: false,
  710. bazel_module: { bp2build_available: true },
  711. }`,
  712. ExpectedBazelTargets: []string{
  713. makeBazelTargetHostOrDevice("custom", "foo", AttrNameToString{}, android.HostSupported),
  714. },
  715. },
  716. {
  717. Description: "host and device default, neither",
  718. ModuleTypeUnderTest: "custom",
  719. ModuleTypeUnderTestFactory: customModuleFactoryHostAndDeviceDefault,
  720. Blueprint: `custom {
  721. name: "foo",
  722. host_supported: false,
  723. device_supported: false,
  724. bazel_module: { bp2build_available: true },
  725. }`,
  726. ExpectedBazelTargets: []string{
  727. MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{
  728. "target_compatible_with": `["@platforms//:incompatible"]`,
  729. }),
  730. },
  731. },
  732. }
  733. for _, tc := range testCases {
  734. t.Run(tc.Description, func(t *testing.T) {
  735. RunBp2BuildTestCaseSimple(t, tc)
  736. })
  737. }
  738. }
  739. func TestLoadStatements(t *testing.T) {
  740. testCases := []struct {
  741. bazelTargets BazelTargets
  742. expectedLoadStatements string
  743. }{
  744. {
  745. bazelTargets: BazelTargets{
  746. BazelTarget{
  747. name: "foo",
  748. ruleClass: "cc_library",
  749. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  750. },
  751. },
  752. expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
  753. },
  754. {
  755. bazelTargets: BazelTargets{
  756. BazelTarget{
  757. name: "foo",
  758. ruleClass: "cc_library",
  759. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  760. },
  761. BazelTarget{
  762. name: "bar",
  763. ruleClass: "cc_library",
  764. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  765. },
  766. },
  767. expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
  768. },
  769. {
  770. bazelTargets: BazelTargets{
  771. BazelTarget{
  772. name: "foo",
  773. ruleClass: "cc_library",
  774. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  775. },
  776. BazelTarget{
  777. name: "bar",
  778. ruleClass: "cc_binary",
  779. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  780. },
  781. },
  782. expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")`,
  783. },
  784. {
  785. bazelTargets: BazelTargets{
  786. BazelTarget{
  787. name: "foo",
  788. ruleClass: "cc_library",
  789. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  790. },
  791. BazelTarget{
  792. name: "bar",
  793. ruleClass: "cc_binary",
  794. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  795. },
  796. BazelTarget{
  797. name: "baz",
  798. ruleClass: "java_binary",
  799. bzlLoadLocation: "//build/bazel/rules:java.bzl",
  800. },
  801. },
  802. expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")
  803. load("//build/bazel/rules:java.bzl", "java_binary")`,
  804. },
  805. {
  806. bazelTargets: BazelTargets{
  807. BazelTarget{
  808. name: "foo",
  809. ruleClass: "cc_binary",
  810. bzlLoadLocation: "//build/bazel/rules:cc.bzl",
  811. },
  812. BazelTarget{
  813. name: "bar",
  814. ruleClass: "java_binary",
  815. bzlLoadLocation: "//build/bazel/rules:java.bzl",
  816. },
  817. BazelTarget{
  818. name: "baz",
  819. ruleClass: "genrule",
  820. // Note: no bzlLoadLocation for native rules
  821. },
  822. },
  823. expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary")
  824. load("//build/bazel/rules:java.bzl", "java_binary")`,
  825. },
  826. }
  827. for _, testCase := range testCases {
  828. actual := testCase.bazelTargets.LoadStatements()
  829. expected := testCase.expectedLoadStatements
  830. if actual != expected {
  831. t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
  832. }
  833. }
  834. }
  835. func TestGenerateBazelTargetModules_OneToMany_LoadedFromStarlark(t *testing.T) {
  836. testCases := []struct {
  837. bp string
  838. expectedBazelTarget string
  839. expectedBazelTargetCount int
  840. expectedLoadStatements string
  841. }{
  842. {
  843. bp: `custom {
  844. name: "bar",
  845. host_supported: true,
  846. one_to_many_prop: true,
  847. bazel_module: { bp2build_available: true },
  848. }`,
  849. expectedBazelTarget: `my_library(
  850. name = "bar",
  851. )
  852. proto_library(
  853. name = "bar_proto_library_deps",
  854. )
  855. my_proto_library(
  856. name = "bar_my_proto_library_deps",
  857. )`,
  858. expectedBazelTargetCount: 3,
  859. expectedLoadStatements: `load("//build/bazel/rules:proto.bzl", "my_proto_library", "proto_library")
  860. load("//build/bazel/rules:rules.bzl", "my_library")`,
  861. },
  862. }
  863. dir := "."
  864. for _, testCase := range testCases {
  865. config := android.TestConfig(buildDir, nil, testCase.bp, nil)
  866. ctx := android.NewTestContext(config)
  867. ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
  868. ctx.RegisterForBazelConversion()
  869. _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
  870. android.FailIfErrored(t, errs)
  871. _, errs = ctx.ResolveDependencies(config)
  872. android.FailIfErrored(t, errs)
  873. codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
  874. bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
  875. android.FailIfErrored(t, err)
  876. if actualCount := len(bazelTargets); actualCount != testCase.expectedBazelTargetCount {
  877. t.Fatalf("Expected %d bazel target, got %d", testCase.expectedBazelTargetCount, actualCount)
  878. }
  879. actualBazelTargets := bazelTargets.String()
  880. if actualBazelTargets != testCase.expectedBazelTarget {
  881. t.Errorf(
  882. "Expected generated Bazel target to be '%s', got '%s'",
  883. testCase.expectedBazelTarget,
  884. actualBazelTargets,
  885. )
  886. }
  887. actualLoadStatements := bazelTargets.LoadStatements()
  888. if actualLoadStatements != testCase.expectedLoadStatements {
  889. t.Errorf(
  890. "Expected generated load statements to be '%s', got '%s'",
  891. testCase.expectedLoadStatements,
  892. actualLoadStatements,
  893. )
  894. }
  895. }
  896. }
  897. func TestModuleTypeBp2Build(t *testing.T) {
  898. testCases := []Bp2buildTestCase{
  899. {
  900. Description: "filegroup with does not specify srcs",
  901. ModuleTypeUnderTest: "filegroup",
  902. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  903. Blueprint: `filegroup {
  904. name: "fg_foo",
  905. bazel_module: { bp2build_available: true },
  906. }`,
  907. ExpectedBazelTargets: []string{
  908. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{}),
  909. },
  910. },
  911. {
  912. Description: "filegroup with no srcs",
  913. ModuleTypeUnderTest: "filegroup",
  914. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  915. Blueprint: `filegroup {
  916. name: "fg_foo",
  917. srcs: [],
  918. bazel_module: { bp2build_available: true },
  919. }`,
  920. ExpectedBazelTargets: []string{
  921. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{}),
  922. },
  923. },
  924. {
  925. Description: "filegroup with srcs",
  926. ModuleTypeUnderTest: "filegroup",
  927. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  928. Blueprint: `filegroup {
  929. name: "fg_foo",
  930. srcs: ["a", "b"],
  931. bazel_module: { bp2build_available: true },
  932. }`,
  933. ExpectedBazelTargets: []string{
  934. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  935. "srcs": `[
  936. "a",
  937. "b",
  938. ]`,
  939. }),
  940. },
  941. },
  942. {
  943. Description: "filegroup with dot-slash-prefixed srcs",
  944. ModuleTypeUnderTest: "filegroup",
  945. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  946. Blueprint: `filegroup {
  947. name: "fg_foo",
  948. srcs: ["./a", "./b"],
  949. bazel_module: { bp2build_available: true },
  950. }`,
  951. ExpectedBazelTargets: []string{
  952. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  953. "srcs": `[
  954. "a",
  955. "b",
  956. ]`,
  957. }),
  958. },
  959. },
  960. {
  961. Description: "filegroup with excludes srcs",
  962. ModuleTypeUnderTest: "filegroup",
  963. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  964. Blueprint: `filegroup {
  965. name: "fg_foo",
  966. srcs: ["a", "b"],
  967. exclude_srcs: ["a"],
  968. bazel_module: { bp2build_available: true },
  969. }`,
  970. ExpectedBazelTargets: []string{
  971. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  972. "srcs": `["b"]`,
  973. }),
  974. },
  975. },
  976. {
  977. Description: "depends_on_other_dir_module",
  978. ModuleTypeUnderTest: "filegroup",
  979. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  980. Blueprint: `filegroup {
  981. name: "fg_foo",
  982. srcs: [
  983. ":foo",
  984. "c",
  985. ],
  986. bazel_module: { bp2build_available: true },
  987. }`,
  988. Filesystem: map[string]string{
  989. "other/Android.bp": `filegroup {
  990. name: "foo",
  991. srcs: ["a", "b"],
  992. bazel_module: { bp2build_available: true },
  993. }`,
  994. },
  995. ExpectedBazelTargets: []string{
  996. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  997. "srcs": `[
  998. "//other:foo",
  999. "c",
  1000. ]`,
  1001. }),
  1002. },
  1003. },
  1004. {
  1005. Description: "depends_on_other_unconverted_module_error",
  1006. ModuleTypeUnderTest: "filegroup",
  1007. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1008. UnconvertedDepsMode: errorModulesUnconvertedDeps,
  1009. Blueprint: `filegroup {
  1010. name: "foobar",
  1011. srcs: [
  1012. ":foo",
  1013. "c",
  1014. ],
  1015. bazel_module: { bp2build_available: true },
  1016. }`,
  1017. ExpectedErr: fmt.Errorf(`filegroup .:foobar depends on unconverted modules: foo`),
  1018. Filesystem: map[string]string{
  1019. "other/Android.bp": `filegroup {
  1020. name: "foo",
  1021. srcs: ["a", "b"],
  1022. }`,
  1023. },
  1024. },
  1025. }
  1026. for _, testCase := range testCases {
  1027. t.Run(testCase.Description, func(t *testing.T) {
  1028. RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, testCase)
  1029. })
  1030. }
  1031. }
  1032. type bp2buildMutator = func(android.TopDownMutatorContext)
  1033. func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) {
  1034. testCases := []struct {
  1035. moduleTypeUnderTest string
  1036. moduleTypeUnderTestFactory android.ModuleFactory
  1037. bp string
  1038. expectedCount int
  1039. description string
  1040. }{
  1041. {
  1042. description: "explicitly unavailable",
  1043. moduleTypeUnderTest: "filegroup",
  1044. moduleTypeUnderTestFactory: android.FileGroupFactory,
  1045. bp: `filegroup {
  1046. name: "foo",
  1047. srcs: ["a", "b"],
  1048. bazel_module: { bp2build_available: false },
  1049. }`,
  1050. expectedCount: 0,
  1051. },
  1052. {
  1053. description: "implicitly unavailable",
  1054. moduleTypeUnderTest: "filegroup",
  1055. moduleTypeUnderTestFactory: android.FileGroupFactory,
  1056. bp: `filegroup {
  1057. name: "foo",
  1058. srcs: ["a", "b"],
  1059. }`,
  1060. expectedCount: 0,
  1061. },
  1062. {
  1063. description: "explicitly available",
  1064. moduleTypeUnderTest: "filegroup",
  1065. moduleTypeUnderTestFactory: android.FileGroupFactory,
  1066. bp: `filegroup {
  1067. name: "foo",
  1068. srcs: ["a", "b"],
  1069. bazel_module: { bp2build_available: true },
  1070. }`,
  1071. expectedCount: 1,
  1072. },
  1073. {
  1074. description: "generates more than 1 target if needed",
  1075. moduleTypeUnderTest: "custom",
  1076. moduleTypeUnderTestFactory: customModuleFactoryHostAndDevice,
  1077. bp: `custom {
  1078. name: "foo",
  1079. one_to_many_prop: true,
  1080. bazel_module: { bp2build_available: true },
  1081. }`,
  1082. expectedCount: 3,
  1083. },
  1084. }
  1085. dir := "."
  1086. for _, testCase := range testCases {
  1087. t.Run(testCase.description, func(t *testing.T) {
  1088. config := android.TestConfig(buildDir, nil, testCase.bp, nil)
  1089. ctx := android.NewTestContext(config)
  1090. ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
  1091. ctx.RegisterForBazelConversion()
  1092. _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
  1093. android.FailIfErrored(t, errs)
  1094. _, errs = ctx.ResolveDependencies(config)
  1095. android.FailIfErrored(t, errs)
  1096. codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
  1097. bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
  1098. android.FailIfErrored(t, err)
  1099. if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
  1100. t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
  1101. }
  1102. })
  1103. }
  1104. }
  1105. func TestAllowlistingBp2buildTargetsWithConfig(t *testing.T) {
  1106. testCases := []struct {
  1107. moduleTypeUnderTest string
  1108. moduleTypeUnderTestFactory android.ModuleFactory
  1109. expectedCount map[string]int
  1110. description string
  1111. bp2buildConfig allowlists.Bp2BuildConfig
  1112. checkDir string
  1113. fs map[string]string
  1114. }{
  1115. {
  1116. description: "test bp2build config package and subpackages config",
  1117. moduleTypeUnderTest: "filegroup",
  1118. moduleTypeUnderTestFactory: android.FileGroupFactory,
  1119. expectedCount: map[string]int{
  1120. "migrated": 1,
  1121. "migrated/but_not_really": 0,
  1122. "migrated/but_not_really/but_really": 1,
  1123. "not_migrated": 0,
  1124. "also_not_migrated": 0,
  1125. },
  1126. bp2buildConfig: allowlists.Bp2BuildConfig{
  1127. "migrated": allowlists.Bp2BuildDefaultTrueRecursively,
  1128. "migrated/but_not_really": allowlists.Bp2BuildDefaultFalse,
  1129. "not_migrated": allowlists.Bp2BuildDefaultFalse,
  1130. },
  1131. fs: map[string]string{
  1132. "migrated/Android.bp": `filegroup { name: "a" }`,
  1133. "migrated/but_not_really/Android.bp": `filegroup { name: "b" }`,
  1134. "migrated/but_not_really/but_really/Android.bp": `filegroup { name: "c" }`,
  1135. "not_migrated/Android.bp": `filegroup { name: "d" }`,
  1136. "also_not_migrated/Android.bp": `filegroup { name: "e" }`,
  1137. },
  1138. },
  1139. {
  1140. description: "test bp2build config opt-in and opt-out",
  1141. moduleTypeUnderTest: "filegroup",
  1142. moduleTypeUnderTestFactory: android.FileGroupFactory,
  1143. expectedCount: map[string]int{
  1144. "package-opt-in": 2,
  1145. "package-opt-in/subpackage": 0,
  1146. "package-opt-out": 1,
  1147. "package-opt-out/subpackage": 0,
  1148. },
  1149. bp2buildConfig: allowlists.Bp2BuildConfig{
  1150. "package-opt-in": allowlists.Bp2BuildDefaultFalse,
  1151. "package-opt-out": allowlists.Bp2BuildDefaultTrueRecursively,
  1152. },
  1153. fs: map[string]string{
  1154. "package-opt-in/Android.bp": `
  1155. filegroup { name: "opt-in-a" }
  1156. filegroup { name: "opt-in-b", bazel_module: { bp2build_available: true } }
  1157. filegroup { name: "opt-in-c", bazel_module: { bp2build_available: true } }
  1158. `,
  1159. "package-opt-in/subpackage/Android.bp": `
  1160. filegroup { name: "opt-in-d" } // parent package not configured to DefaultTrueRecursively
  1161. `,
  1162. "package-opt-out/Android.bp": `
  1163. filegroup { name: "opt-out-a" }
  1164. filegroup { name: "opt-out-b", bazel_module: { bp2build_available: false } }
  1165. filegroup { name: "opt-out-c", bazel_module: { bp2build_available: false } }
  1166. `,
  1167. "package-opt-out/subpackage/Android.bp": `
  1168. filegroup { name: "opt-out-g", bazel_module: { bp2build_available: false } }
  1169. filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } }
  1170. `,
  1171. },
  1172. },
  1173. }
  1174. dir := "."
  1175. for _, testCase := range testCases {
  1176. fs := make(map[string][]byte)
  1177. toParse := []string{
  1178. "Android.bp",
  1179. }
  1180. for f, content := range testCase.fs {
  1181. if strings.HasSuffix(f, "Android.bp") {
  1182. toParse = append(toParse, f)
  1183. }
  1184. fs[f] = []byte(content)
  1185. }
  1186. config := android.TestConfig(buildDir, nil, "", fs)
  1187. ctx := android.NewTestContext(config)
  1188. ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
  1189. allowlist := android.NewBp2BuildAllowlist().SetDefaultConfig(testCase.bp2buildConfig)
  1190. ctx.RegisterBp2BuildConfig(allowlist)
  1191. ctx.RegisterForBazelConversion()
  1192. _, errs := ctx.ParseFileList(dir, toParse)
  1193. android.FailIfErrored(t, errs)
  1194. _, errs = ctx.ResolveDependencies(config)
  1195. android.FailIfErrored(t, errs)
  1196. codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
  1197. // For each directory, test that the expected number of generated targets is correct.
  1198. for dir, expectedCount := range testCase.expectedCount {
  1199. bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
  1200. android.FailIfErrored(t, err)
  1201. if actualCount := len(bazelTargets); actualCount != expectedCount {
  1202. t.Fatalf(
  1203. "%s: Expected %d bazel target for %s package, got %d",
  1204. testCase.description,
  1205. expectedCount,
  1206. dir,
  1207. actualCount)
  1208. }
  1209. }
  1210. }
  1211. }
  1212. func TestCombineBuildFilesBp2buildTargets(t *testing.T) {
  1213. testCases := []Bp2buildTestCase{
  1214. {
  1215. Description: "filegroup bazel_module.label",
  1216. ModuleTypeUnderTest: "filegroup",
  1217. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1218. Blueprint: `filegroup {
  1219. name: "fg_foo",
  1220. bazel_module: { label: "//other:fg_foo" },
  1221. }`,
  1222. ExpectedBazelTargets: []string{},
  1223. Filesystem: map[string]string{
  1224. "other/BUILD.bazel": `// BUILD file`,
  1225. },
  1226. },
  1227. {
  1228. Description: "multiple bazel_module.label same BUILD",
  1229. ModuleTypeUnderTest: "filegroup",
  1230. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1231. Blueprint: `filegroup {
  1232. name: "fg_foo",
  1233. bazel_module: { label: "//other:fg_foo" },
  1234. }
  1235. filegroup {
  1236. name: "foo",
  1237. bazel_module: { label: "//other:foo" },
  1238. }`,
  1239. ExpectedBazelTargets: []string{},
  1240. Filesystem: map[string]string{
  1241. "other/BUILD.bazel": `// BUILD file`,
  1242. },
  1243. },
  1244. {
  1245. Description: "filegroup bazel_module.label and bp2build in subdir",
  1246. ModuleTypeUnderTest: "filegroup",
  1247. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1248. Dir: "other",
  1249. Blueprint: ``,
  1250. Filesystem: map[string]string{
  1251. "other/Android.bp": `filegroup {
  1252. name: "fg_foo",
  1253. bazel_module: {
  1254. bp2build_available: true,
  1255. },
  1256. }
  1257. filegroup {
  1258. name: "fg_bar",
  1259. bazel_module: {
  1260. label: "//other:fg_bar"
  1261. },
  1262. }`,
  1263. "other/BUILD.bazel": `// definition for fg_bar`,
  1264. },
  1265. ExpectedBazelTargets: []string{
  1266. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{}),
  1267. },
  1268. },
  1269. {
  1270. Description: "filegroup bazel_module.label and filegroup bp2build",
  1271. ModuleTypeUnderTest: "filegroup",
  1272. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1273. Filesystem: map[string]string{
  1274. "other/BUILD.bazel": `// BUILD file`,
  1275. },
  1276. Blueprint: `filegroup {
  1277. name: "fg_foo",
  1278. bazel_module: {
  1279. label: "//other:fg_foo",
  1280. },
  1281. }
  1282. filegroup {
  1283. name: "fg_bar",
  1284. bazel_module: {
  1285. bp2build_available: true,
  1286. },
  1287. }`,
  1288. ExpectedBazelTargets: []string{
  1289. MakeBazelTargetNoRestrictions("filegroup", "fg_bar", map[string]string{}),
  1290. },
  1291. },
  1292. }
  1293. dir := "."
  1294. for _, testCase := range testCases {
  1295. t.Run(testCase.Description, func(t *testing.T) {
  1296. fs := make(map[string][]byte)
  1297. toParse := []string{
  1298. "Android.bp",
  1299. }
  1300. for f, content := range testCase.Filesystem {
  1301. if strings.HasSuffix(f, "Android.bp") {
  1302. toParse = append(toParse, f)
  1303. }
  1304. fs[f] = []byte(content)
  1305. }
  1306. config := android.TestConfig(buildDir, nil, testCase.Blueprint, fs)
  1307. ctx := android.NewTestContext(config)
  1308. ctx.RegisterModuleType(testCase.ModuleTypeUnderTest, testCase.ModuleTypeUnderTestFactory)
  1309. ctx.RegisterForBazelConversion()
  1310. _, errs := ctx.ParseFileList(dir, toParse)
  1311. if errored(t, testCase, errs) {
  1312. return
  1313. }
  1314. _, errs = ctx.ResolveDependencies(config)
  1315. if errored(t, testCase, errs) {
  1316. return
  1317. }
  1318. checkDir := dir
  1319. if testCase.Dir != "" {
  1320. checkDir = testCase.Dir
  1321. }
  1322. codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
  1323. bazelTargets, err := generateBazelTargetsForDir(codegenCtx, checkDir)
  1324. android.FailIfErrored(t, err)
  1325. bazelTargets.sort()
  1326. actualCount := len(bazelTargets)
  1327. expectedCount := len(testCase.ExpectedBazelTargets)
  1328. if actualCount != expectedCount {
  1329. t.Errorf("Expected %d bazel target, got %d\n%s", expectedCount, actualCount, bazelTargets)
  1330. }
  1331. for i, target := range bazelTargets {
  1332. actualContent := target.content
  1333. expectedContent := testCase.ExpectedBazelTargets[i]
  1334. if expectedContent != actualContent {
  1335. t.Errorf(
  1336. "Expected generated Bazel target to be '%s', got '%s'",
  1337. expectedContent,
  1338. actualContent,
  1339. )
  1340. }
  1341. }
  1342. })
  1343. }
  1344. }
  1345. func TestGlob(t *testing.T) {
  1346. testCases := []Bp2buildTestCase{
  1347. {
  1348. Description: "filegroup with glob",
  1349. ModuleTypeUnderTest: "filegroup",
  1350. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1351. Blueprint: `filegroup {
  1352. name: "fg_foo",
  1353. srcs: ["**/*.txt"],
  1354. bazel_module: { bp2build_available: true },
  1355. }`,
  1356. ExpectedBazelTargets: []string{
  1357. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1358. "srcs": `[
  1359. "other/a.txt",
  1360. "other/b.txt",
  1361. "other/subdir/a.txt",
  1362. ]`,
  1363. }),
  1364. },
  1365. Filesystem: map[string]string{
  1366. "other/a.txt": "",
  1367. "other/b.txt": "",
  1368. "other/subdir/a.txt": "",
  1369. "other/file": "",
  1370. },
  1371. },
  1372. {
  1373. Description: "filegroup with glob in subdir",
  1374. ModuleTypeUnderTest: "filegroup",
  1375. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1376. Dir: "other",
  1377. Filesystem: map[string]string{
  1378. "other/Android.bp": `filegroup {
  1379. name: "fg_foo",
  1380. srcs: ["**/*.txt"],
  1381. bazel_module: { bp2build_available: true },
  1382. }`,
  1383. "other/a.txt": "",
  1384. "other/b.txt": "",
  1385. "other/subdir/a.txt": "",
  1386. "other/file": "",
  1387. },
  1388. ExpectedBazelTargets: []string{
  1389. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1390. "srcs": `[
  1391. "a.txt",
  1392. "b.txt",
  1393. "subdir/a.txt",
  1394. ]`,
  1395. }),
  1396. },
  1397. },
  1398. {
  1399. Description: "filegroup with glob with no kept BUILD files",
  1400. ModuleTypeUnderTest: "filegroup",
  1401. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1402. KeepBuildFileForDirs: []string{
  1403. // empty
  1404. },
  1405. Blueprint: `filegroup {
  1406. name: "fg_foo",
  1407. srcs: ["**/*.txt"],
  1408. bazel_module: { bp2build_available: true },
  1409. }`,
  1410. Filesystem: map[string]string{
  1411. "a.txt": "",
  1412. "b.txt": "",
  1413. "foo/BUILD": "",
  1414. "foo/a.txt": "",
  1415. "foo/bar/BUILD": "",
  1416. "foo/bar/b.txt": "",
  1417. },
  1418. ExpectedBazelTargets: []string{
  1419. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1420. "srcs": `[
  1421. "a.txt",
  1422. "b.txt",
  1423. "foo/a.txt",
  1424. "foo/bar/b.txt",
  1425. ]`,
  1426. }),
  1427. },
  1428. },
  1429. {
  1430. Description: "filegroup with glob with kept BUILD file",
  1431. ModuleTypeUnderTest: "filegroup",
  1432. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1433. KeepBuildFileForDirs: []string{
  1434. "foo",
  1435. },
  1436. Blueprint: `filegroup {
  1437. name: "fg_foo",
  1438. srcs: ["**/*.txt"],
  1439. bazel_module: { bp2build_available: true },
  1440. }`,
  1441. Filesystem: map[string]string{
  1442. "a.txt": "",
  1443. "b.txt": "",
  1444. "foo/BUILD": "",
  1445. "foo/a.txt": "",
  1446. "foo/bar/BUILD": "",
  1447. "foo/bar/b.txt": "",
  1448. },
  1449. ExpectedBazelTargets: []string{
  1450. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1451. "srcs": `[
  1452. "a.txt",
  1453. "b.txt",
  1454. "//foo:a.txt",
  1455. "//foo:bar/b.txt",
  1456. ]`,
  1457. }),
  1458. },
  1459. },
  1460. {
  1461. Description: "filegroup with glob with kept BUILD.bazel file",
  1462. ModuleTypeUnderTest: "filegroup",
  1463. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1464. KeepBuildFileForDirs: []string{
  1465. "foo",
  1466. },
  1467. Blueprint: `filegroup {
  1468. name: "fg_foo",
  1469. srcs: ["**/*.txt"],
  1470. bazel_module: { bp2build_available: true },
  1471. }`,
  1472. Filesystem: map[string]string{
  1473. "a.txt": "",
  1474. "b.txt": "",
  1475. "foo/BUILD.bazel": "",
  1476. "foo/a.txt": "",
  1477. "foo/bar/BUILD.bazel": "",
  1478. "foo/bar/b.txt": "",
  1479. },
  1480. ExpectedBazelTargets: []string{
  1481. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1482. "srcs": `[
  1483. "a.txt",
  1484. "b.txt",
  1485. "//foo:a.txt",
  1486. "//foo:bar/b.txt",
  1487. ]`,
  1488. }),
  1489. },
  1490. },
  1491. {
  1492. Description: "filegroup with glob with Android.bp file as boundary",
  1493. ModuleTypeUnderTest: "filegroup",
  1494. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1495. Blueprint: `filegroup {
  1496. name: "fg_foo",
  1497. srcs: ["**/*.txt"],
  1498. bazel_module: { bp2build_available: true },
  1499. }`,
  1500. Filesystem: map[string]string{
  1501. "a.txt": "",
  1502. "b.txt": "",
  1503. "foo/Android.bp": "",
  1504. "foo/a.txt": "",
  1505. "foo/bar/Android.bp": "",
  1506. "foo/bar/b.txt": "",
  1507. },
  1508. ExpectedBazelTargets: []string{
  1509. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1510. "srcs": `[
  1511. "a.txt",
  1512. "b.txt",
  1513. "//foo:a.txt",
  1514. "//foo/bar:b.txt",
  1515. ]`,
  1516. }),
  1517. },
  1518. },
  1519. {
  1520. Description: "filegroup with glob in subdir with kept BUILD and BUILD.bazel file",
  1521. ModuleTypeUnderTest: "filegroup",
  1522. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1523. Dir: "other",
  1524. KeepBuildFileForDirs: []string{
  1525. "other/foo",
  1526. "other/foo/bar",
  1527. // deliberately not other/foo/baz/BUILD.
  1528. },
  1529. Filesystem: map[string]string{
  1530. "other/Android.bp": `filegroup {
  1531. name: "fg_foo",
  1532. srcs: ["**/*.txt"],
  1533. bazel_module: { bp2build_available: true },
  1534. }`,
  1535. "other/a.txt": "",
  1536. "other/b.txt": "",
  1537. "other/foo/BUILD": "",
  1538. "other/foo/a.txt": "",
  1539. "other/foo/bar/BUILD.bazel": "",
  1540. "other/foo/bar/b.txt": "",
  1541. "other/foo/baz/BUILD": "",
  1542. "other/foo/baz/c.txt": "",
  1543. },
  1544. ExpectedBazelTargets: []string{
  1545. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1546. "srcs": `[
  1547. "a.txt",
  1548. "b.txt",
  1549. "//other/foo:a.txt",
  1550. "//other/foo/bar:b.txt",
  1551. "//other/foo:baz/c.txt",
  1552. ]`,
  1553. }),
  1554. },
  1555. },
  1556. }
  1557. for _, testCase := range testCases {
  1558. t.Run(testCase.Description, func(t *testing.T) {
  1559. RunBp2BuildTestCaseSimple(t, testCase)
  1560. })
  1561. }
  1562. }
  1563. func TestGlobExcludeSrcs(t *testing.T) {
  1564. testCases := []Bp2buildTestCase{
  1565. {
  1566. Description: "filegroup top level exclude_srcs",
  1567. ModuleTypeUnderTest: "filegroup",
  1568. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1569. Blueprint: `filegroup {
  1570. name: "fg_foo",
  1571. srcs: ["**/*.txt"],
  1572. exclude_srcs: ["c.txt"],
  1573. bazel_module: { bp2build_available: true },
  1574. }`,
  1575. Filesystem: map[string]string{
  1576. "a.txt": "",
  1577. "b.txt": "",
  1578. "c.txt": "",
  1579. "dir/Android.bp": "",
  1580. "dir/e.txt": "",
  1581. "dir/f.txt": "",
  1582. },
  1583. ExpectedBazelTargets: []string{
  1584. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1585. "srcs": `[
  1586. "a.txt",
  1587. "b.txt",
  1588. "//dir:e.txt",
  1589. "//dir:f.txt",
  1590. ]`,
  1591. }),
  1592. },
  1593. },
  1594. {
  1595. Description: "filegroup in subdir exclude_srcs",
  1596. ModuleTypeUnderTest: "filegroup",
  1597. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1598. Blueprint: "",
  1599. Dir: "dir",
  1600. Filesystem: map[string]string{
  1601. "dir/Android.bp": `filegroup {
  1602. name: "fg_foo",
  1603. srcs: ["**/*.txt"],
  1604. exclude_srcs: ["b.txt"],
  1605. bazel_module: { bp2build_available: true },
  1606. }
  1607. `,
  1608. "dir/a.txt": "",
  1609. "dir/b.txt": "",
  1610. "dir/subdir/Android.bp": "",
  1611. "dir/subdir/e.txt": "",
  1612. "dir/subdir/f.txt": "",
  1613. },
  1614. ExpectedBazelTargets: []string{
  1615. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1616. "srcs": `[
  1617. "a.txt",
  1618. "//dir/subdir:e.txt",
  1619. "//dir/subdir:f.txt",
  1620. ]`,
  1621. }),
  1622. },
  1623. },
  1624. }
  1625. for _, testCase := range testCases {
  1626. t.Run(testCase.Description, func(t *testing.T) {
  1627. RunBp2BuildTestCaseSimple(t, testCase)
  1628. })
  1629. }
  1630. }
  1631. func TestCommonBp2BuildModuleAttrs(t *testing.T) {
  1632. testCases := []Bp2buildTestCase{
  1633. {
  1634. Description: "Required into data test",
  1635. ModuleTypeUnderTest: "filegroup",
  1636. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1637. Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
  1638. filegroup {
  1639. name: "fg_foo",
  1640. required: ["reqd"],
  1641. bazel_module: { bp2build_available: true },
  1642. }`,
  1643. ExpectedBazelTargets: []string{
  1644. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1645. "data": `[":reqd"]`,
  1646. }),
  1647. },
  1648. },
  1649. {
  1650. Description: "Required into data test, cyclic self reference is filtered out",
  1651. ModuleTypeUnderTest: "filegroup",
  1652. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1653. Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
  1654. filegroup {
  1655. name: "fg_foo",
  1656. required: ["reqd", "fg_foo"],
  1657. bazel_module: { bp2build_available: true },
  1658. }`,
  1659. ExpectedBazelTargets: []string{
  1660. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1661. "data": `[":reqd"]`,
  1662. }),
  1663. },
  1664. },
  1665. {
  1666. Description: "Required via arch into data test",
  1667. ModuleTypeUnderTest: "python_library",
  1668. ModuleTypeUnderTestFactory: python.PythonLibraryFactory,
  1669. Blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqdx86") +
  1670. simpleModuleDoNotConvertBp2build("python_library", "reqdarm") + `
  1671. python_library {
  1672. name: "fg_foo",
  1673. arch: {
  1674. arm: {
  1675. required: ["reqdarm"],
  1676. },
  1677. x86: {
  1678. required: ["reqdx86"],
  1679. },
  1680. },
  1681. bazel_module: { bp2build_available: true },
  1682. }`,
  1683. ExpectedBazelTargets: []string{
  1684. MakeBazelTarget("py_library", "fg_foo", map[string]string{
  1685. "data": `select({
  1686. "//build/bazel/platforms/arch:arm": [":reqdarm"],
  1687. "//build/bazel/platforms/arch:x86": [":reqdx86"],
  1688. "//conditions:default": [],
  1689. })`,
  1690. "srcs_version": `"PY3"`,
  1691. "imports": `["."]`,
  1692. }),
  1693. },
  1694. },
  1695. {
  1696. Description: "Required appended to data test",
  1697. ModuleTypeUnderTest: "python_library",
  1698. ModuleTypeUnderTestFactory: python.PythonLibraryFactory,
  1699. Filesystem: map[string]string{
  1700. "data.bin": "",
  1701. "src.py": "",
  1702. },
  1703. Blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqd") + `
  1704. python_library {
  1705. name: "fg_foo",
  1706. data: ["data.bin"],
  1707. required: ["reqd"],
  1708. bazel_module: { bp2build_available: true },
  1709. }`,
  1710. ExpectedBazelTargets: []string{
  1711. MakeBazelTarget("py_library", "fg_foo", map[string]string{
  1712. "data": `[
  1713. "data.bin",
  1714. ":reqd",
  1715. ]`,
  1716. "srcs_version": `"PY3"`,
  1717. "imports": `["."]`,
  1718. }),
  1719. },
  1720. },
  1721. {
  1722. Description: "All props-to-attrs at once together test",
  1723. ModuleTypeUnderTest: "filegroup",
  1724. ModuleTypeUnderTestFactory: android.FileGroupFactory,
  1725. Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
  1726. filegroup {
  1727. name: "fg_foo",
  1728. required: ["reqd"],
  1729. bazel_module: { bp2build_available: true },
  1730. }`,
  1731. ExpectedBazelTargets: []string{
  1732. MakeBazelTargetNoRestrictions("filegroup", "fg_foo", map[string]string{
  1733. "data": `[":reqd"]`,
  1734. }),
  1735. },
  1736. },
  1737. }
  1738. for _, tc := range testCases {
  1739. t.Run(tc.Description, func(t *testing.T) {
  1740. RunBp2BuildTestCaseSimple(t, tc)
  1741. })
  1742. }
  1743. }