namespace_test.go 15 KB

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