variable_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. "reflect"
  17. "strconv"
  18. "testing"
  19. "github.com/google/blueprint/proptools"
  20. )
  21. type printfIntoPropertyTestCase struct {
  22. in string
  23. val interface{}
  24. out string
  25. err bool
  26. }
  27. var printfIntoPropertyTestCases = []printfIntoPropertyTestCase{
  28. {
  29. in: "%d",
  30. val: 0,
  31. out: "0",
  32. },
  33. {
  34. in: "%d",
  35. val: 1,
  36. out: "1",
  37. },
  38. {
  39. in: "%d",
  40. val: 2,
  41. out: "2",
  42. },
  43. {
  44. in: "%d",
  45. val: false,
  46. out: "0",
  47. },
  48. {
  49. in: "%d",
  50. val: true,
  51. out: "1",
  52. },
  53. {
  54. in: "%d",
  55. val: -1,
  56. out: "-1",
  57. },
  58. {
  59. in: "-DA=%d",
  60. val: 1,
  61. out: "-DA=1",
  62. },
  63. {
  64. in: "-DA=%du",
  65. val: 1,
  66. out: "-DA=1u",
  67. },
  68. {
  69. in: "-DA=%s",
  70. val: "abc",
  71. out: "-DA=abc",
  72. },
  73. {
  74. in: `-DA="%s"`,
  75. val: "abc",
  76. out: `-DA="abc"`,
  77. },
  78. {
  79. in: "%%",
  80. err: true,
  81. },
  82. {
  83. in: "%d%s",
  84. err: true,
  85. },
  86. {
  87. in: "%d,%s",
  88. err: true,
  89. },
  90. {
  91. in: "%d",
  92. val: "",
  93. err: true,
  94. },
  95. {
  96. in: "%d",
  97. val: 1.5,
  98. err: true,
  99. },
  100. {
  101. in: "%f",
  102. val: 1.5,
  103. err: true,
  104. },
  105. }
  106. func TestPrintfIntoProperty(t *testing.T) {
  107. for _, testCase := range printfIntoPropertyTestCases {
  108. s := testCase.in
  109. v := reflect.ValueOf(&s).Elem()
  110. err := printfIntoProperty(v, testCase.val)
  111. if err != nil && !testCase.err {
  112. t.Errorf("unexpected error %s", err)
  113. } else if err == nil && testCase.err {
  114. t.Errorf("expected error")
  115. } else if err == nil && v.String() != testCase.out {
  116. t.Errorf("expected %q got %q", testCase.out, v.String())
  117. }
  118. }
  119. }
  120. type testProductVariableModule struct {
  121. ModuleBase
  122. }
  123. func (m *testProductVariableModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  124. }
  125. var testProductVariableProperties = struct {
  126. Product_variables struct {
  127. Eng struct {
  128. Srcs []string
  129. Cflags []string
  130. }
  131. }
  132. }{}
  133. func testProductVariableModuleFactoryFactory(props interface{}) func() Module {
  134. return func() Module {
  135. m := &testProductVariableModule{}
  136. clonedProps := proptools.CloneProperties(reflect.ValueOf(props)).Interface()
  137. m.AddProperties(clonedProps)
  138. // Set a default soongConfigVariableProperties, this will be used as the input to the property struct filter
  139. // for this test module.
  140. m.variableProperties = testProductVariableProperties
  141. InitAndroidModule(m)
  142. return m
  143. }
  144. }
  145. func TestProductVariables(t *testing.T) {
  146. // Test that a module can use one product variable even if it doesn't have all the properties
  147. // supported by that product variable.
  148. bp := `
  149. module1 {
  150. name: "foo",
  151. product_variables: {
  152. eng: {
  153. srcs: ["foo.c"],
  154. },
  155. },
  156. }
  157. module2 {
  158. name: "bar",
  159. product_variables: {
  160. eng: {
  161. cflags: ["-DBAR"],
  162. },
  163. },
  164. }
  165. module3 {
  166. name: "baz",
  167. }
  168. `
  169. GroupFixturePreparers(
  170. FixtureModifyProductVariables(func(variables FixtureProductVariables) {
  171. variables.Eng = proptools.BoolPtr(true)
  172. }),
  173. FixtureRegisterWithContext(func(ctx RegistrationContext) {
  174. // A module type that has a srcs property but not a cflags property.
  175. ctx.RegisterModuleType("module1", testProductVariableModuleFactoryFactory(&struct {
  176. Srcs []string
  177. }{}))
  178. // A module type that has a cflags property but not a srcs property.
  179. ctx.RegisterModuleType("module2", testProductVariableModuleFactoryFactory(&struct {
  180. Cflags []string
  181. }{}))
  182. // A module type that does not have any properties that match product_variables.
  183. ctx.RegisterModuleType("module3", testProductVariableModuleFactoryFactory(&struct {
  184. Foo []string
  185. }{}))
  186. ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
  187. ctx.BottomUp("variable", VariableMutator).Parallel()
  188. })
  189. }),
  190. FixtureWithRootAndroidBp(bp),
  191. ).RunTest(t)
  192. }
  193. var testProductVariableDefaultsProperties = struct {
  194. Product_variables struct {
  195. Eng struct {
  196. Foo []string
  197. Bar []string
  198. }
  199. }
  200. }{}
  201. type productVariablesDefaultsTestProperties struct {
  202. Foo []string
  203. }
  204. type productVariablesDefaultsTestProperties2 struct {
  205. Foo []string
  206. Bar []string
  207. }
  208. type productVariablesDefaultsTestModule struct {
  209. ModuleBase
  210. DefaultableModuleBase
  211. properties productVariablesDefaultsTestProperties
  212. }
  213. func (d *productVariablesDefaultsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
  214. ctx.Build(pctx, BuildParams{
  215. Rule: Touch,
  216. Output: PathForModuleOut(ctx, "out"),
  217. })
  218. }
  219. func productVariablesDefaultsTestModuleFactory() Module {
  220. module := &productVariablesDefaultsTestModule{}
  221. module.AddProperties(&module.properties)
  222. module.variableProperties = testProductVariableDefaultsProperties
  223. InitAndroidModule(module)
  224. InitDefaultableModule(module)
  225. return module
  226. }
  227. type productVariablesDefaultsTestDefaults struct {
  228. ModuleBase
  229. DefaultsModuleBase
  230. }
  231. func productVariablesDefaultsTestDefaultsFactory() Module {
  232. defaults := &productVariablesDefaultsTestDefaults{}
  233. defaults.AddProperties(&productVariablesDefaultsTestProperties{})
  234. defaults.AddProperties(&productVariablesDefaultsTestProperties2{})
  235. defaults.variableProperties = testProductVariableDefaultsProperties
  236. InitDefaultsModule(defaults)
  237. return defaults
  238. }
  239. // Test a defaults module that supports more product variable properties than the target module.
  240. func TestProductVariablesDefaults(t *testing.T) {
  241. bp := `
  242. defaults {
  243. name: "defaults",
  244. product_variables: {
  245. eng: {
  246. foo: ["product_variable_defaults"],
  247. bar: ["product_variable_defaults"],
  248. },
  249. },
  250. foo: ["defaults"],
  251. bar: ["defaults"],
  252. }
  253. test {
  254. name: "foo",
  255. defaults: ["defaults"],
  256. foo: ["module"],
  257. product_variables: {
  258. eng: {
  259. foo: ["product_variable_module"],
  260. },
  261. },
  262. }
  263. `
  264. result := GroupFixturePreparers(
  265. FixtureModifyProductVariables(func(variables FixtureProductVariables) {
  266. variables.Eng = boolPtr(true)
  267. }),
  268. PrepareForTestWithDefaults,
  269. PrepareForTestWithVariables,
  270. FixtureRegisterWithContext(func(ctx RegistrationContext) {
  271. ctx.RegisterModuleType("test", productVariablesDefaultsTestModuleFactory)
  272. ctx.RegisterModuleType("defaults", productVariablesDefaultsTestDefaultsFactory)
  273. }),
  274. FixtureWithRootAndroidBp(bp),
  275. ).RunTest(t)
  276. foo := result.ModuleForTests("foo", "").Module().(*productVariablesDefaultsTestModule)
  277. want := []string{"defaults", "module", "product_variable_defaults", "product_variable_module"}
  278. AssertDeepEquals(t, "foo", want, foo.properties.Foo)
  279. }
  280. func BenchmarkSliceToTypeArray(b *testing.B) {
  281. for _, n := range []int{1, 2, 4, 8, 100} {
  282. var propStructs []interface{}
  283. for i := 0; i < n; i++ {
  284. propStructs = append(propStructs, &struct {
  285. A *string
  286. B string
  287. }{})
  288. }
  289. b.Run(strconv.Itoa(n), func(b *testing.B) {
  290. for i := 0; i < b.N; i++ {
  291. _ = sliceToTypeArray(propStructs)
  292. }
  293. })
  294. }
  295. }