module_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. // Copyright 2015 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 android
  15. import (
  16. "path/filepath"
  17. "runtime"
  18. "testing"
  19. )
  20. func TestSrcIsModule(t *testing.T) {
  21. type args struct {
  22. s string
  23. }
  24. tests := []struct {
  25. name string
  26. args args
  27. wantModule string
  28. }{
  29. {
  30. name: "file",
  31. args: args{
  32. s: "foo",
  33. },
  34. wantModule: "",
  35. },
  36. {
  37. name: "module",
  38. args: args{
  39. s: ":foo",
  40. },
  41. wantModule: "foo",
  42. },
  43. {
  44. name: "tag",
  45. args: args{
  46. s: ":foo{.bar}",
  47. },
  48. wantModule: "foo{.bar}",
  49. },
  50. {
  51. name: "extra colon",
  52. args: args{
  53. s: ":foo:bar",
  54. },
  55. wantModule: "foo:bar",
  56. },
  57. {
  58. name: "fully qualified",
  59. args: args{
  60. s: "//foo:bar",
  61. },
  62. wantModule: "//foo:bar",
  63. },
  64. {
  65. name: "fully qualified with tag",
  66. args: args{
  67. s: "//foo:bar{.tag}",
  68. },
  69. wantModule: "//foo:bar{.tag}",
  70. },
  71. {
  72. name: "invalid unqualified name",
  73. args: args{
  74. s: ":foo/bar",
  75. },
  76. wantModule: "",
  77. },
  78. }
  79. for _, tt := range tests {
  80. t.Run(tt.name, func(t *testing.T) {
  81. if gotModule := SrcIsModule(tt.args.s); gotModule != tt.wantModule {
  82. t.Errorf("SrcIsModule() = %v, want %v", gotModule, tt.wantModule)
  83. }
  84. })
  85. }
  86. }
  87. func TestSrcIsModuleWithTag(t *testing.T) {
  88. type args struct {
  89. s string
  90. }
  91. tests := []struct {
  92. name string
  93. args args
  94. wantModule string
  95. wantTag string
  96. }{
  97. {
  98. name: "file",
  99. args: args{
  100. s: "foo",
  101. },
  102. wantModule: "",
  103. wantTag: "",
  104. },
  105. {
  106. name: "module",
  107. args: args{
  108. s: ":foo",
  109. },
  110. wantModule: "foo",
  111. wantTag: "",
  112. },
  113. {
  114. name: "tag",
  115. args: args{
  116. s: ":foo{.bar}",
  117. },
  118. wantModule: "foo",
  119. wantTag: ".bar",
  120. },
  121. {
  122. name: "empty tag",
  123. args: args{
  124. s: ":foo{}",
  125. },
  126. wantModule: "foo",
  127. wantTag: "",
  128. },
  129. {
  130. name: "extra colon",
  131. args: args{
  132. s: ":foo:bar",
  133. },
  134. wantModule: "foo:bar",
  135. },
  136. {
  137. name: "invalid tag",
  138. args: args{
  139. s: ":foo{.bar",
  140. },
  141. wantModule: "foo{.bar",
  142. },
  143. {
  144. name: "invalid tag 2",
  145. args: args{
  146. s: ":foo.bar}",
  147. },
  148. wantModule: "foo.bar}",
  149. },
  150. {
  151. name: "fully qualified",
  152. args: args{
  153. s: "//foo:bar",
  154. },
  155. wantModule: "//foo:bar",
  156. },
  157. {
  158. name: "fully qualified with tag",
  159. args: args{
  160. s: "//foo:bar{.tag}",
  161. },
  162. wantModule: "//foo:bar",
  163. wantTag: ".tag",
  164. },
  165. {
  166. name: "invalid unqualified name",
  167. args: args{
  168. s: ":foo/bar",
  169. },
  170. wantModule: "",
  171. },
  172. {
  173. name: "invalid unqualified name with tag",
  174. args: args{
  175. s: ":foo/bar{.tag}",
  176. },
  177. wantModule: "",
  178. },
  179. }
  180. for _, tt := range tests {
  181. t.Run(tt.name, func(t *testing.T) {
  182. gotModule, gotTag := SrcIsModuleWithTag(tt.args.s)
  183. if gotModule != tt.wantModule {
  184. t.Errorf("SrcIsModuleWithTag() gotModule = %v, want %v", gotModule, tt.wantModule)
  185. }
  186. if gotTag != tt.wantTag {
  187. t.Errorf("SrcIsModuleWithTag() gotTag = %v, want %v", gotTag, tt.wantTag)
  188. }
  189. })
  190. }
  191. }
  192. type depsModule struct {
  193. ModuleBase
  194. props struct {
  195. Deps []string
  196. }
  197. }
  198. func (m *depsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  199. outputFile := PathForModuleOut(ctx, ctx.ModuleName())
  200. ctx.Build(pctx, BuildParams{
  201. Rule: Touch,
  202. Output: outputFile,
  203. })
  204. installFile := ctx.InstallFile(PathForModuleInstall(ctx), ctx.ModuleName(), outputFile)
  205. ctx.InstallSymlink(PathForModuleInstall(ctx, "symlinks"), ctx.ModuleName(), installFile)
  206. }
  207. func (m *depsModule) DepsMutator(ctx BottomUpMutatorContext) {
  208. ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
  209. }
  210. func depsModuleFactory() Module {
  211. m := &depsModule{}
  212. m.AddProperties(&m.props)
  213. InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
  214. return m
  215. }
  216. var prepareForModuleTests = FixtureRegisterWithContext(func(ctx RegistrationContext) {
  217. ctx.RegisterModuleType("deps", depsModuleFactory)
  218. })
  219. func TestErrorDependsOnDisabledModule(t *testing.T) {
  220. bp := `
  221. deps {
  222. name: "foo",
  223. deps: ["bar"],
  224. }
  225. deps {
  226. name: "bar",
  227. enabled: false,
  228. }
  229. `
  230. prepareForModuleTests.
  231. ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo": depends on disabled module "bar"`)).
  232. RunTestWithBp(t, bp)
  233. }
  234. func TestValidateCorrectBuildParams(t *testing.T) {
  235. config := TestConfig(t.TempDir(), nil, "", nil)
  236. pathContext := PathContextForTesting(config)
  237. bparams := convertBuildParams(BuildParams{
  238. // Test with Output
  239. Output: PathForOutput(pathContext, "undeclared_symlink"),
  240. SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"),
  241. })
  242. err := validateBuildParams(bparams)
  243. if err != nil {
  244. t.Error(err)
  245. }
  246. bparams = convertBuildParams(BuildParams{
  247. // Test with ImplicitOutput
  248. ImplicitOutput: PathForOutput(pathContext, "undeclared_symlink"),
  249. SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"),
  250. })
  251. err = validateBuildParams(bparams)
  252. if err != nil {
  253. t.Error(err)
  254. }
  255. }
  256. func TestValidateIncorrectBuildParams(t *testing.T) {
  257. config := TestConfig(t.TempDir(), nil, "", nil)
  258. pathContext := PathContextForTesting(config)
  259. params := BuildParams{
  260. Output: PathForOutput(pathContext, "regular_output"),
  261. Outputs: PathsForOutput(pathContext, []string{"out1", "out2"}),
  262. ImplicitOutput: PathForOutput(pathContext, "implicit_output"),
  263. ImplicitOutputs: PathsForOutput(pathContext, []string{"i_out1", "_out2"}),
  264. SymlinkOutput: PathForOutput(pathContext, "undeclared_symlink"),
  265. }
  266. bparams := convertBuildParams(params)
  267. err := validateBuildParams(bparams)
  268. if err != nil {
  269. FailIfNoMatchingErrors(t, "undeclared_symlink is not a declared output or implicit output", []error{err})
  270. } else {
  271. t.Errorf("Expected build params to fail validation: %+v", bparams)
  272. }
  273. }
  274. func TestDistErrorChecking(t *testing.T) {
  275. bp := `
  276. deps {
  277. name: "foo",
  278. dist: {
  279. dest: "../invalid-dest",
  280. dir: "../invalid-dir",
  281. suffix: "invalid/suffix",
  282. },
  283. dists: [
  284. {
  285. dest: "../invalid-dest0",
  286. dir: "../invalid-dir0",
  287. suffix: "invalid/suffix0",
  288. },
  289. {
  290. dest: "../invalid-dest1",
  291. dir: "../invalid-dir1",
  292. suffix: "invalid/suffix1",
  293. },
  294. ],
  295. }
  296. `
  297. expectedErrs := []string{
  298. "\\QAndroid.bp:5:13: module \"foo\": dist.dest: Path is outside directory: ../invalid-dest\\E",
  299. "\\QAndroid.bp:6:12: module \"foo\": dist.dir: Path is outside directory: ../invalid-dir\\E",
  300. "\\QAndroid.bp:7:15: module \"foo\": dist.suffix: Suffix may not contain a '/' character.\\E",
  301. "\\QAndroid.bp:11:15: module \"foo\": dists[0].dest: Path is outside directory: ../invalid-dest0\\E",
  302. "\\QAndroid.bp:12:14: module \"foo\": dists[0].dir: Path is outside directory: ../invalid-dir0\\E",
  303. "\\QAndroid.bp:13:17: module \"foo\": dists[0].suffix: Suffix may not contain a '/' character.\\E",
  304. "\\QAndroid.bp:16:15: module \"foo\": dists[1].dest: Path is outside directory: ../invalid-dest1\\E",
  305. "\\QAndroid.bp:17:14: module \"foo\": dists[1].dir: Path is outside directory: ../invalid-dir1\\E",
  306. "\\QAndroid.bp:18:17: module \"foo\": dists[1].suffix: Suffix may not contain a '/' character.\\E",
  307. }
  308. prepareForModuleTests.
  309. ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)).
  310. RunTestWithBp(t, bp)
  311. }
  312. func TestInstall(t *testing.T) {
  313. if runtime.GOOS != "linux" {
  314. t.Skip("requires linux")
  315. }
  316. bp := `
  317. deps {
  318. name: "foo",
  319. deps: ["bar"],
  320. }
  321. deps {
  322. name: "bar",
  323. deps: ["baz", "qux"],
  324. }
  325. deps {
  326. name: "baz",
  327. deps: ["qux"],
  328. }
  329. deps {
  330. name: "qux",
  331. }
  332. `
  333. result := GroupFixturePreparers(
  334. prepareForModuleTests,
  335. PrepareForTestWithArchMutator,
  336. ).RunTestWithBp(t, bp)
  337. module := func(name string, host bool) TestingModule {
  338. variant := "android_common"
  339. if host {
  340. variant = result.Config.BuildOSCommonTarget.String()
  341. }
  342. return result.ModuleForTests(name, variant)
  343. }
  344. outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
  345. installRule := func(name string) TestingBuildParams {
  346. return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system", name))
  347. }
  348. symlinkRule := func(name string) TestingBuildParams {
  349. return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system/symlinks", name))
  350. }
  351. hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
  352. hostInstallRule := func(name string) TestingBuildParams {
  353. return module(name, true).Output(filepath.Join("out/soong/host/linux-x86", name))
  354. }
  355. hostSymlinkRule := func(name string) TestingBuildParams {
  356. return module(name, true).Output(filepath.Join("out/soong/host/linux-x86/symlinks", name))
  357. }
  358. assertInputs := func(params TestingBuildParams, inputs ...Path) {
  359. t.Helper()
  360. AssertArrayString(t, "expected inputs", Paths(inputs).Strings(),
  361. append(PathsIfNonNil(params.Input), params.Inputs...).Strings())
  362. }
  363. assertImplicits := func(params TestingBuildParams, implicits ...Path) {
  364. t.Helper()
  365. AssertArrayString(t, "expected implicit dependencies", Paths(implicits).Strings(),
  366. append(PathsIfNonNil(params.Implicit), params.Implicits...).Strings())
  367. }
  368. assertOrderOnlys := func(params TestingBuildParams, orderonlys ...Path) {
  369. t.Helper()
  370. AssertArrayString(t, "expected orderonly dependencies", Paths(orderonlys).Strings(),
  371. params.OrderOnly.Strings())
  372. }
  373. // Check host install rule dependencies
  374. assertInputs(hostInstallRule("foo"), hostOutputRule("foo").Output)
  375. assertImplicits(hostInstallRule("foo"),
  376. hostInstallRule("bar").Output,
  377. hostSymlinkRule("bar").Output,
  378. hostInstallRule("baz").Output,
  379. hostSymlinkRule("baz").Output,
  380. hostInstallRule("qux").Output,
  381. hostSymlinkRule("qux").Output,
  382. )
  383. assertOrderOnlys(hostInstallRule("foo"))
  384. // Check host symlink rule dependencies. Host symlinks must use a normal dependency, not an
  385. // order-only dependency, so that the tool gets updated when the symlink is depended on.
  386. assertInputs(hostSymlinkRule("foo"), hostInstallRule("foo").Output)
  387. assertImplicits(hostSymlinkRule("foo"))
  388. assertOrderOnlys(hostSymlinkRule("foo"))
  389. // Check device install rule dependencies
  390. assertInputs(installRule("foo"), outputRule("foo").Output)
  391. assertImplicits(installRule("foo"))
  392. assertOrderOnlys(installRule("foo"),
  393. installRule("bar").Output,
  394. symlinkRule("bar").Output,
  395. installRule("baz").Output,
  396. symlinkRule("baz").Output,
  397. installRule("qux").Output,
  398. symlinkRule("qux").Output,
  399. )
  400. // Check device symlink rule dependencies. Device symlinks could use an order-only dependency,
  401. // but the current implementation uses a normal dependency.
  402. assertInputs(symlinkRule("foo"), installRule("foo").Output)
  403. assertImplicits(symlinkRule("foo"))
  404. assertOrderOnlys(symlinkRule("foo"))
  405. }
  406. func TestInstallKatiEnabled(t *testing.T) {
  407. if runtime.GOOS != "linux" {
  408. t.Skip("requires linux")
  409. }
  410. bp := `
  411. deps {
  412. name: "foo",
  413. deps: ["bar"],
  414. }
  415. deps {
  416. name: "bar",
  417. deps: ["baz", "qux"],
  418. }
  419. deps {
  420. name: "baz",
  421. deps: ["qux"],
  422. }
  423. deps {
  424. name: "qux",
  425. }
  426. `
  427. result := GroupFixturePreparers(
  428. prepareForModuleTests,
  429. PrepareForTestWithArchMutator,
  430. FixtureModifyConfig(SetKatiEnabledForTests),
  431. PrepareForTestWithMakevars,
  432. ).RunTestWithBp(t, bp)
  433. rules := result.InstallMakeRulesForTesting(t)
  434. module := func(name string, host bool) TestingModule {
  435. variant := "android_common"
  436. if host {
  437. variant = result.Config.BuildOSCommonTarget.String()
  438. }
  439. return result.ModuleForTests(name, variant)
  440. }
  441. outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
  442. ruleForOutput := func(output string) InstallMakeRule {
  443. for _, rule := range rules {
  444. if rule.Target == output {
  445. return rule
  446. }
  447. }
  448. t.Fatalf("no make install rule for %s", output)
  449. return InstallMakeRule{}
  450. }
  451. installRule := func(name string) InstallMakeRule {
  452. return ruleForOutput(filepath.Join("out/target/product/test_device/system", name))
  453. }
  454. symlinkRule := func(name string) InstallMakeRule {
  455. return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
  456. }
  457. hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
  458. hostInstallRule := func(name string) InstallMakeRule {
  459. return ruleForOutput(filepath.Join("out/host/linux-x86", name))
  460. }
  461. hostSymlinkRule := func(name string) InstallMakeRule {
  462. return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
  463. }
  464. assertDeps := func(rule InstallMakeRule, deps ...string) {
  465. t.Helper()
  466. AssertArrayString(t, "expected inputs", deps, rule.Deps)
  467. }
  468. assertOrderOnlys := func(rule InstallMakeRule, orderonlys ...string) {
  469. t.Helper()
  470. AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.OrderOnlyDeps)
  471. }
  472. // Check host install rule dependencies
  473. assertDeps(hostInstallRule("foo"),
  474. hostOutputRule("foo").Output.String(),
  475. hostInstallRule("bar").Target,
  476. hostSymlinkRule("bar").Target,
  477. hostInstallRule("baz").Target,
  478. hostSymlinkRule("baz").Target,
  479. hostInstallRule("qux").Target,
  480. hostSymlinkRule("qux").Target,
  481. )
  482. assertOrderOnlys(hostInstallRule("foo"))
  483. // Check host symlink rule dependencies. Host symlinks must use a normal dependency, not an
  484. // order-only dependency, so that the tool gets updated when the symlink is depended on.
  485. assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").Target)
  486. assertOrderOnlys(hostSymlinkRule("foo"))
  487. // Check device install rule dependencies
  488. assertDeps(installRule("foo"), outputRule("foo").Output.String())
  489. assertOrderOnlys(installRule("foo"),
  490. installRule("bar").Target,
  491. symlinkRule("bar").Target,
  492. installRule("baz").Target,
  493. symlinkRule("baz").Target,
  494. installRule("qux").Target,
  495. symlinkRule("qux").Target,
  496. )
  497. // Check device symlink rule dependencies. Device symlinks could use an order-only dependency,
  498. // but the current implementation uses a normal dependency.
  499. assertDeps(symlinkRule("foo"), installRule("foo").Target)
  500. assertOrderOnlys(symlinkRule("foo"))
  501. }
  502. type PropsTestModuleEmbedded struct {
  503. Embedded_prop *string
  504. }
  505. type propsTestModule struct {
  506. ModuleBase
  507. DefaultableModuleBase
  508. props struct {
  509. A string `android:"arch_variant"`
  510. B *bool
  511. C []string
  512. }
  513. otherProps struct {
  514. PropsTestModuleEmbedded
  515. D *int64
  516. Nested struct {
  517. E *string
  518. }
  519. F *string `blueprint:"mutated"`
  520. }
  521. }
  522. func propsTestModuleFactory() Module {
  523. module := &propsTestModule{}
  524. module.AddProperties(&module.props, &module.otherProps)
  525. InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth)
  526. InitDefaultableModule(module)
  527. return module
  528. }
  529. type propsTestModuleDefaults struct {
  530. ModuleBase
  531. DefaultsModuleBase
  532. }
  533. func propsTestModuleDefaultsFactory() Module {
  534. defaults := &propsTestModuleDefaults{}
  535. module := propsTestModule{}
  536. defaults.AddProperties(&module.props, &module.otherProps)
  537. InitDefaultsModule(defaults)
  538. return defaults
  539. }
  540. func (p *propsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  541. str := "abc"
  542. p.otherProps.F = &str
  543. }
  544. func TestUsedProperties(t *testing.T) {
  545. testCases := []struct {
  546. desc string
  547. bp string
  548. expectedProps []propInfo
  549. }{
  550. {
  551. desc: "only name",
  552. bp: `test {
  553. name: "foo",
  554. }
  555. `,
  556. expectedProps: []propInfo{
  557. propInfo{"Name", "string"},
  558. },
  559. },
  560. {
  561. desc: "some props",
  562. bp: `test {
  563. name: "foo",
  564. a: "abc",
  565. b: true,
  566. d: 123,
  567. }
  568. `,
  569. expectedProps: []propInfo{
  570. propInfo{"A", "string"},
  571. propInfo{"B", "bool"},
  572. propInfo{"D", "int64"},
  573. propInfo{"Name", "string"},
  574. },
  575. },
  576. {
  577. desc: "unused non-pointer prop",
  578. bp: `test {
  579. name: "foo",
  580. b: true,
  581. d: 123,
  582. }
  583. `,
  584. expectedProps: []propInfo{
  585. // for non-pointer cannot distinguish between unused and intentionally set to empty
  586. propInfo{"A", "string"},
  587. propInfo{"B", "bool"},
  588. propInfo{"D", "int64"},
  589. propInfo{"Name", "string"},
  590. },
  591. },
  592. {
  593. desc: "nested props",
  594. bp: `test {
  595. name: "foo",
  596. nested: {
  597. e: "abc",
  598. }
  599. }
  600. `,
  601. expectedProps: []propInfo{
  602. propInfo{"Nested.E", "string"},
  603. propInfo{"Name", "string"},
  604. },
  605. },
  606. {
  607. desc: "arch props",
  608. bp: `test {
  609. name: "foo",
  610. arch: {
  611. x86_64: {
  612. a: "abc",
  613. },
  614. }
  615. }
  616. `,
  617. expectedProps: []propInfo{
  618. propInfo{"Name", "string"},
  619. propInfo{"Arch.X86_64.A", "string"},
  620. },
  621. },
  622. {
  623. desc: "embedded props",
  624. bp: `test {
  625. name: "foo",
  626. embedded_prop: "a",
  627. }
  628. `,
  629. expectedProps: []propInfo{
  630. propInfo{"Embedded_prop", "string"},
  631. propInfo{"Name", "string"},
  632. },
  633. },
  634. {
  635. desc: "defaults",
  636. bp: `
  637. test_defaults {
  638. name: "foo_defaults",
  639. a: "a",
  640. b: true,
  641. embedded_prop:"a",
  642. arch: {
  643. x86_64: {
  644. a: "a",
  645. },
  646. },
  647. }
  648. test {
  649. name: "foo",
  650. defaults: ["foo_defaults"],
  651. c: ["a"],
  652. nested: {
  653. e: "d",
  654. },
  655. target: {
  656. linux: {
  657. a: "a",
  658. },
  659. },
  660. }
  661. `,
  662. expectedProps: []propInfo{
  663. propInfo{"A", "string"},
  664. propInfo{"B", "bool"},
  665. propInfo{"C", "string slice"},
  666. propInfo{"Embedded_prop", "string"},
  667. propInfo{"Nested.E", "string"},
  668. propInfo{"Name", "string"},
  669. propInfo{"Arch.X86_64.A", "string"},
  670. propInfo{"Target.Linux.A", "string"},
  671. propInfo{"Defaults", "string slice"},
  672. },
  673. },
  674. }
  675. for _, tc := range testCases {
  676. t.Run(tc.desc, func(t *testing.T) {
  677. result := GroupFixturePreparers(
  678. PrepareForTestWithAllowMissingDependencies,
  679. PrepareForTestWithDefaults,
  680. FixtureRegisterWithContext(func(ctx RegistrationContext) {
  681. ctx.RegisterModuleType("test", propsTestModuleFactory)
  682. ctx.RegisterModuleType("test_defaults", propsTestModuleDefaultsFactory)
  683. }),
  684. FixtureWithRootAndroidBp(tc.bp),
  685. ).RunTest(t)
  686. foo := result.ModuleForTests("foo", "").Module().base()
  687. AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())
  688. })
  689. }
  690. }