properties_test.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. // Copyright 2021 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 bazel
  15. import (
  16. "reflect"
  17. "strings"
  18. "testing"
  19. "github.com/google/blueprint/proptools"
  20. )
  21. func TestUniqueBazelLabels(t *testing.T) {
  22. testCases := []struct {
  23. originalLabels []Label
  24. expectedUniqueLabels []Label
  25. }{
  26. {
  27. originalLabels: []Label{
  28. {Label: "a"},
  29. {Label: "b"},
  30. {Label: "a"},
  31. {Label: "c"},
  32. },
  33. expectedUniqueLabels: []Label{
  34. {Label: "a"},
  35. {Label: "b"},
  36. {Label: "c"},
  37. },
  38. },
  39. }
  40. for _, tc := range testCases {
  41. actualUniqueLabels := UniqueSortedBazelLabels(tc.originalLabels)
  42. if !reflect.DeepEqual(tc.expectedUniqueLabels, actualUniqueLabels) {
  43. t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabels, actualUniqueLabels)
  44. }
  45. }
  46. }
  47. func TestSubtractStrings(t *testing.T) {
  48. testCases := []struct {
  49. haystack []string
  50. needle []string
  51. expectedResult []string
  52. }{
  53. {
  54. haystack: []string{
  55. "a",
  56. "b",
  57. "c",
  58. },
  59. needle: []string{
  60. "a",
  61. },
  62. expectedResult: []string{
  63. "b", "c",
  64. },
  65. },
  66. }
  67. for _, tc := range testCases {
  68. actualResult := SubtractStrings(tc.haystack, tc.needle)
  69. if !reflect.DeepEqual(tc.expectedResult, actualResult) {
  70. t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
  71. }
  72. }
  73. }
  74. func TestSubtractBazelLabelList(t *testing.T) {
  75. testCases := []struct {
  76. haystack LabelList
  77. needle LabelList
  78. expectedResult LabelList
  79. }{
  80. {
  81. haystack: LabelList{
  82. Includes: []Label{
  83. {Label: "a"},
  84. {Label: "b"},
  85. {Label: "c"},
  86. },
  87. Excludes: []Label{
  88. {Label: "x"},
  89. {Label: "y"},
  90. {Label: "z"},
  91. },
  92. },
  93. needle: LabelList{
  94. Includes: []Label{
  95. {Label: "a"},
  96. },
  97. Excludes: []Label{
  98. {Label: "z"},
  99. },
  100. },
  101. // NOTE: Excludes are intentionally not subtracted
  102. expectedResult: LabelList{
  103. Includes: []Label{
  104. {Label: "b"},
  105. {Label: "c"},
  106. },
  107. Excludes: []Label{
  108. {Label: "x"},
  109. {Label: "y"},
  110. {Label: "z"},
  111. },
  112. },
  113. },
  114. }
  115. for _, tc := range testCases {
  116. actualResult := SubtractBazelLabelList(tc.haystack, tc.needle)
  117. if !reflect.DeepEqual(tc.expectedResult, actualResult) {
  118. t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
  119. }
  120. }
  121. }
  122. func TestFirstUniqueBazelLabelList(t *testing.T) {
  123. testCases := []struct {
  124. originalLabelList LabelList
  125. expectedUniqueLabelList LabelList
  126. }{
  127. {
  128. originalLabelList: LabelList{
  129. Includes: []Label{
  130. {Label: "a"},
  131. {Label: "b"},
  132. {Label: "a"},
  133. {Label: "c"},
  134. },
  135. Excludes: []Label{
  136. {Label: "x"},
  137. {Label: "x"},
  138. {Label: "y"},
  139. {Label: "z"},
  140. },
  141. },
  142. expectedUniqueLabelList: LabelList{
  143. Includes: []Label{
  144. {Label: "a"},
  145. {Label: "b"},
  146. {Label: "c"},
  147. },
  148. Excludes: []Label{
  149. {Label: "x"},
  150. {Label: "y"},
  151. {Label: "z"},
  152. },
  153. },
  154. },
  155. }
  156. for _, tc := range testCases {
  157. actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList)
  158. if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
  159. t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
  160. }
  161. }
  162. }
  163. func TestUniqueSortedBazelLabelList(t *testing.T) {
  164. testCases := []struct {
  165. originalLabelList LabelList
  166. expectedUniqueLabelList LabelList
  167. }{
  168. {
  169. originalLabelList: LabelList{
  170. Includes: []Label{
  171. {Label: "c"},
  172. {Label: "a"},
  173. {Label: "a"},
  174. {Label: "b"},
  175. },
  176. Excludes: []Label{
  177. {Label: "y"},
  178. {Label: "z"},
  179. {Label: "x"},
  180. {Label: "x"},
  181. },
  182. },
  183. expectedUniqueLabelList: LabelList{
  184. Includes: []Label{
  185. {Label: "a"},
  186. {Label: "b"},
  187. {Label: "c"},
  188. },
  189. Excludes: []Label{
  190. {Label: "x"},
  191. {Label: "y"},
  192. {Label: "z"},
  193. },
  194. },
  195. },
  196. }
  197. for _, tc := range testCases {
  198. actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList)
  199. if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
  200. t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
  201. }
  202. }
  203. }
  204. func makeLabels(labels ...string) []Label {
  205. var ret []Label
  206. for _, l := range labels {
  207. ret = append(ret, Label{Label: l})
  208. }
  209. return ret
  210. }
  211. func makeLabelList(includes, excludes []string) LabelList {
  212. return LabelList{
  213. Includes: makeLabels(includes...),
  214. Excludes: makeLabels(excludes...),
  215. }
  216. }
  217. func TestResolveExcludes(t *testing.T) {
  218. attr := LabelListAttribute{
  219. Value: makeLabelList(
  220. []string{
  221. "all_include",
  222. "arm_exclude",
  223. "android_exclude",
  224. },
  225. []string{"all_exclude"},
  226. ),
  227. ConfigurableValues: configurableLabelLists{
  228. ArchConfigurationAxis: labelListSelectValues{
  229. "arm": makeLabelList([]string{}, []string{"arm_exclude"}),
  230. "x86": makeLabelList([]string{"x86_include"}, []string{}),
  231. ConditionsDefaultConfigKey: makeLabelList([]string{"default_include"}, []string{}),
  232. },
  233. OsConfigurationAxis: labelListSelectValues{
  234. "android": makeLabelList([]string{}, []string{"android_exclude"}),
  235. "linux": makeLabelList([]string{"linux_include"}, []string{}),
  236. },
  237. OsArchConfigurationAxis: labelListSelectValues{
  238. "linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
  239. },
  240. ProductVariableConfigurationAxis("product_with_defaults", NoConfigAxis): labelListSelectValues{
  241. "a": makeLabelList([]string{}, []string{"not_in_value"}),
  242. "b": makeLabelList([]string{"b_val"}, []string{}),
  243. "c": makeLabelList([]string{"c_val"}, []string{}),
  244. ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2"}, []string{}),
  245. },
  246. ProductVariableConfigurationAxis("product_only_with_excludes", NoConfigAxis): labelListSelectValues{
  247. "a": makeLabelList([]string{}, []string{"not_in_value"}),
  248. },
  249. },
  250. }
  251. attr.ResolveExcludes()
  252. expectedBaseIncludes := []Label{{Label: "all_include"}}
  253. if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
  254. t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
  255. }
  256. var nilLabels []Label
  257. expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
  258. ArchConfigurationAxis: {
  259. "arm": nilLabels,
  260. "x86": makeLabels("arm_exclude", "x86_include"),
  261. ConditionsDefaultConfigKey: makeLabels("arm_exclude", "default_include"),
  262. },
  263. OsConfigurationAxis: {
  264. "android": nilLabels,
  265. "linux": makeLabels("android_exclude", "linux_include"),
  266. ConditionsDefaultConfigKey: makeLabels("android_exclude"),
  267. },
  268. OsArchConfigurationAxis: {
  269. "linux_x86": makeLabels("linux_x86_include"),
  270. ConditionsDefaultConfigKey: nilLabels,
  271. },
  272. ProductVariableConfigurationAxis("product_with_defaults", NoConfigAxis): {
  273. "a": nilLabels,
  274. "b": makeLabels("b_val"),
  275. "c": makeLabels("c_val"),
  276. ConditionsDefaultConfigKey: makeLabels("c_val", "default", "default2"),
  277. },
  278. }
  279. for _, axis := range attr.SortedConfigurationAxes() {
  280. if _, ok := expectedConfiguredIncludes[axis]; !ok {
  281. t.Errorf("Found unexpected axis %s", axis)
  282. continue
  283. }
  284. expectedForAxis := expectedConfiguredIncludes[axis]
  285. gotForAxis := attr.ConfigurableValues[axis]
  286. if len(expectedForAxis) != len(gotForAxis) {
  287. t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
  288. }
  289. for config, value := range gotForAxis {
  290. if expected, ok := expectedForAxis[config]; ok {
  291. if !reflect.DeepEqual(expected, value.Includes) {
  292. t.Errorf("For %s,\nexpected: %#v\ngot %#v", axis, expected, value.Includes)
  293. }
  294. } else {
  295. t.Errorf("Got unexpected config %q for %s", config, axis)
  296. }
  297. }
  298. }
  299. }
  300. func TestLabelListAttributePartition(t *testing.T) {
  301. testCases := []struct {
  302. name string
  303. input LabelListAttribute
  304. predicated LabelListAttribute
  305. unpredicated LabelListAttribute
  306. predicate func(label Label) bool
  307. }{
  308. {
  309. name: "move all to predicated partition",
  310. input: MakeLabelListAttribute(makeLabelList(
  311. []string{"keep1", "throw1", "keep2", "throw2"},
  312. []string{"keep1", "throw1", "keep2", "throw2"},
  313. )),
  314. predicated: MakeLabelListAttribute(makeLabelList(
  315. []string{"keep1", "throw1", "keep2", "throw2"},
  316. []string{"keep1", "throw1", "keep2", "throw2"},
  317. )),
  318. unpredicated: LabelListAttribute{},
  319. predicate: func(label Label) bool {
  320. return true
  321. },
  322. },
  323. {
  324. name: "move all to unpredicated partition",
  325. input: MakeLabelListAttribute(makeLabelList(
  326. []string{"keep1", "throw1", "keep2", "throw2"},
  327. []string{"keep1", "throw1", "keep2", "throw2"},
  328. )),
  329. predicated: LabelListAttribute{},
  330. unpredicated: MakeLabelListAttribute(makeLabelList(
  331. []string{"keep1", "throw1", "keep2", "throw2"},
  332. []string{"keep1", "throw1", "keep2", "throw2"},
  333. )),
  334. predicate: func(label Label) bool {
  335. return false
  336. },
  337. },
  338. {
  339. name: "partition includes and excludes",
  340. input: MakeLabelListAttribute(makeLabelList(
  341. []string{"keep1", "throw1", "keep2", "throw2"},
  342. []string{"keep1", "throw1", "keep2", "throw2"},
  343. )),
  344. predicated: MakeLabelListAttribute(makeLabelList(
  345. []string{"keep1", "keep2"},
  346. []string{"keep1", "keep2"},
  347. )),
  348. unpredicated: MakeLabelListAttribute(makeLabelList(
  349. []string{"throw1", "throw2"},
  350. []string{"throw1", "throw2"},
  351. )),
  352. predicate: func(label Label) bool {
  353. return strings.HasPrefix(label.Label, "keep")
  354. },
  355. },
  356. {
  357. name: "partition excludes only",
  358. input: MakeLabelListAttribute(makeLabelList(
  359. []string{},
  360. []string{"keep1", "throw1", "keep2", "throw2"},
  361. )),
  362. predicated: MakeLabelListAttribute(makeLabelList(
  363. []string{},
  364. []string{"keep1", "keep2"},
  365. )),
  366. unpredicated: MakeLabelListAttribute(makeLabelList(
  367. []string{},
  368. []string{"throw1", "throw2"},
  369. )),
  370. predicate: func(label Label) bool {
  371. return strings.HasPrefix(label.Label, "keep")
  372. },
  373. },
  374. {
  375. name: "partition includes only",
  376. input: MakeLabelListAttribute(makeLabelList(
  377. []string{"keep1", "throw1", "keep2", "throw2"},
  378. []string{},
  379. )),
  380. predicated: MakeLabelListAttribute(makeLabelList(
  381. []string{"keep1", "keep2"},
  382. []string{},
  383. )),
  384. unpredicated: MakeLabelListAttribute(makeLabelList(
  385. []string{"throw1", "throw2"},
  386. []string{},
  387. )),
  388. predicate: func(label Label) bool {
  389. return strings.HasPrefix(label.Label, "keep")
  390. },
  391. },
  392. {
  393. name: "empty partition",
  394. input: MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
  395. predicated: LabelListAttribute{},
  396. unpredicated: LabelListAttribute{},
  397. predicate: func(label Label) bool {
  398. return true
  399. },
  400. },
  401. }
  402. for _, tc := range testCases {
  403. t.Run(tc.name, func(t *testing.T) {
  404. predicated, unpredicated := tc.input.Partition(tc.predicate)
  405. if !predicated.Value.Equals(tc.predicated.Value) {
  406. t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
  407. }
  408. for axis, configs := range predicated.ConfigurableValues {
  409. tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
  410. if !ok || !reflect.DeepEqual(configs, tcConfigs) {
  411. t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
  412. }
  413. }
  414. if !unpredicated.Value.Equals(tc.unpredicated.Value) {
  415. t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
  416. }
  417. for axis, configs := range unpredicated.ConfigurableValues {
  418. tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
  419. if !ok || !reflect.DeepEqual(configs, tcConfigs) {
  420. t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
  421. }
  422. }
  423. })
  424. }
  425. }
  426. // labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
  427. // typ
  428. func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
  429. return func(omc OtherModuleContext, label Label) (string, bool) {
  430. m, ok := omc.ModuleFromName(label.Label)
  431. if !ok {
  432. return label.Label, false
  433. }
  434. mTyp := omc.OtherModuleType(m)
  435. if typ == mTyp {
  436. return label.Label + suffix, true
  437. }
  438. return label.Label, false
  439. }
  440. }
  441. func TestPartitionLabelListAttribute(t *testing.T) {
  442. testCases := []struct {
  443. name string
  444. ctx *OtherModuleTestContext
  445. labelList LabelListAttribute
  446. filters LabelPartitions
  447. expected PartitionToLabelListAttribute
  448. expectedErrMsg *string
  449. }{
  450. {
  451. name: "no configurable values",
  452. ctx: &OtherModuleTestContext{},
  453. labelList: LabelListAttribute{
  454. Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
  455. },
  456. filters: LabelPartitions{
  457. "A": LabelPartition{Extensions: []string{".a"}},
  458. "B": LabelPartition{Extensions: []string{".b"}},
  459. "C": LabelPartition{Extensions: []string{".c"}},
  460. },
  461. expected: PartitionToLabelListAttribute{
  462. "A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
  463. "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
  464. "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
  465. },
  466. },
  467. {
  468. name: "no configurable values, remainder partition",
  469. ctx: &OtherModuleTestContext{},
  470. labelList: LabelListAttribute{
  471. Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
  472. },
  473. filters: LabelPartitions{
  474. "A": LabelPartition{Extensions: []string{".a"}, Keep_remainder: true},
  475. "B": LabelPartition{Extensions: []string{".b"}},
  476. "C": LabelPartition{Extensions: []string{".c"}},
  477. },
  478. expected: PartitionToLabelListAttribute{
  479. "A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "d.d", "e.e"}, []string{})},
  480. "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
  481. "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
  482. },
  483. },
  484. {
  485. name: "no configurable values, empty partition",
  486. ctx: &OtherModuleTestContext{},
  487. labelList: LabelListAttribute{
  488. Value: makeLabelList([]string{"a.a", "c.c"}, []string{}),
  489. },
  490. filters: LabelPartitions{
  491. "A": LabelPartition{Extensions: []string{".a"}},
  492. "B": LabelPartition{Extensions: []string{".b"}},
  493. "C": LabelPartition{Extensions: []string{".c"}},
  494. },
  495. expected: PartitionToLabelListAttribute{
  496. "A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
  497. "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
  498. },
  499. },
  500. {
  501. name: "no configurable values, has map",
  502. ctx: &OtherModuleTestContext{
  503. Modules: []TestModuleInfo{{ModuleName: "srcs", Typ: "fg", Dir: "dir"}},
  504. },
  505. labelList: LabelListAttribute{
  506. Value: makeLabelList([]string{"a.a", "srcs", "b.b", "c.c"}, []string{}),
  507. },
  508. filters: LabelPartitions{
  509. "A": LabelPartition{Extensions: []string{".a"}, LabelMapper: labelAddSuffixForTypeMapper("_a", "fg")},
  510. "B": LabelPartition{Extensions: []string{".b"}},
  511. "C": LabelPartition{Extensions: []string{".c"}},
  512. },
  513. expected: PartitionToLabelListAttribute{
  514. "A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "srcs_a"}, []string{})},
  515. "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
  516. "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
  517. },
  518. },
  519. {
  520. name: "configurable values, keeps empty if excludes",
  521. ctx: &OtherModuleTestContext{},
  522. labelList: LabelListAttribute{
  523. ConfigurableValues: configurableLabelLists{
  524. ArchConfigurationAxis: labelListSelectValues{
  525. "x86": makeLabelList([]string{"a.a", "c.c"}, []string{}),
  526. "arm": makeLabelList([]string{"b.b"}, []string{}),
  527. "x86_64": makeLabelList([]string{"b.b"}, []string{"d.d"}),
  528. },
  529. },
  530. },
  531. filters: LabelPartitions{
  532. "A": LabelPartition{Extensions: []string{".a"}},
  533. "B": LabelPartition{Extensions: []string{".b"}},
  534. "C": LabelPartition{Extensions: []string{".c"}},
  535. },
  536. expected: PartitionToLabelListAttribute{
  537. "A": LabelListAttribute{
  538. ConfigurableValues: configurableLabelLists{
  539. ArchConfigurationAxis: labelListSelectValues{
  540. "x86": makeLabelList([]string{"a.a"}, []string{}),
  541. "x86_64": makeLabelList([]string{}, []string{"c.c"}),
  542. },
  543. },
  544. },
  545. "B": LabelListAttribute{
  546. ConfigurableValues: configurableLabelLists{
  547. ArchConfigurationAxis: labelListSelectValues{
  548. "arm": makeLabelList([]string{"b.b"}, []string{}),
  549. "x86_64": makeLabelList([]string{"b.b"}, []string{"c.c"}),
  550. },
  551. },
  552. },
  553. "C": LabelListAttribute{
  554. ConfigurableValues: configurableLabelLists{
  555. ArchConfigurationAxis: labelListSelectValues{
  556. "x86": makeLabelList([]string{"c.c"}, []string{}),
  557. "x86_64": makeLabelList([]string{}, []string{"c.c"}),
  558. },
  559. },
  560. },
  561. },
  562. },
  563. {
  564. name: "error for multiple partitions same value",
  565. ctx: &OtherModuleTestContext{},
  566. labelList: LabelListAttribute{
  567. Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
  568. },
  569. filters: LabelPartitions{
  570. "A": LabelPartition{Extensions: []string{".a"}},
  571. "other A": LabelPartition{Extensions: []string{".a"}},
  572. },
  573. expected: PartitionToLabelListAttribute{},
  574. expectedErrMsg: proptools.StringPtr(`"a.a" was found in multiple partitions:`),
  575. },
  576. }
  577. for _, tc := range testCases {
  578. t.Run(tc.name, func(t *testing.T) {
  579. got := PartitionLabelListAttribute(tc.ctx, &tc.labelList, tc.filters)
  580. if hasErrors, expectsErr := len(tc.ctx.errors) > 0, tc.expectedErrMsg != nil; hasErrors != expectsErr {
  581. t.Errorf("Unexpected error(s): %q, expected: %q", tc.ctx.errors, *tc.expectedErrMsg)
  582. } else if tc.expectedErrMsg != nil {
  583. found := false
  584. for _, err := range tc.ctx.errors {
  585. if strings.Contains(err, *tc.expectedErrMsg) {
  586. found = true
  587. break
  588. }
  589. }
  590. if !found {
  591. t.Errorf("Expected error message: %q, got %q", *tc.expectedErrMsg, tc.ctx.errors)
  592. }
  593. return
  594. }
  595. if len(tc.expected) != len(got) {
  596. t.Errorf("Expected %d partitions, got %d partitions", len(tc.expected), len(got))
  597. }
  598. for partition, expectedLla := range tc.expected {
  599. gotLla, ok := got[partition]
  600. if !ok {
  601. t.Errorf("Expected partition %q, but it was not found %v", partition, got)
  602. continue
  603. }
  604. expectedLabelList := expectedLla.Value
  605. gotLabelList := gotLla.Value
  606. if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
  607. t.Errorf("Expected no config includes %v, got %v", expectedLabelList.Includes, gotLabelList.Includes)
  608. }
  609. expectedAxes := expectedLla.SortedConfigurationAxes()
  610. gotAxes := gotLla.SortedConfigurationAxes()
  611. if !reflect.DeepEqual(expectedAxes, gotAxes) {
  612. t.Errorf("Expected axes %v, got %v (%#v)", expectedAxes, gotAxes, gotLla)
  613. }
  614. for _, axis := range expectedLla.SortedConfigurationAxes() {
  615. if _, exists := gotLla.ConfigurableValues[axis]; !exists {
  616. t.Errorf("Expected %s to be a supported axis, but it was not found", axis)
  617. }
  618. if expected, got := expectedLla.ConfigurableValues[axis], gotLla.ConfigurableValues[axis]; len(expected) != len(got) {
  619. t.Errorf("For axis %q: expected configs %v, got %v", axis, expected, got)
  620. }
  621. for config, expectedLabelList := range expectedLla.ConfigurableValues[axis] {
  622. gotLabelList, exists := gotLla.ConfigurableValues[axis][config]
  623. if !exists {
  624. t.Errorf("Expected %s to be a supported config, but config was not found", config)
  625. continue
  626. }
  627. if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
  628. t.Errorf("Expected %s %s includes %v, got %v", axis, config, expectedLabelList.Includes, gotLabelList.Includes)
  629. }
  630. }
  631. }
  632. }
  633. })
  634. }
  635. }
  636. func TestDeduplicateAxesFromBase(t *testing.T) {
  637. attr := StringListAttribute{
  638. Value: []string{
  639. "all_include",
  640. "arm_include",
  641. "android_include",
  642. "linux_x86_include",
  643. },
  644. ConfigurableValues: configurableStringLists{
  645. ArchConfigurationAxis: stringListSelectValues{
  646. "arm": []string{"arm_include"},
  647. "x86": []string{"x86_include"},
  648. },
  649. OsConfigurationAxis: stringListSelectValues{
  650. "android": []string{"android_include"},
  651. "linux": []string{"linux_include"},
  652. },
  653. OsArchConfigurationAxis: stringListSelectValues{
  654. "linux_x86": {"linux_x86_include"},
  655. },
  656. ProductVariableConfigurationAxis("a", NoConfigAxis): stringListSelectValues{
  657. "a": []string{"not_in_value"},
  658. },
  659. },
  660. }
  661. attr.DeduplicateAxesFromBase()
  662. expectedBaseIncludes := []string{
  663. "all_include",
  664. "arm_include",
  665. "android_include",
  666. "linux_x86_include",
  667. }
  668. if !reflect.DeepEqual(expectedBaseIncludes, attr.Value) {
  669. t.Errorf("Expected Value includes %q, got %q", attr.Value, expectedBaseIncludes)
  670. }
  671. expectedConfiguredIncludes := configurableStringLists{
  672. ArchConfigurationAxis: stringListSelectValues{
  673. "x86": []string{"x86_include"},
  674. },
  675. OsConfigurationAxis: stringListSelectValues{
  676. "linux": []string{"linux_include"},
  677. },
  678. OsArchConfigurationAxis: stringListSelectValues{},
  679. ProductVariableConfigurationAxis("a", NoConfigAxis): stringListSelectValues{
  680. "a": []string{"not_in_value"},
  681. },
  682. }
  683. for _, axis := range attr.SortedConfigurationAxes() {
  684. if _, ok := expectedConfiguredIncludes[axis]; !ok {
  685. t.Errorf("Found unexpected axis %s", axis)
  686. continue
  687. }
  688. expectedForAxis := expectedConfiguredIncludes[axis]
  689. gotForAxis := attr.ConfigurableValues[axis]
  690. if len(expectedForAxis) != len(gotForAxis) {
  691. t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
  692. }
  693. for config, value := range gotForAxis {
  694. if expected, ok := expectedForAxis[config]; ok {
  695. if !reflect.DeepEqual(expected, value) {
  696. t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value)
  697. }
  698. } else {
  699. t.Errorf("Got unexpected config %q for %s", config, axis)
  700. }
  701. }
  702. }
  703. }