mutator_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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. "fmt"
  17. "reflect"
  18. "strings"
  19. "testing"
  20. "github.com/google/blueprint"
  21. "github.com/google/blueprint/proptools"
  22. )
  23. type mutatorTestModule struct {
  24. ModuleBase
  25. props struct {
  26. Deps_missing_deps []string
  27. Mutator_missing_deps []string
  28. }
  29. missingDeps []string
  30. }
  31. func mutatorTestModuleFactory() Module {
  32. module := &mutatorTestModule{}
  33. module.AddProperties(&module.props)
  34. InitAndroidModule(module)
  35. return module
  36. }
  37. func (m *mutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  38. ctx.Build(pctx, BuildParams{
  39. Rule: Touch,
  40. Output: PathForModuleOut(ctx, "output"),
  41. })
  42. m.missingDeps = ctx.GetMissingDependencies()
  43. }
  44. func (m *mutatorTestModule) DepsMutator(ctx BottomUpMutatorContext) {
  45. ctx.AddDependency(ctx.Module(), nil, m.props.Deps_missing_deps...)
  46. }
  47. func addMissingDependenciesMutator(ctx TopDownMutatorContext) {
  48. ctx.AddMissingDependencies(ctx.Module().(*mutatorTestModule).props.Mutator_missing_deps)
  49. }
  50. func TestMutatorAddMissingDependencies(t *testing.T) {
  51. bp := `
  52. test {
  53. name: "foo",
  54. deps_missing_deps: ["regular_missing_dep"],
  55. mutator_missing_deps: ["added_missing_dep"],
  56. }
  57. `
  58. config := TestConfig(buildDir, nil, bp, nil)
  59. config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
  60. ctx := NewTestContext()
  61. ctx.SetAllowMissingDependencies(true)
  62. ctx.RegisterModuleType("test", mutatorTestModuleFactory)
  63. ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
  64. ctx.TopDown("add_missing_dependencies", addMissingDependenciesMutator)
  65. })
  66. ctx.Register(config)
  67. _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
  68. FailIfErrored(t, errs)
  69. _, errs = ctx.PrepareBuildActions(config)
  70. FailIfErrored(t, errs)
  71. foo := ctx.ModuleForTests("foo", "").Module().(*mutatorTestModule)
  72. if g, w := foo.missingDeps, []string{"added_missing_dep", "regular_missing_dep"}; !reflect.DeepEqual(g, w) {
  73. t.Errorf("want foo missing deps %q, got %q", w, g)
  74. }
  75. }
  76. func TestModuleString(t *testing.T) {
  77. ctx := NewTestContext()
  78. var moduleStrings []string
  79. ctx.PreArchMutators(func(ctx RegisterMutatorsContext) {
  80. ctx.BottomUp("pre_arch", func(ctx BottomUpMutatorContext) {
  81. moduleStrings = append(moduleStrings, ctx.Module().String())
  82. ctx.CreateVariations("a", "b")
  83. })
  84. ctx.TopDown("rename_top_down", func(ctx TopDownMutatorContext) {
  85. moduleStrings = append(moduleStrings, ctx.Module().String())
  86. ctx.Rename(ctx.Module().base().Name() + "_renamed1")
  87. })
  88. })
  89. ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
  90. ctx.BottomUp("pre_deps", func(ctx BottomUpMutatorContext) {
  91. moduleStrings = append(moduleStrings, ctx.Module().String())
  92. ctx.CreateVariations("c", "d")
  93. })
  94. })
  95. ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
  96. ctx.BottomUp("post_deps", func(ctx BottomUpMutatorContext) {
  97. moduleStrings = append(moduleStrings, ctx.Module().String())
  98. ctx.CreateLocalVariations("e", "f")
  99. })
  100. ctx.BottomUp("rename_bottom_up", func(ctx BottomUpMutatorContext) {
  101. moduleStrings = append(moduleStrings, ctx.Module().String())
  102. ctx.Rename(ctx.Module().base().Name() + "_renamed2")
  103. })
  104. ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
  105. moduleStrings = append(moduleStrings, ctx.Module().String())
  106. })
  107. })
  108. ctx.RegisterModuleType("test", mutatorTestModuleFactory)
  109. bp := `
  110. test {
  111. name: "foo",
  112. }
  113. `
  114. config := TestConfig(buildDir, nil, bp, nil)
  115. ctx.Register(config)
  116. _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
  117. FailIfErrored(t, errs)
  118. _, errs = ctx.PrepareBuildActions(config)
  119. FailIfErrored(t, errs)
  120. want := []string{
  121. // Initial name.
  122. "foo{}",
  123. // After pre_arch (reversed because rename_top_down is TopDown so it visits in reverse order).
  124. "foo{pre_arch:b}",
  125. "foo{pre_arch:a}",
  126. // After rename_top_down.
  127. "foo_renamed1{pre_arch:a}",
  128. "foo_renamed1{pre_arch:b}",
  129. // After pre_deps.
  130. "foo_renamed1{pre_arch:a,pre_deps:c}",
  131. "foo_renamed1{pre_arch:a,pre_deps:d}",
  132. "foo_renamed1{pre_arch:b,pre_deps:c}",
  133. "foo_renamed1{pre_arch:b,pre_deps:d}",
  134. // After post_deps.
  135. "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:e}",
  136. "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:f}",
  137. "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:e}",
  138. "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:f}",
  139. "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:e}",
  140. "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:f}",
  141. "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:e}",
  142. "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:f}",
  143. // After rename_bottom_up.
  144. "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:e}",
  145. "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:f}",
  146. "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:e}",
  147. "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:f}",
  148. "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:e}",
  149. "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:f}",
  150. "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:e}",
  151. "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:f}",
  152. }
  153. if !reflect.DeepEqual(moduleStrings, want) {
  154. t.Errorf("want module String() values:\n%q\ngot:\n%q", want, moduleStrings)
  155. }
  156. }
  157. func TestFinalDepsPhase(t *testing.T) {
  158. ctx := NewTestContext()
  159. finalGot := map[string]int{}
  160. dep1Tag := struct {
  161. blueprint.BaseDependencyTag
  162. }{}
  163. dep2Tag := struct {
  164. blueprint.BaseDependencyTag
  165. }{}
  166. ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
  167. ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
  168. if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
  169. ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
  170. }
  171. })
  172. ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) {
  173. ctx.CreateLocalVariations("a", "b")
  174. })
  175. })
  176. ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
  177. ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
  178. if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
  179. ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
  180. }
  181. })
  182. ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
  183. finalGot[ctx.Module().String()] += 1
  184. ctx.VisitDirectDeps(func(mod Module) {
  185. finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1
  186. })
  187. })
  188. })
  189. ctx.RegisterModuleType("test", mutatorTestModuleFactory)
  190. bp := `
  191. test {
  192. name: "common_dep_1",
  193. }
  194. test {
  195. name: "common_dep_2",
  196. }
  197. test {
  198. name: "foo",
  199. }
  200. `
  201. config := TestConfig(buildDir, nil, bp, nil)
  202. ctx.Register(config)
  203. _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
  204. FailIfErrored(t, errs)
  205. _, errs = ctx.PrepareBuildActions(config)
  206. FailIfErrored(t, errs)
  207. finalWant := map[string]int{
  208. "common_dep_1{variant:a}": 1,
  209. "common_dep_1{variant:b}": 1,
  210. "common_dep_2{variant:a}": 1,
  211. "common_dep_2{variant:b}": 1,
  212. "foo{variant:a}": 1,
  213. "foo{variant:a} -> common_dep_1{variant:a}": 1,
  214. "foo{variant:a} -> common_dep_2{variant:a}": 1,
  215. "foo{variant:b}": 1,
  216. "foo{variant:b} -> common_dep_1{variant:b}": 1,
  217. "foo{variant:b} -> common_dep_2{variant:a}": 1,
  218. }
  219. if !reflect.DeepEqual(finalWant, finalGot) {
  220. t.Errorf("want:\n%q\ngot:\n%q", finalWant, finalGot)
  221. }
  222. }
  223. func TestNoCreateVariationsInFinalDeps(t *testing.T) {
  224. ctx := NewTestContext()
  225. checkErr := func() {
  226. if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") {
  227. panic("Expected FinalDepsMutators consistency check to fail")
  228. }
  229. }
  230. ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
  231. ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) {
  232. defer checkErr()
  233. ctx.CreateVariations("a", "b")
  234. })
  235. ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) {
  236. defer checkErr()
  237. ctx.CreateLocalVariations("a", "b")
  238. })
  239. })
  240. ctx.RegisterModuleType("test", mutatorTestModuleFactory)
  241. config := TestConfig(buildDir, nil, `test {name: "foo"}`, nil)
  242. ctx.Register(config)
  243. _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
  244. FailIfErrored(t, errs)
  245. _, errs = ctx.PrepareBuildActions(config)
  246. FailIfErrored(t, errs)
  247. }