prebuilt_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. // Copyright 2016 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. "fmt"
  17. "testing"
  18. "github.com/google/blueprint"
  19. )
  20. func TestPrebuilts(t *testing.T) {
  21. buildOS := TestArchConfig(t.TempDir(), nil, "", nil).BuildOS
  22. var prebuiltsTests = []struct {
  23. name string
  24. replaceBp bool // modules is added to default bp boilerplate if false.
  25. modules string
  26. prebuilt []OsType
  27. preparer FixturePreparer
  28. }{
  29. {
  30. name: "no prebuilt",
  31. modules: `
  32. source {
  33. name: "bar",
  34. }`,
  35. prebuilt: nil,
  36. },
  37. {
  38. name: "no source prebuilt not preferred",
  39. modules: `
  40. prebuilt {
  41. name: "bar",
  42. prefer: false,
  43. srcs: ["prebuilt_file"],
  44. }`,
  45. prebuilt: []OsType{Android, buildOS},
  46. },
  47. {
  48. name: "no source prebuilt preferred",
  49. modules: `
  50. prebuilt {
  51. name: "bar",
  52. prefer: true,
  53. srcs: ["prebuilt_file"],
  54. }`,
  55. prebuilt: []OsType{Android, buildOS},
  56. },
  57. {
  58. name: "prebuilt not preferred",
  59. modules: `
  60. source {
  61. name: "bar",
  62. }
  63. prebuilt {
  64. name: "bar",
  65. prefer: false,
  66. srcs: ["prebuilt_file"],
  67. }`,
  68. prebuilt: nil,
  69. },
  70. {
  71. name: "prebuilt preferred",
  72. modules: `
  73. source {
  74. name: "bar",
  75. }
  76. prebuilt {
  77. name: "bar",
  78. prefer: true,
  79. srcs: ["prebuilt_file"],
  80. }`,
  81. prebuilt: []OsType{Android, buildOS},
  82. },
  83. {
  84. name: "prebuilt no file not preferred",
  85. modules: `
  86. source {
  87. name: "bar",
  88. }
  89. prebuilt {
  90. name: "bar",
  91. prefer: false,
  92. }`,
  93. prebuilt: nil,
  94. },
  95. {
  96. name: "prebuilt no file preferred",
  97. modules: `
  98. source {
  99. name: "bar",
  100. }
  101. prebuilt {
  102. name: "bar",
  103. prefer: true,
  104. }`,
  105. prebuilt: nil,
  106. },
  107. {
  108. name: "prebuilt file from filegroup preferred",
  109. modules: `
  110. filegroup {
  111. name: "fg",
  112. srcs: ["prebuilt_file"],
  113. }
  114. prebuilt {
  115. name: "bar",
  116. prefer: true,
  117. srcs: [":fg"],
  118. }`,
  119. prebuilt: []OsType{Android, buildOS},
  120. },
  121. {
  122. name: "prebuilt module for device only",
  123. modules: `
  124. source {
  125. name: "bar",
  126. }
  127. prebuilt {
  128. name: "bar",
  129. host_supported: false,
  130. prefer: true,
  131. srcs: ["prebuilt_file"],
  132. }`,
  133. prebuilt: []OsType{Android},
  134. },
  135. {
  136. name: "prebuilt file for host only",
  137. modules: `
  138. source {
  139. name: "bar",
  140. }
  141. prebuilt {
  142. name: "bar",
  143. prefer: true,
  144. target: {
  145. host: {
  146. srcs: ["prebuilt_file"],
  147. },
  148. },
  149. }`,
  150. prebuilt: []OsType{buildOS},
  151. },
  152. {
  153. name: "prebuilt override not preferred",
  154. modules: `
  155. source {
  156. name: "baz",
  157. }
  158. override_source {
  159. name: "bar",
  160. base: "baz",
  161. }
  162. prebuilt {
  163. name: "bar",
  164. prefer: false,
  165. srcs: ["prebuilt_file"],
  166. }`,
  167. prebuilt: nil,
  168. },
  169. {
  170. name: "prebuilt override preferred",
  171. modules: `
  172. source {
  173. name: "baz",
  174. }
  175. override_source {
  176. name: "bar",
  177. base: "baz",
  178. }
  179. prebuilt {
  180. name: "bar",
  181. prefer: true,
  182. srcs: ["prebuilt_file"],
  183. }`,
  184. prebuilt: []OsType{Android, buildOS},
  185. },
  186. {
  187. name: "prebuilt including default-disabled OS",
  188. replaceBp: true,
  189. modules: `
  190. source {
  191. name: "foo",
  192. deps: [":bar"],
  193. target: {
  194. windows: {
  195. enabled: true,
  196. },
  197. },
  198. }
  199. source {
  200. name: "bar",
  201. target: {
  202. windows: {
  203. enabled: true,
  204. },
  205. },
  206. }
  207. prebuilt {
  208. name: "bar",
  209. prefer: true,
  210. srcs: ["prebuilt_file"],
  211. target: {
  212. windows: {
  213. enabled: true,
  214. },
  215. },
  216. }`,
  217. prebuilt: []OsType{Android, buildOS, Windows},
  218. },
  219. {
  220. name: "fall back to source for default-disabled OS",
  221. replaceBp: true,
  222. modules: `
  223. source {
  224. name: "foo",
  225. deps: [":bar"],
  226. target: {
  227. windows: {
  228. enabled: true,
  229. },
  230. },
  231. }
  232. source {
  233. name: "bar",
  234. target: {
  235. windows: {
  236. enabled: true,
  237. },
  238. },
  239. }
  240. prebuilt {
  241. name: "bar",
  242. prefer: true,
  243. srcs: ["prebuilt_file"],
  244. }`,
  245. prebuilt: []OsType{Android, buildOS},
  246. },
  247. {
  248. name: "prebuilt properties customizable",
  249. replaceBp: true,
  250. modules: `
  251. source {
  252. name: "foo",
  253. deps: [":bar"],
  254. }
  255. soong_config_module_type {
  256. name: "prebuilt_with_config",
  257. module_type: "prebuilt",
  258. config_namespace: "any_namespace",
  259. bool_variables: ["bool_var"],
  260. properties: ["prefer"],
  261. }
  262. prebuilt_with_config {
  263. name: "bar",
  264. prefer: true,
  265. srcs: ["prebuilt_file"],
  266. soong_config_variables: {
  267. bool_var: {
  268. prefer: false,
  269. conditions_default: {
  270. prefer: true,
  271. },
  272. },
  273. },
  274. }`,
  275. prebuilt: []OsType{Android, buildOS},
  276. },
  277. {
  278. name: "prebuilt use_source_config_var={acme, use_source} - no var specified",
  279. modules: `
  280. source {
  281. name: "bar",
  282. }
  283. prebuilt {
  284. name: "bar",
  285. use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
  286. srcs: ["prebuilt_file"],
  287. }`,
  288. // When use_source_env is specified then it will use the prebuilt by default if the environment
  289. // variable is not set.
  290. prebuilt: []OsType{Android, buildOS},
  291. },
  292. {
  293. name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false",
  294. modules: `
  295. source {
  296. name: "bar",
  297. }
  298. prebuilt {
  299. name: "bar",
  300. use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
  301. srcs: ["prebuilt_file"],
  302. }`,
  303. preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
  304. variables.VendorVars = map[string]map[string]string{
  305. "acme": {
  306. "use_source": "false",
  307. },
  308. }
  309. }),
  310. // Setting the environment variable named in use_source_env to false will cause the prebuilt to
  311. // be used.
  312. prebuilt: []OsType{Android, buildOS},
  313. },
  314. {
  315. name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
  316. modules: `
  317. source {
  318. name: "bar",
  319. }
  320. prebuilt {
  321. name: "bar",
  322. use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
  323. srcs: ["prebuilt_file"],
  324. }`,
  325. preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
  326. variables.VendorVars = map[string]map[string]string{
  327. "acme": {
  328. "use_source": "true",
  329. },
  330. }
  331. }),
  332. // Setting the environment variable named in use_source_env to true will cause the source to be
  333. // used.
  334. prebuilt: nil,
  335. },
  336. {
  337. name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source",
  338. modules: `
  339. prebuilt {
  340. name: "bar",
  341. use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
  342. srcs: ["prebuilt_file"],
  343. }`,
  344. preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
  345. variables.VendorVars = map[string]map[string]string{
  346. "acme": {
  347. "use_source": "true",
  348. },
  349. }
  350. }),
  351. // Although the environment variable says to use source there is no source available.
  352. prebuilt: []OsType{Android, buildOS},
  353. },
  354. }
  355. fs := MockFS{
  356. "prebuilt_file": nil,
  357. "source_file": nil,
  358. }
  359. for _, test := range prebuiltsTests {
  360. t.Run(test.name, func(t *testing.T) {
  361. bp := test.modules
  362. if !test.replaceBp {
  363. bp = bp + `
  364. source {
  365. name: "foo",
  366. deps: [":bar"],
  367. }`
  368. }
  369. // Add windows to the target list to test the logic when a variant is
  370. // disabled by default.
  371. if !Windows.DefaultDisabled {
  372. t.Errorf("windows is assumed to be disabled by default")
  373. }
  374. result := GroupFixturePreparers(
  375. PrepareForTestWithArchMutator,
  376. PrepareForTestWithPrebuilts,
  377. PrepareForTestWithOverrides,
  378. PrepareForTestWithFilegroup,
  379. // Add a Windows target to the configuration.
  380. FixtureModifyConfig(func(config Config) {
  381. config.Targets[Windows] = []Target{
  382. {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true},
  383. }
  384. }),
  385. fs.AddToFixture(),
  386. FixtureRegisterWithContext(registerTestPrebuiltModules),
  387. OptionalFixturePreparer(test.preparer),
  388. ).RunTestWithBp(t, bp)
  389. for _, variant := range result.ModuleVariantsForTests("foo") {
  390. foo := result.ModuleForTests("foo", variant)
  391. t.Run(foo.Module().Target().Os.String(), func(t *testing.T) {
  392. var dependsOnSourceModule, dependsOnPrebuiltModule bool
  393. result.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
  394. if _, ok := m.(*sourceModule); ok {
  395. dependsOnSourceModule = true
  396. }
  397. if p, ok := m.(*prebuiltModule); ok {
  398. dependsOnPrebuiltModule = true
  399. if !p.Prebuilt().properties.UsePrebuilt {
  400. t.Errorf("dependency on prebuilt module not marked used")
  401. }
  402. }
  403. })
  404. moduleIsDisabled := !foo.Module().Enabled()
  405. deps := foo.Module().(*sourceModule).deps
  406. if moduleIsDisabled {
  407. if len(deps) > 0 {
  408. t.Errorf("disabled module got deps: %v", deps)
  409. }
  410. } else {
  411. if len(deps) != 1 {
  412. t.Errorf("deps does not have single path, but is %v", deps)
  413. }
  414. }
  415. var usingSourceFile, usingPrebuiltFile bool
  416. if len(deps) > 0 && deps[0].String() == "source_file" {
  417. usingSourceFile = true
  418. }
  419. if len(deps) > 0 && deps[0].String() == "prebuilt_file" {
  420. usingPrebuiltFile = true
  421. }
  422. prebuilt := false
  423. for _, os := range test.prebuilt {
  424. if os == foo.Module().Target().Os {
  425. prebuilt = true
  426. }
  427. }
  428. if prebuilt {
  429. if moduleIsDisabled {
  430. t.Errorf("dependent module for prebuilt is disabled")
  431. }
  432. if !dependsOnPrebuiltModule {
  433. t.Errorf("doesn't depend on prebuilt module")
  434. }
  435. if !usingPrebuiltFile {
  436. t.Errorf("doesn't use prebuilt_file")
  437. }
  438. if dependsOnSourceModule {
  439. t.Errorf("depends on source module")
  440. }
  441. if usingSourceFile {
  442. t.Errorf("using source_file")
  443. }
  444. } else if !moduleIsDisabled {
  445. if dependsOnPrebuiltModule {
  446. t.Errorf("depends on prebuilt module")
  447. }
  448. if usingPrebuiltFile {
  449. t.Errorf("using prebuilt_file")
  450. }
  451. if !dependsOnSourceModule {
  452. t.Errorf("doesn't depend on source module")
  453. }
  454. if !usingSourceFile {
  455. t.Errorf("doesn't use source_file")
  456. }
  457. }
  458. })
  459. }
  460. })
  461. }
  462. }
  463. func testPrebuiltError(t *testing.T, expectedError, bp string) {
  464. t.Helper()
  465. fs := MockFS{
  466. "prebuilt_file": nil,
  467. }
  468. GroupFixturePreparers(
  469. PrepareForTestWithArchMutator,
  470. PrepareForTestWithPrebuilts,
  471. PrepareForTestWithOverrides,
  472. fs.AddToFixture(),
  473. FixtureRegisterWithContext(registerTestPrebuiltModules),
  474. ).
  475. ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(expectedError)).
  476. RunTestWithBp(t, bp)
  477. }
  478. func TestPrebuiltShouldNotChangePartition(t *testing.T) {
  479. testPrebuiltError(t, `partition is different`, `
  480. source {
  481. name: "foo",
  482. vendor: true,
  483. }
  484. prebuilt {
  485. name: "foo",
  486. prefer: true,
  487. srcs: ["prebuilt_file"],
  488. }`)
  489. }
  490. func TestPrebuiltShouldNotChangePartition_WithOverride(t *testing.T) {
  491. testPrebuiltError(t, `partition is different`, `
  492. source {
  493. name: "foo",
  494. vendor: true,
  495. }
  496. override_source {
  497. name: "bar",
  498. base: "foo",
  499. }
  500. prebuilt {
  501. name: "bar",
  502. prefer: true,
  503. srcs: ["prebuilt_file"],
  504. }`)
  505. }
  506. func registerTestPrebuiltBuildComponents(ctx RegistrationContext) {
  507. registerTestPrebuiltModules(ctx)
  508. RegisterPrebuiltMutators(ctx)
  509. ctx.PostDepsMutators(RegisterOverridePostDepsMutators)
  510. }
  511. var prepareForTestWithFakePrebuiltModules = FixtureRegisterWithContext(registerTestPrebuiltModules)
  512. func registerTestPrebuiltModules(ctx RegistrationContext) {
  513. ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
  514. ctx.RegisterModuleType("source", newSourceModule)
  515. ctx.RegisterModuleType("override_source", newOverrideSourceModule)
  516. ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
  517. ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
  518. ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
  519. }
  520. type prebuiltModule struct {
  521. ModuleBase
  522. prebuilt Prebuilt
  523. properties struct {
  524. Srcs []string `android:"path,arch_variant"`
  525. }
  526. src Path
  527. }
  528. func newPrebuiltModule() Module {
  529. m := &prebuiltModule{}
  530. m.AddProperties(&m.properties)
  531. InitPrebuiltModule(m, &m.properties.Srcs)
  532. InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
  533. return m
  534. }
  535. func (p *prebuiltModule) Name() string {
  536. return p.prebuilt.Name(p.ModuleBase.Name())
  537. }
  538. func (p *prebuiltModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  539. if len(p.properties.Srcs) >= 1 {
  540. p.src = p.prebuilt.SingleSourcePath(ctx)
  541. }
  542. }
  543. func (p *prebuiltModule) Prebuilt() *Prebuilt {
  544. return &p.prebuilt
  545. }
  546. func (p *prebuiltModule) OutputFiles(tag string) (Paths, error) {
  547. switch tag {
  548. case "":
  549. return Paths{p.src}, nil
  550. default:
  551. return nil, fmt.Errorf("unsupported module reference tag %q", tag)
  552. }
  553. }
  554. type sourceModuleProperties struct {
  555. Deps []string `android:"path,arch_variant"`
  556. }
  557. type sourceModule struct {
  558. ModuleBase
  559. OverridableModuleBase
  560. properties sourceModuleProperties
  561. dependsOnSourceModule, dependsOnPrebuiltModule bool
  562. deps Paths
  563. src Path
  564. }
  565. func newSourceModule() Module {
  566. m := &sourceModule{}
  567. m.AddProperties(&m.properties)
  568. InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
  569. InitOverridableModule(m, nil)
  570. return m
  571. }
  572. func (s *sourceModule) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
  573. // s.properties.Deps are annotated with android:path, so they are
  574. // automatically added to the dependency by pathDeps mutator
  575. }
  576. func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  577. s.deps = PathsForModuleSrc(ctx, s.properties.Deps)
  578. s.src = PathForModuleSrc(ctx, "source_file")
  579. }
  580. func (s *sourceModule) Srcs() Paths {
  581. return Paths{s.src}
  582. }
  583. type overrideSourceModule struct {
  584. ModuleBase
  585. OverrideModuleBase
  586. }
  587. func (o *overrideSourceModule) GenerateAndroidBuildActions(_ ModuleContext) {
  588. }
  589. func newOverrideSourceModule() Module {
  590. m := &overrideSourceModule{}
  591. m.AddProperties(&sourceModuleProperties{})
  592. InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
  593. InitOverrideModule(m)
  594. return m
  595. }