namespace_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. // Copyright 2017 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. "reflect"
  18. "testing"
  19. "github.com/google/blueprint"
  20. )
  21. func TestDependingOnModuleInSameNamespace(t *testing.T) {
  22. result := GroupFixturePreparers(
  23. prepareForTestWithNamespace,
  24. dirBpToPreparer(map[string]string{
  25. "dir1": `
  26. soong_namespace {
  27. }
  28. test_module {
  29. name: "a",
  30. }
  31. test_module {
  32. name: "b",
  33. deps: ["a"],
  34. }
  35. `,
  36. }),
  37. ).RunTest(t)
  38. a := getModule(result, "a")
  39. b := getModule(result, "b")
  40. if !dependsOn(result, b, a) {
  41. t.Errorf("module b does not depend on module a in the same namespace")
  42. }
  43. }
  44. func TestDependingOnModuleInRootNamespace(t *testing.T) {
  45. result := GroupFixturePreparers(
  46. prepareForTestWithNamespace,
  47. dirBpToPreparer(map[string]string{
  48. ".": `
  49. test_module {
  50. name: "b",
  51. deps: ["a"],
  52. }
  53. test_module {
  54. name: "a",
  55. }
  56. `,
  57. }),
  58. ).RunTest(t)
  59. a := getModule(result, "a")
  60. b := getModule(result, "b")
  61. if !dependsOn(result, b, a) {
  62. t.Errorf("module b in root namespace does not depend on module a in the root namespace")
  63. }
  64. }
  65. func TestImplicitlyImportRootNamespace(t *testing.T) {
  66. GroupFixturePreparers(
  67. prepareForTestWithNamespace,
  68. dirBpToPreparer(map[string]string{
  69. ".": `
  70. test_module {
  71. name: "a",
  72. }
  73. `,
  74. "dir1": `
  75. soong_namespace {
  76. }
  77. test_module {
  78. name: "b",
  79. deps: ["a"],
  80. }
  81. `,
  82. }),
  83. ).RunTest(t)
  84. // RunTest will report any errors
  85. }
  86. func TestDependingOnBlueprintModuleInRootNamespace(t *testing.T) {
  87. GroupFixturePreparers(
  88. prepareForTestWithNamespace,
  89. dirBpToPreparer(map[string]string{
  90. ".": `
  91. blueprint_test_module {
  92. name: "a",
  93. }
  94. `,
  95. "dir1": `
  96. soong_namespace {
  97. }
  98. blueprint_test_module {
  99. name: "b",
  100. deps: ["a"],
  101. }
  102. `,
  103. }),
  104. ).RunTest(t)
  105. // RunTest will report any errors
  106. }
  107. func TestDependingOnModuleInImportedNamespace(t *testing.T) {
  108. result := GroupFixturePreparers(
  109. prepareForTestWithNamespace,
  110. dirBpToPreparer(map[string]string{
  111. "dir1": `
  112. soong_namespace {
  113. }
  114. test_module {
  115. name: "a",
  116. }
  117. `,
  118. "dir2": `
  119. soong_namespace {
  120. imports: ["dir1"],
  121. }
  122. test_module {
  123. name: "b",
  124. deps: ["a"],
  125. }
  126. `,
  127. }),
  128. ).RunTest(t)
  129. a := getModule(result, "a")
  130. b := getModule(result, "b")
  131. if !dependsOn(result, b, a) {
  132. t.Errorf("module b does not depend on module a in the same namespace")
  133. }
  134. }
  135. func TestDependingOnModuleInNonImportedNamespace(t *testing.T) {
  136. GroupFixturePreparers(
  137. prepareForTestWithNamespace,
  138. dirBpToPreparer(map[string]string{
  139. "dir1": `
  140. soong_namespace {
  141. }
  142. test_module {
  143. name: "a",
  144. }
  145. `,
  146. "dir2": `
  147. soong_namespace {
  148. }
  149. test_module {
  150. name: "a",
  151. }
  152. `,
  153. "dir3": `
  154. soong_namespace {
  155. }
  156. test_module {
  157. name: "b",
  158. deps: ["a"],
  159. }
  160. `,
  161. }),
  162. ).
  163. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir3/Android.bp:4:5: "b" depends on undefined module "a".
  164. Module "b" is defined in namespace "dir3" which can read these 2 namespaces: ["dir3" "."]
  165. Module "a" can be found in these namespaces: ["dir1" "dir2"]\E
  166. Or did you mean ["soong_namespace"]?`)).
  167. RunTest(t)
  168. }
  169. func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) {
  170. result := GroupFixturePreparers(
  171. prepareForTestWithNamespace,
  172. dirBpToPreparer(map[string]string{
  173. "dir1": `
  174. soong_namespace {
  175. }
  176. test_module {
  177. name: "a",
  178. }
  179. `,
  180. "dir2": `
  181. soong_namespace {
  182. }
  183. test_module {
  184. name: "b",
  185. deps: ["//dir1:a"],
  186. }
  187. `,
  188. }),
  189. ).RunTest(t)
  190. a := getModule(result, "a")
  191. b := getModule(result, "b")
  192. if !dependsOn(result, b, a) {
  193. t.Errorf("module b does not depend on module a")
  194. }
  195. }
  196. func TestSameNameInTwoNamespaces(t *testing.T) {
  197. result := GroupFixturePreparers(
  198. prepareForTestWithNamespace,
  199. dirBpToPreparer(map[string]string{
  200. "dir1": `
  201. soong_namespace {
  202. }
  203. test_module {
  204. name: "a",
  205. id: "1",
  206. }
  207. test_module {
  208. name: "b",
  209. deps: ["a"],
  210. id: "2",
  211. }
  212. `,
  213. "dir2": `
  214. soong_namespace {
  215. }
  216. test_module {
  217. name: "a",
  218. id:"3",
  219. }
  220. test_module {
  221. name: "b",
  222. deps: ["a"],
  223. id:"4",
  224. }
  225. `,
  226. }),
  227. ).RunTest(t)
  228. one := findModuleById(result, "1")
  229. two := findModuleById(result, "2")
  230. three := findModuleById(result, "3")
  231. four := findModuleById(result, "4")
  232. if !dependsOn(result, two, one) {
  233. t.Fatalf("Module 2 does not depend on module 1 in its namespace")
  234. }
  235. if dependsOn(result, two, three) {
  236. t.Fatalf("Module 2 depends on module 3 in another namespace")
  237. }
  238. if !dependsOn(result, four, three) {
  239. t.Fatalf("Module 4 does not depend on module 3 in its namespace")
  240. }
  241. if dependsOn(result, four, one) {
  242. t.Fatalf("Module 4 depends on module 1 in another namespace")
  243. }
  244. }
  245. func TestSearchOrder(t *testing.T) {
  246. result := GroupFixturePreparers(
  247. prepareForTestWithNamespace,
  248. dirBpToPreparer(map[string]string{
  249. "dir1": `
  250. soong_namespace {
  251. }
  252. test_module {
  253. name: "a",
  254. id: "1",
  255. }
  256. `,
  257. "dir2": `
  258. soong_namespace {
  259. }
  260. test_module {
  261. name: "a",
  262. id:"2",
  263. }
  264. test_module {
  265. name: "b",
  266. id:"3",
  267. }
  268. `,
  269. "dir3": `
  270. soong_namespace {
  271. }
  272. test_module {
  273. name: "a",
  274. id:"4",
  275. }
  276. test_module {
  277. name: "b",
  278. id:"5",
  279. }
  280. test_module {
  281. name: "c",
  282. id:"6",
  283. }
  284. `,
  285. ".": `
  286. test_module {
  287. name: "a",
  288. id: "7",
  289. }
  290. test_module {
  291. name: "b",
  292. id: "8",
  293. }
  294. test_module {
  295. name: "c",
  296. id: "9",
  297. }
  298. test_module {
  299. name: "d",
  300. id: "10",
  301. }
  302. `,
  303. "dir4": `
  304. soong_namespace {
  305. imports: ["dir1", "dir2", "dir3"]
  306. }
  307. test_module {
  308. name: "test_me",
  309. id:"0",
  310. deps: ["a", "b", "c", "d"],
  311. }
  312. `,
  313. }),
  314. ).RunTest(t)
  315. testMe := findModuleById(result, "0")
  316. if !dependsOn(result, testMe, findModuleById(result, "1")) {
  317. t.Errorf("test_me doesn't depend on id 1")
  318. }
  319. if !dependsOn(result, testMe, findModuleById(result, "3")) {
  320. t.Errorf("test_me doesn't depend on id 3")
  321. }
  322. if !dependsOn(result, testMe, findModuleById(result, "6")) {
  323. t.Errorf("test_me doesn't depend on id 6")
  324. }
  325. if !dependsOn(result, testMe, findModuleById(result, "10")) {
  326. t.Errorf("test_me doesn't depend on id 10")
  327. }
  328. if numDeps(result, testMe) != 4 {
  329. t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(result, testMe))
  330. }
  331. }
  332. func TestTwoNamespacesCanImportEachOther(t *testing.T) {
  333. GroupFixturePreparers(
  334. prepareForTestWithNamespace,
  335. dirBpToPreparer(map[string]string{
  336. "dir1": `
  337. soong_namespace {
  338. imports: ["dir2"]
  339. }
  340. test_module {
  341. name: "a",
  342. }
  343. test_module {
  344. name: "c",
  345. deps: ["b"],
  346. }
  347. `,
  348. "dir2": `
  349. soong_namespace {
  350. imports: ["dir1"],
  351. }
  352. test_module {
  353. name: "b",
  354. deps: ["a"],
  355. }
  356. `,
  357. }),
  358. ).RunTest(t)
  359. // RunTest will report any errors
  360. }
  361. func TestImportingNonexistentNamespace(t *testing.T) {
  362. GroupFixturePreparers(
  363. prepareForTestWithNamespace,
  364. dirBpToPreparer(map[string]string{
  365. "dir1": `
  366. soong_namespace {
  367. imports: ["a_nonexistent_namespace"]
  368. }
  369. test_module {
  370. name: "a",
  371. deps: ["a_nonexistent_module"]
  372. }
  373. `,
  374. }),
  375. ).
  376. // should complain about the missing namespace and not complain about the unresolvable dependency
  377. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:2:5: module "soong_namespace": namespace a_nonexistent_namespace does not exist\E`)).
  378. RunTest(t)
  379. }
  380. func TestNamespacesDontInheritParentNamespaces(t *testing.T) {
  381. GroupFixturePreparers(
  382. prepareForTestWithNamespace,
  383. dirBpToPreparer(map[string]string{
  384. "dir1": `
  385. soong_namespace {
  386. }
  387. test_module {
  388. name: "a",
  389. }
  390. `,
  391. "dir1/subdir1": `
  392. soong_namespace {
  393. }
  394. test_module {
  395. name: "b",
  396. deps: ["a"],
  397. }
  398. `,
  399. }),
  400. ).
  401. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/subdir1/Android.bp:4:5: "b" depends on undefined module "a".
  402. Module "b" is defined in namespace "dir1/subdir1" which can read these 2 namespaces: ["dir1/subdir1" "."]
  403. Module "a" can be found in these namespaces: ["dir1"]\E
  404. Or did you mean ["soong_namespace"]?`)).
  405. RunTest(t)
  406. }
  407. func TestModulesDoReceiveParentNamespace(t *testing.T) {
  408. GroupFixturePreparers(
  409. prepareForTestWithNamespace,
  410. dirBpToPreparer(map[string]string{
  411. "dir1": `
  412. soong_namespace {
  413. }
  414. test_module {
  415. name: "a",
  416. }
  417. `,
  418. "dir1/subdir": `
  419. test_module {
  420. name: "b",
  421. deps: ["a"],
  422. }
  423. `,
  424. }),
  425. ).RunTest(t)
  426. // RunTest will report any errors
  427. }
  428. func TestNamespaceImportsNotTransitive(t *testing.T) {
  429. GroupFixturePreparers(
  430. prepareForTestWithNamespace,
  431. dirBpToPreparer(map[string]string{
  432. "dir1": `
  433. soong_namespace {
  434. }
  435. test_module {
  436. name: "a",
  437. }
  438. `,
  439. "dir2": `
  440. soong_namespace {
  441. imports: ["dir1"],
  442. }
  443. test_module {
  444. name: "b",
  445. deps: ["a"],
  446. }
  447. `,
  448. "dir3": `
  449. soong_namespace {
  450. imports: ["dir2"],
  451. }
  452. test_module {
  453. name: "c",
  454. deps: ["a"],
  455. }
  456. `,
  457. }),
  458. ).
  459. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir3/Android.bp:5:5: "c" depends on undefined module "a".
  460. Module "c" is defined in namespace "dir3" which can read these 3 namespaces: ["dir3" "dir2" "."]
  461. Module "a" can be found in these namespaces: ["dir1"]\E
  462. Or did you mean ["b"]?`)).
  463. RunTest(t)
  464. }
  465. func TestTwoNamepacesInSameDir(t *testing.T) {
  466. GroupFixturePreparers(
  467. prepareForTestWithNamespace,
  468. dirBpToPreparer(map[string]string{
  469. "dir1": `
  470. soong_namespace {
  471. }
  472. soong_namespace {
  473. }
  474. `,
  475. }),
  476. ).
  477. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:4:5: namespace dir1 already exists\E`)).
  478. RunTest(t)
  479. }
  480. func TestNamespaceNotAtTopOfFile(t *testing.T) {
  481. GroupFixturePreparers(
  482. prepareForTestWithNamespace,
  483. dirBpToPreparer(map[string]string{
  484. "dir1": `
  485. test_module {
  486. name: "a"
  487. }
  488. soong_namespace {
  489. }
  490. `,
  491. }),
  492. ).
  493. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:5:5: a namespace must be the first module in the file\E`)).
  494. RunTest(t)
  495. }
  496. func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) {
  497. GroupFixturePreparers(
  498. prepareForTestWithNamespace,
  499. dirBpToPreparer(map[string]string{
  500. "dir1": `
  501. soong_namespace {
  502. }
  503. test_module {
  504. name: "a"
  505. }
  506. test_module {
  507. name: "a"
  508. }
  509. `,
  510. }),
  511. ).
  512. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(`\Qdir1/Android.bp:7:5: module "a" already defined
  513. dir1/Android.bp:4:5 <-- previous definition here\E`)).
  514. RunTest(t)
  515. }
  516. func TestDeclaringNamespaceInNonAndroidBpFile(t *testing.T) {
  517. GroupFixturePreparers(
  518. prepareForTestWithNamespace,
  519. FixtureWithRootAndroidBp(`
  520. build = ["include.bp"]
  521. `),
  522. FixtureAddTextFile("include.bp", `
  523. soong_namespace {
  524. }
  525. `),
  526. ).
  527. ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(
  528. `\Qinclude.bp:2:5: A namespace may only be declared in a file named Android.bp\E`,
  529. )).
  530. RunTest(t)
  531. }
  532. // so that the generated .ninja file will have consistent names
  533. func TestConsistentNamespaceNames(t *testing.T) {
  534. result := GroupFixturePreparers(
  535. prepareForTestWithNamespace,
  536. dirBpToPreparer(map[string]string{
  537. "dir1": "soong_namespace{}",
  538. "dir2": "soong_namespace{}",
  539. "dir3": "soong_namespace{}",
  540. }),
  541. ).RunTest(t)
  542. ns1, _ := result.NameResolver.namespaceAt("dir1")
  543. ns2, _ := result.NameResolver.namespaceAt("dir2")
  544. ns3, _ := result.NameResolver.namespaceAt("dir3")
  545. actualIds := []string{ns1.id, ns2.id, ns3.id}
  546. expectedIds := []string{"1", "2", "3"}
  547. if !reflect.DeepEqual(actualIds, expectedIds) {
  548. t.Errorf("Incorrect namespace ids.\nactual: %s\nexpected: %s\n", actualIds, expectedIds)
  549. }
  550. }
  551. // so that the generated .ninja file will have consistent names
  552. func TestRename(t *testing.T) {
  553. GroupFixturePreparers(
  554. prepareForTestWithNamespace,
  555. dirBpToPreparer(map[string]string{
  556. "dir1": `
  557. soong_namespace {
  558. }
  559. test_module {
  560. name: "a",
  561. deps: ["c"],
  562. }
  563. test_module {
  564. name: "b",
  565. rename: "c",
  566. }
  567. `,
  568. }),
  569. ).RunTest(t)
  570. // RunTest will report any errors
  571. }
  572. func TestNamespace_Exports(t *testing.T) {
  573. result := GroupFixturePreparers(
  574. prepareForTestWithNamespace,
  575. FixtureModifyProductVariables(func(variables FixtureProductVariables) {
  576. variables.NamespacesToExport = []string{"dir1"}
  577. }),
  578. dirBpToPreparer(map[string]string{
  579. "dir1": `
  580. soong_namespace {
  581. }
  582. test_module {
  583. name: "a",
  584. }
  585. `,
  586. "dir2": `
  587. soong_namespace {
  588. }
  589. test_module {
  590. name: "b",
  591. }
  592. `,
  593. }),
  594. ).RunTest(t)
  595. aModule := result.Module("a", "")
  596. AssertBoolEquals(t, "a exported", true, aModule.ExportedToMake())
  597. bModule := result.Module("b", "")
  598. AssertBoolEquals(t, "b not exported", false, bModule.ExportedToMake())
  599. }
  600. // some utils to support the tests
  601. var prepareForTestWithNamespace = GroupFixturePreparers(
  602. FixtureRegisterWithContext(registerNamespaceBuildComponents),
  603. FixtureRegisterWithContext(func(ctx RegistrationContext) {
  604. ctx.PreArchMutators(RegisterNamespaceMutator)
  605. }),
  606. FixtureModifyContext(func(ctx *TestContext) {
  607. ctx.RegisterModuleType("test_module", newTestModule)
  608. ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
  609. ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
  610. ctx.BottomUp("rename", renameMutator)
  611. })
  612. }),
  613. )
  614. // dirBpToPreparer takes a map from directory to the contents of the Android.bp file and produces a
  615. // FixturePreparer.
  616. func dirBpToPreparer(bps map[string]string) FixturePreparer {
  617. files := make(MockFS, len(bps))
  618. files["Android.bp"] = []byte("")
  619. for dir, text := range bps {
  620. files[filepath.Join(dir, "Android.bp")] = []byte(text)
  621. }
  622. return files.AddToFixture()
  623. }
  624. func dependsOn(result *TestResult, module TestingModule, possibleDependency TestingModule) bool {
  625. depends := false
  626. visit := func(dependency blueprint.Module) {
  627. if dependency == possibleDependency.module {
  628. depends = true
  629. }
  630. }
  631. result.VisitDirectDeps(module.module, visit)
  632. return depends
  633. }
  634. func numDeps(result *TestResult, module TestingModule) int {
  635. count := 0
  636. visit := func(dependency blueprint.Module) {
  637. count++
  638. }
  639. result.VisitDirectDeps(module.module, visit)
  640. return count
  641. }
  642. func getModule(result *TestResult, moduleName string) TestingModule {
  643. return result.ModuleForTests(moduleName, "")
  644. }
  645. func findModuleById(result *TestResult, id string) (module TestingModule) {
  646. visit := func(candidate blueprint.Module) {
  647. testModule, ok := candidate.(*testModule)
  648. if ok {
  649. if testModule.properties.Id == id {
  650. module = newTestingModule(result.config, testModule)
  651. }
  652. }
  653. }
  654. result.VisitAllModules(visit)
  655. return module
  656. }
  657. type testModule struct {
  658. ModuleBase
  659. properties struct {
  660. Rename string
  661. Deps []string
  662. Id string
  663. }
  664. }
  665. func (m *testModule) DepsMutator(ctx BottomUpMutatorContext) {
  666. if m.properties.Rename != "" {
  667. ctx.Rename(m.properties.Rename)
  668. }
  669. for _, d := range m.properties.Deps {
  670. ctx.AddDependency(ctx.Module(), nil, d)
  671. }
  672. }
  673. func (m *testModule) GenerateAndroidBuildActions(ModuleContext) {
  674. }
  675. func renameMutator(ctx BottomUpMutatorContext) {
  676. if m, ok := ctx.Module().(*testModule); ok {
  677. if m.properties.Rename != "" {
  678. ctx.Rename(m.properties.Rename)
  679. }
  680. }
  681. }
  682. func newTestModule() Module {
  683. m := &testModule{}
  684. m.AddProperties(&m.properties)
  685. InitAndroidModule(m)
  686. return m
  687. }
  688. type blueprintTestModule struct {
  689. blueprint.SimpleName
  690. properties struct {
  691. Deps []string
  692. }
  693. }
  694. func (b *blueprintTestModule) DynamicDependencies(_ blueprint.DynamicDependerModuleContext) []string {
  695. return b.properties.Deps
  696. }
  697. func (b *blueprintTestModule) GenerateBuildActions(blueprint.ModuleContext) {
  698. }
  699. func newBlueprintTestModule() (blueprint.Module, []interface{}) {
  700. m := &blueprintTestModule{}
  701. return m, []interface{}{&m.properties, &m.SimpleName.Properties}
  702. }