blob: 751cb8b307c94ea370bf60842d7485806b2d125f [file] [log] [blame]
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +00001// 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
15package bazel
16
17import (
18 "reflect"
Liz Kammer57e2e7a2021-09-20 12:55:02 -040019 "strings"
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000020 "testing"
Liz Kammer57e2e7a2021-09-20 12:55:02 -040021
22 "github.com/google/blueprint/proptools"
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000023)
24
25func TestUniqueBazelLabels(t *testing.T) {
26 testCases := []struct {
27 originalLabels []Label
28 expectedUniqueLabels []Label
29 }{
30 {
31 originalLabels: []Label{
32 {Label: "a"},
33 {Label: "b"},
34 {Label: "a"},
35 {Label: "c"},
Spandan Das5e04d482023-08-16 20:45:39 +000036 // namespaces
37 {Label: "//foo:bar", OriginalModuleName: "bar"}, // when referenced from foo namespace
38 {Label: "//foo:bar", OriginalModuleName: "//foo:bar"}, // when reference from root namespace
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000039 },
40 expectedUniqueLabels: []Label{
Spandan Das5e04d482023-08-16 20:45:39 +000041 {Label: "//foo:bar", OriginalModuleName: "bar"},
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000042 {Label: "a"},
43 {Label: "b"},
44 {Label: "c"},
45 },
46 },
47 }
48 for _, tc := range testCases {
Jingwen Chened9c17d2021-04-13 07:14:55 +000049 actualUniqueLabels := UniqueSortedBazelLabels(tc.originalLabels)
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000050 if !reflect.DeepEqual(tc.expectedUniqueLabels, actualUniqueLabels) {
51 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabels, actualUniqueLabels)
52 }
53 }
54}
55
Rupert Shuttleworthb8151682021-04-06 20:06:21 +000056func TestSubtractStrings(t *testing.T) {
57 testCases := []struct {
58 haystack []string
59 needle []string
60 expectedResult []string
61 }{
62 {
63 haystack: []string{
64 "a",
65 "b",
66 "c",
67 },
68 needle: []string{
69 "a",
70 },
71 expectedResult: []string{
72 "b", "c",
73 },
74 },
75 }
76 for _, tc := range testCases {
77 actualResult := SubtractStrings(tc.haystack, tc.needle)
78 if !reflect.DeepEqual(tc.expectedResult, actualResult) {
79 t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
80 }
81 }
82}
83
84func TestSubtractBazelLabelList(t *testing.T) {
85 testCases := []struct {
86 haystack LabelList
87 needle LabelList
88 expectedResult LabelList
89 }{
90 {
91 haystack: LabelList{
92 Includes: []Label{
93 {Label: "a"},
94 {Label: "b"},
95 {Label: "c"},
96 },
97 Excludes: []Label{
98 {Label: "x"},
99 {Label: "y"},
100 {Label: "z"},
101 },
102 },
103 needle: LabelList{
104 Includes: []Label{
105 {Label: "a"},
106 },
107 Excludes: []Label{
108 {Label: "z"},
109 },
110 },
111 // NOTE: Excludes are intentionally not subtracted
112 expectedResult: LabelList{
113 Includes: []Label{
114 {Label: "b"},
115 {Label: "c"},
116 },
117 Excludes: []Label{
118 {Label: "x"},
119 {Label: "y"},
120 {Label: "z"},
121 },
122 },
123 },
124 }
125 for _, tc := range testCases {
126 actualResult := SubtractBazelLabelList(tc.haystack, tc.needle)
127 if !reflect.DeepEqual(tc.expectedResult, actualResult) {
128 t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
129 }
130 }
131}
Liz Kammer5f5dbaa2023-07-17 17:44:08 -0400132
133func TestSubtractBazelLabelListAttribute(t *testing.T) {
134 testCases := []struct {
135 haystack LabelListAttribute
136 needle LabelListAttribute
137 expected LabelListAttribute
138 }{
139 {
140 haystack: LabelListAttribute{
141 Value: makeLabelList(
142 []string{"a", "b", "a", "c"},
143 []string{"x", "x", "y", "z"},
144 ),
145 ConfigurableValues: configurableLabelLists{
146 ArchConfigurationAxis: labelListSelectValues{
147 "arm": makeLabelList([]string{"arm_1", "arm_2"}, []string{}),
148 "x86": makeLabelList([]string{"x86_3", "x86_4", "x86_5"}, []string{"x86_5"}),
149 },
150 },
151 },
152 needle: LabelListAttribute{
153 Value: makeLabelList(
154 []string{"d", "a"},
155 []string{"x", "y2", "z2"},
156 ),
157 ConfigurableValues: configurableLabelLists{
158 ArchConfigurationAxis: labelListSelectValues{
159 "arm": makeLabelList([]string{"arm_1", "arm_3"}, []string{}),
160 "x86": makeLabelList([]string{"x86_3", "x86_4"}, []string{"x86_6"}),
161 },
162 },
163 },
164 expected: LabelListAttribute{
165 Value: makeLabelList(
166 []string{"b", "c"},
167 []string{"x", "x", "y", "z"},
168 ),
169 ConfigurableValues: configurableLabelLists{
170 ArchConfigurationAxis: labelListSelectValues{
171 "arm": makeLabelList([]string{"arm_2"}, []string{}),
172 "x86": makeLabelList([]string{"x86_5"}, []string{"x86_5"}),
173 },
174 },
175 ForceSpecifyEmptyList: false,
176 EmitEmptyList: false,
177 Prepend: false,
178 },
179 },
180 }
181 for _, tc := range testCases {
182 got := SubtractBazelLabelListAttribute(tc.haystack, tc.needle)
183 if !reflect.DeepEqual(tc.expected, got) {
184 t.Fatalf("Expected\n%v, but got\n%v", tc.expected, got)
185 }
186 }
187}
188
Liz Kammer9abd62d2021-05-21 08:37:59 -0400189func TestFirstUniqueBazelLabelList(t *testing.T) {
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000190 testCases := []struct {
191 originalLabelList LabelList
192 expectedUniqueLabelList LabelList
193 }{
194 {
195 originalLabelList: LabelList{
196 Includes: []Label{
197 {Label: "a"},
198 {Label: "b"},
199 {Label: "a"},
200 {Label: "c"},
Spandan Das5e04d482023-08-16 20:45:39 +0000201 // namespaces
202 {Label: "//foo:bar", OriginalModuleName: "bar"}, // when referenced from foo namespace
203 {Label: "//foo:bar", OriginalModuleName: "//foo:bar"}, // when referenced from root namespace
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000204 },
205 Excludes: []Label{
206 {Label: "x"},
207 {Label: "x"},
208 {Label: "y"},
209 {Label: "z"},
210 },
211 },
212 expectedUniqueLabelList: LabelList{
213 Includes: []Label{
214 {Label: "a"},
215 {Label: "b"},
216 {Label: "c"},
Spandan Das5e04d482023-08-16 20:45:39 +0000217 {Label: "//foo:bar", OriginalModuleName: "bar"},
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000218 },
219 Excludes: []Label{
220 {Label: "x"},
221 {Label: "y"},
222 {Label: "z"},
223 },
224 },
225 },
226 }
227 for _, tc := range testCases {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400228 actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList)
229 if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
230 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
231 }
232 }
233}
234
Liz Kammer5f5dbaa2023-07-17 17:44:08 -0400235func TestFirstUniqueBazelLabelListAttribute(t *testing.T) {
236 testCases := []struct {
237 originalLabelList LabelListAttribute
238 expectedUniqueLabelList LabelListAttribute
239 }{
240 {
241 originalLabelList: LabelListAttribute{
242 Value: makeLabelList(
243 []string{"a", "b", "a", "c"},
244 []string{"x", "x", "y", "z"},
245 ),
246 ConfigurableValues: configurableLabelLists{
247 ArchConfigurationAxis: labelListSelectValues{
248 "arm": makeLabelList([]string{"1", "2", "1"}, []string{}),
249 "x86": makeLabelList([]string{"3", "4", "4"}, []string{"5", "5"}),
250 },
251 },
252 },
253 expectedUniqueLabelList: LabelListAttribute{
254 Value: makeLabelList(
255 []string{"a", "b", "c"},
256 []string{"x", "y", "z"},
257 ),
258 ConfigurableValues: configurableLabelLists{
259 ArchConfigurationAxis: labelListSelectValues{
260 "arm": makeLabelList([]string{"1", "2"}, []string{}),
261 "x86": makeLabelList([]string{"3", "4"}, []string{"5"}),
262 },
263 },
264 },
265 },
266 }
267 for _, tc := range testCases {
268 actualUniqueLabelList := FirstUniqueBazelLabelListAttribute(tc.originalLabelList)
269 if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
270 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
271 }
272 }
273}
274
Liz Kammer9abd62d2021-05-21 08:37:59 -0400275func TestUniqueSortedBazelLabelList(t *testing.T) {
276 testCases := []struct {
277 originalLabelList LabelList
278 expectedUniqueLabelList LabelList
279 }{
280 {
281 originalLabelList: LabelList{
282 Includes: []Label{
283 {Label: "c"},
284 {Label: "a"},
285 {Label: "a"},
286 {Label: "b"},
287 },
288 Excludes: []Label{
289 {Label: "y"},
290 {Label: "z"},
291 {Label: "x"},
292 {Label: "x"},
293 },
294 },
295 expectedUniqueLabelList: LabelList{
296 Includes: []Label{
297 {Label: "a"},
298 {Label: "b"},
299 {Label: "c"},
300 },
301 Excludes: []Label{
302 {Label: "x"},
303 {Label: "y"},
304 {Label: "z"},
305 },
306 },
307 },
308 }
309 for _, tc := range testCases {
310 actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList)
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000311 if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
312 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
313 }
314 }
315}
Liz Kammer74deed42021-06-02 13:02:03 -0400316
317func makeLabels(labels ...string) []Label {
318 var ret []Label
319 for _, l := range labels {
320 ret = append(ret, Label{Label: l})
321 }
322 return ret
323}
324
325func makeLabelList(includes, excludes []string) LabelList {
326 return LabelList{
327 Includes: makeLabels(includes...),
328 Excludes: makeLabels(excludes...),
329 }
330}
331
332func TestResolveExcludes(t *testing.T) {
333 attr := LabelListAttribute{
334 Value: makeLabelList(
335 []string{
336 "all_include",
337 "arm_exclude",
338 "android_exclude",
Liz Kammer748d7072023-01-25 12:07:43 -0500339 "product_config_exclude",
Liz Kammer74deed42021-06-02 13:02:03 -0400340 },
341 []string{"all_exclude"},
342 ),
343 ConfigurableValues: configurableLabelLists{
344 ArchConfigurationAxis: labelListSelectValues{
Jingwen Chen9af49a42021-11-02 10:27:17 +0000345 "arm": makeLabelList([]string{}, []string{"arm_exclude"}),
346 "x86": makeLabelList([]string{"x86_include"}, []string{}),
347 ConditionsDefaultConfigKey: makeLabelList([]string{"default_include"}, []string{}),
Liz Kammer74deed42021-06-02 13:02:03 -0400348 },
349 OsConfigurationAxis: labelListSelectValues{
350 "android": makeLabelList([]string{}, []string{"android_exclude"}),
351 "linux": makeLabelList([]string{"linux_include"}, []string{}),
352 },
353 OsArchConfigurationAxis: labelListSelectValues{
354 "linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
355 },
Cole Faust150f9a52023-04-26 10:52:24 -0700356 ProductVariableConfigurationAxis(false, "product_with_defaults"): labelListSelectValues{
Jingwen Chen9af49a42021-11-02 10:27:17 +0000357 "a": makeLabelList([]string{}, []string{"not_in_value"}),
358 "b": makeLabelList([]string{"b_val"}, []string{}),
359 "c": makeLabelList([]string{"c_val"}, []string{}),
Liz Kammer748d7072023-01-25 12:07:43 -0500360 ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2", "all_exclude"}, []string{}),
Jingwen Chen9af49a42021-11-02 10:27:17 +0000361 },
Cole Faust150f9a52023-04-26 10:52:24 -0700362 ProductVariableConfigurationAxis(false, "product_only_with_excludes"): labelListSelectValues{
Liz Kammer748d7072023-01-25 12:07:43 -0500363 "a": makeLabelList([]string{}, []string{"product_config_exclude"}),
Liz Kammer74deed42021-06-02 13:02:03 -0400364 },
365 },
366 }
367
368 attr.ResolveExcludes()
369
Jingwen Chen9af49a42021-11-02 10:27:17 +0000370 expectedBaseIncludes := []Label{{Label: "all_include"}}
Liz Kammer74deed42021-06-02 13:02:03 -0400371 if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
372 t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
373 }
374 var nilLabels []Label
375 expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
Jingwen Chen9af49a42021-11-02 10:27:17 +0000376 ArchConfigurationAxis: {
377 "arm": nilLabels,
378 "x86": makeLabels("arm_exclude", "x86_include"),
379 ConditionsDefaultConfigKey: makeLabels("arm_exclude", "default_include"),
Liz Kammer74deed42021-06-02 13:02:03 -0400380 },
Jingwen Chen9af49a42021-11-02 10:27:17 +0000381 OsConfigurationAxis: {
382 "android": nilLabels,
383 "linux": makeLabels("android_exclude", "linux_include"),
384 ConditionsDefaultConfigKey: makeLabels("android_exclude"),
Liz Kammer74deed42021-06-02 13:02:03 -0400385 },
Jingwen Chen9af49a42021-11-02 10:27:17 +0000386 OsArchConfigurationAxis: {
387 "linux_x86": makeLabels("linux_x86_include"),
388 ConditionsDefaultConfigKey: nilLabels,
389 },
Cole Faust150f9a52023-04-26 10:52:24 -0700390 ProductVariableConfigurationAxis(false, "product_with_defaults"): {
Jingwen Chen9af49a42021-11-02 10:27:17 +0000391 "a": nilLabels,
392 "b": makeLabels("b_val"),
393 "c": makeLabels("c_val"),
394 ConditionsDefaultConfigKey: makeLabels("c_val", "default", "default2"),
Liz Kammer74deed42021-06-02 13:02:03 -0400395 },
Cole Faust150f9a52023-04-26 10:52:24 -0700396 ProductVariableConfigurationAxis(false, "product_only_with_excludes"): {
Liz Kammer748d7072023-01-25 12:07:43 -0500397 "a": nilLabels,
398 ConditionsDefaultConfigKey: makeLabels("product_config_exclude"),
399 },
Liz Kammer74deed42021-06-02 13:02:03 -0400400 }
401 for _, axis := range attr.SortedConfigurationAxes() {
402 if _, ok := expectedConfiguredIncludes[axis]; !ok {
403 t.Errorf("Found unexpected axis %s", axis)
404 continue
405 }
406 expectedForAxis := expectedConfiguredIncludes[axis]
407 gotForAxis := attr.ConfigurableValues[axis]
408 if len(expectedForAxis) != len(gotForAxis) {
409 t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
410 }
411 for config, value := range gotForAxis {
412 if expected, ok := expectedForAxis[config]; ok {
413 if !reflect.DeepEqual(expected, value.Includes) {
Jingwen Chen9af49a42021-11-02 10:27:17 +0000414 t.Errorf("For %s,\nexpected: %#v\ngot %#v", axis, expected, value.Includes)
Liz Kammer74deed42021-06-02 13:02:03 -0400415 }
416 } else {
417 t.Errorf("Got unexpected config %q for %s", config, axis)
418 }
419 }
420 }
421}
Liz Kammer5fad5012021-09-09 14:08:21 -0400422
Sam Delmericoc1130dc2022-08-25 14:43:54 -0400423func TestLabelListAttributePartition(t *testing.T) {
424 testCases := []struct {
425 name string
426 input LabelListAttribute
427 predicated LabelListAttribute
428 unpredicated LabelListAttribute
429 predicate func(label Label) bool
430 }{
431 {
432 name: "move all to predicated partition",
433 input: MakeLabelListAttribute(makeLabelList(
434 []string{"keep1", "throw1", "keep2", "throw2"},
435 []string{"keep1", "throw1", "keep2", "throw2"},
436 )),
437 predicated: MakeLabelListAttribute(makeLabelList(
438 []string{"keep1", "throw1", "keep2", "throw2"},
439 []string{"keep1", "throw1", "keep2", "throw2"},
440 )),
441 unpredicated: LabelListAttribute{},
442 predicate: func(label Label) bool {
443 return true
444 },
445 },
446 {
447 name: "move all to unpredicated partition",
448 input: MakeLabelListAttribute(makeLabelList(
449 []string{"keep1", "throw1", "keep2", "throw2"},
450 []string{"keep1", "throw1", "keep2", "throw2"},
451 )),
452 predicated: LabelListAttribute{},
453 unpredicated: MakeLabelListAttribute(makeLabelList(
454 []string{"keep1", "throw1", "keep2", "throw2"},
455 []string{"keep1", "throw1", "keep2", "throw2"},
456 )),
457 predicate: func(label Label) bool {
458 return false
459 },
460 },
461 {
462 name: "partition includes and excludes",
463 input: MakeLabelListAttribute(makeLabelList(
464 []string{"keep1", "throw1", "keep2", "throw2"},
465 []string{"keep1", "throw1", "keep2", "throw2"},
466 )),
467 predicated: MakeLabelListAttribute(makeLabelList(
468 []string{"keep1", "keep2"},
469 []string{"keep1", "keep2"},
470 )),
471 unpredicated: MakeLabelListAttribute(makeLabelList(
472 []string{"throw1", "throw2"},
473 []string{"throw1", "throw2"},
474 )),
475 predicate: func(label Label) bool {
476 return strings.HasPrefix(label.Label, "keep")
477 },
478 },
479 {
480 name: "partition excludes only",
481 input: MakeLabelListAttribute(makeLabelList(
482 []string{},
483 []string{"keep1", "throw1", "keep2", "throw2"},
484 )),
485 predicated: MakeLabelListAttribute(makeLabelList(
486 []string{},
487 []string{"keep1", "keep2"},
488 )),
489 unpredicated: MakeLabelListAttribute(makeLabelList(
490 []string{},
491 []string{"throw1", "throw2"},
492 )),
493 predicate: func(label Label) bool {
494 return strings.HasPrefix(label.Label, "keep")
495 },
496 },
497 {
498 name: "partition includes only",
499 input: MakeLabelListAttribute(makeLabelList(
500 []string{"keep1", "throw1", "keep2", "throw2"},
501 []string{},
502 )),
503 predicated: MakeLabelListAttribute(makeLabelList(
504 []string{"keep1", "keep2"},
505 []string{},
506 )),
507 unpredicated: MakeLabelListAttribute(makeLabelList(
508 []string{"throw1", "throw2"},
509 []string{},
510 )),
511 predicate: func(label Label) bool {
512 return strings.HasPrefix(label.Label, "keep")
513 },
514 },
515 {
516 name: "empty partition",
517 input: MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
518 predicated: LabelListAttribute{},
519 unpredicated: LabelListAttribute{},
520 predicate: func(label Label) bool {
521 return true
522 },
523 },
524 }
525
526 for _, tc := range testCases {
527 t.Run(tc.name, func(t *testing.T) {
528 predicated, unpredicated := tc.input.Partition(tc.predicate)
529 if !predicated.Value.Equals(tc.predicated.Value) {
530 t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
531 }
532 for axis, configs := range predicated.ConfigurableValues {
533 tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
534 if !ok || !reflect.DeepEqual(configs, tcConfigs) {
535 t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
536 }
537 }
538 if !unpredicated.Value.Equals(tc.unpredicated.Value) {
539 t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
540 }
541 for axis, configs := range unpredicated.ConfigurableValues {
542 tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
543 if !ok || !reflect.DeepEqual(configs, tcConfigs) {
544 t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
545 }
546 }
547 })
548 }
549}
550
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400551// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
552// typ
553func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
Liz Kammer12615db2021-09-28 09:19:17 -0400554 return func(omc OtherModuleContext, label Label) (string, bool) {
555 m, ok := omc.ModuleFromName(label.Label)
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400556 if !ok {
Liz Kammer12615db2021-09-28 09:19:17 -0400557 return label.Label, false
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400558 }
559 mTyp := omc.OtherModuleType(m)
560 if typ == mTyp {
Liz Kammer12615db2021-09-28 09:19:17 -0400561 return label.Label + suffix, true
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400562 }
Liz Kammer12615db2021-09-28 09:19:17 -0400563 return label.Label, false
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400564 }
565}
566
567func TestPartitionLabelListAttribute(t *testing.T) {
568 testCases := []struct {
569 name string
Sam Delmericocc518432022-03-30 15:50:34 +0000570 ctx *OtherModuleTestContext
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400571 labelList LabelListAttribute
572 filters LabelPartitions
573 expected PartitionToLabelListAttribute
574 expectedErrMsg *string
575 }{
576 {
577 name: "no configurable values",
Sam Delmericocc518432022-03-30 15:50:34 +0000578 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400579 labelList: LabelListAttribute{
580 Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
581 },
582 filters: LabelPartitions{
583 "A": LabelPartition{Extensions: []string{".a"}},
584 "B": LabelPartition{Extensions: []string{".b"}},
585 "C": LabelPartition{Extensions: []string{".c"}},
586 },
587 expected: PartitionToLabelListAttribute{
588 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
589 "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
590 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
591 },
592 },
593 {
594 name: "no configurable values, remainder partition",
Sam Delmericocc518432022-03-30 15:50:34 +0000595 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400596 labelList: LabelListAttribute{
597 Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
598 },
599 filters: LabelPartitions{
600 "A": LabelPartition{Extensions: []string{".a"}, Keep_remainder: true},
601 "B": LabelPartition{Extensions: []string{".b"}},
602 "C": LabelPartition{Extensions: []string{".c"}},
603 },
604 expected: PartitionToLabelListAttribute{
605 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "d.d", "e.e"}, []string{})},
606 "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
607 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
608 },
609 },
610 {
611 name: "no configurable values, empty partition",
Sam Delmericocc518432022-03-30 15:50:34 +0000612 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400613 labelList: LabelListAttribute{
614 Value: makeLabelList([]string{"a.a", "c.c"}, []string{}),
615 },
616 filters: LabelPartitions{
617 "A": LabelPartition{Extensions: []string{".a"}},
618 "B": LabelPartition{Extensions: []string{".b"}},
619 "C": LabelPartition{Extensions: []string{".c"}},
620 },
621 expected: PartitionToLabelListAttribute{
622 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
623 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
624 },
625 },
626 {
627 name: "no configurable values, has map",
Sam Delmericocc518432022-03-30 15:50:34 +0000628 ctx: &OtherModuleTestContext{
629 Modules: []TestModuleInfo{{ModuleName: "srcs", Typ: "fg", Dir: "dir"}},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400630 },
631 labelList: LabelListAttribute{
632 Value: makeLabelList([]string{"a.a", "srcs", "b.b", "c.c"}, []string{}),
633 },
634 filters: LabelPartitions{
635 "A": LabelPartition{Extensions: []string{".a"}, LabelMapper: labelAddSuffixForTypeMapper("_a", "fg")},
636 "B": LabelPartition{Extensions: []string{".b"}},
637 "C": LabelPartition{Extensions: []string{".c"}},
638 },
639 expected: PartitionToLabelListAttribute{
640 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "srcs_a"}, []string{})},
641 "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
642 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
643 },
644 },
645 {
646 name: "configurable values, keeps empty if excludes",
Sam Delmericocc518432022-03-30 15:50:34 +0000647 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400648 labelList: LabelListAttribute{
649 ConfigurableValues: configurableLabelLists{
650 ArchConfigurationAxis: labelListSelectValues{
651 "x86": makeLabelList([]string{"a.a", "c.c"}, []string{}),
652 "arm": makeLabelList([]string{"b.b"}, []string{}),
653 "x86_64": makeLabelList([]string{"b.b"}, []string{"d.d"}),
654 },
655 },
656 },
657 filters: LabelPartitions{
658 "A": LabelPartition{Extensions: []string{".a"}},
659 "B": LabelPartition{Extensions: []string{".b"}},
660 "C": LabelPartition{Extensions: []string{".c"}},
661 },
662 expected: PartitionToLabelListAttribute{
663 "A": LabelListAttribute{
664 ConfigurableValues: configurableLabelLists{
665 ArchConfigurationAxis: labelListSelectValues{
666 "x86": makeLabelList([]string{"a.a"}, []string{}),
667 "x86_64": makeLabelList([]string{}, []string{"c.c"}),
668 },
669 },
670 },
671 "B": LabelListAttribute{
672 ConfigurableValues: configurableLabelLists{
673 ArchConfigurationAxis: labelListSelectValues{
674 "arm": makeLabelList([]string{"b.b"}, []string{}),
675 "x86_64": makeLabelList([]string{"b.b"}, []string{"c.c"}),
676 },
677 },
678 },
679 "C": LabelListAttribute{
680 ConfigurableValues: configurableLabelLists{
681 ArchConfigurationAxis: labelListSelectValues{
682 "x86": makeLabelList([]string{"c.c"}, []string{}),
683 "x86_64": makeLabelList([]string{}, []string{"c.c"}),
684 },
685 },
686 },
687 },
688 },
689 {
690 name: "error for multiple partitions same value",
Sam Delmericocc518432022-03-30 15:50:34 +0000691 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400692 labelList: LabelListAttribute{
693 Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
694 },
695 filters: LabelPartitions{
696 "A": LabelPartition{Extensions: []string{".a"}},
697 "other A": LabelPartition{Extensions: []string{".a"}},
698 },
699 expected: PartitionToLabelListAttribute{},
700 expectedErrMsg: proptools.StringPtr(`"a.a" was found in multiple partitions:`),
701 },
702 }
703
704 for _, tc := range testCases {
705 t.Run(tc.name, func(t *testing.T) {
706 got := PartitionLabelListAttribute(tc.ctx, &tc.labelList, tc.filters)
707
708 if hasErrors, expectsErr := len(tc.ctx.errors) > 0, tc.expectedErrMsg != nil; hasErrors != expectsErr {
709 t.Errorf("Unexpected error(s): %q, expected: %q", tc.ctx.errors, *tc.expectedErrMsg)
710 } else if tc.expectedErrMsg != nil {
711 found := false
712 for _, err := range tc.ctx.errors {
713 if strings.Contains(err, *tc.expectedErrMsg) {
714 found = true
715 break
716 }
717 }
718
719 if !found {
720 t.Errorf("Expected error message: %q, got %q", *tc.expectedErrMsg, tc.ctx.errors)
721 }
722 return
723 }
724
725 if len(tc.expected) != len(got) {
726 t.Errorf("Expected %d partitions, got %d partitions", len(tc.expected), len(got))
727 }
728 for partition, expectedLla := range tc.expected {
729 gotLla, ok := got[partition]
730 if !ok {
731 t.Errorf("Expected partition %q, but it was not found %v", partition, got)
732 continue
733 }
734 expectedLabelList := expectedLla.Value
735 gotLabelList := gotLla.Value
736 if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
737 t.Errorf("Expected no config includes %v, got %v", expectedLabelList.Includes, gotLabelList.Includes)
738 }
739 expectedAxes := expectedLla.SortedConfigurationAxes()
740 gotAxes := gotLla.SortedConfigurationAxes()
741 if !reflect.DeepEqual(expectedAxes, gotAxes) {
742 t.Errorf("Expected axes %v, got %v (%#v)", expectedAxes, gotAxes, gotLla)
743 }
744 for _, axis := range expectedLla.SortedConfigurationAxes() {
745 if _, exists := gotLla.ConfigurableValues[axis]; !exists {
746 t.Errorf("Expected %s to be a supported axis, but it was not found", axis)
747 }
748 if expected, got := expectedLla.ConfigurableValues[axis], gotLla.ConfigurableValues[axis]; len(expected) != len(got) {
749 t.Errorf("For axis %q: expected configs %v, got %v", axis, expected, got)
750 }
751 for config, expectedLabelList := range expectedLla.ConfigurableValues[axis] {
752 gotLabelList, exists := gotLla.ConfigurableValues[axis][config]
753 if !exists {
754 t.Errorf("Expected %s to be a supported config, but config was not found", config)
755 continue
756 }
757 if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
758 t.Errorf("Expected %s %s includes %v, got %v", axis, config, expectedLabelList.Includes, gotLabelList.Includes)
759 }
760 }
761 }
762 }
763 })
764 }
765}
766
Liz Kammer5fad5012021-09-09 14:08:21 -0400767func TestDeduplicateAxesFromBase(t *testing.T) {
768 attr := StringListAttribute{
769 Value: []string{
770 "all_include",
771 "arm_include",
772 "android_include",
773 "linux_x86_include",
774 },
775 ConfigurableValues: configurableStringLists{
776 ArchConfigurationAxis: stringListSelectValues{
777 "arm": []string{"arm_include"},
778 "x86": []string{"x86_include"},
779 },
780 OsConfigurationAxis: stringListSelectValues{
781 "android": []string{"android_include"},
782 "linux": []string{"linux_include"},
783 },
784 OsArchConfigurationAxis: stringListSelectValues{
785 "linux_x86": {"linux_x86_include"},
786 },
Cole Faust150f9a52023-04-26 10:52:24 -0700787 ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
Liz Kammer5fad5012021-09-09 14:08:21 -0400788 "a": []string{"not_in_value"},
789 },
790 },
791 }
792
793 attr.DeduplicateAxesFromBase()
794
795 expectedBaseIncludes := []string{
796 "all_include",
797 "arm_include",
798 "android_include",
799 "linux_x86_include",
800 }
801 if !reflect.DeepEqual(expectedBaseIncludes, attr.Value) {
802 t.Errorf("Expected Value includes %q, got %q", attr.Value, expectedBaseIncludes)
803 }
804 expectedConfiguredIncludes := configurableStringLists{
805 ArchConfigurationAxis: stringListSelectValues{
806 "x86": []string{"x86_include"},
807 },
808 OsConfigurationAxis: stringListSelectValues{
809 "linux": []string{"linux_include"},
810 },
811 OsArchConfigurationAxis: stringListSelectValues{},
Cole Faust150f9a52023-04-26 10:52:24 -0700812 ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
Liz Kammer5fad5012021-09-09 14:08:21 -0400813 "a": []string{"not_in_value"},
814 },
815 }
816 for _, axis := range attr.SortedConfigurationAxes() {
817 if _, ok := expectedConfiguredIncludes[axis]; !ok {
818 t.Errorf("Found unexpected axis %s", axis)
819 continue
820 }
821 expectedForAxis := expectedConfiguredIncludes[axis]
822 gotForAxis := attr.ConfigurableValues[axis]
823 if len(expectedForAxis) != len(gotForAxis) {
824 t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
825 }
826 for config, value := range gotForAxis {
827 if expected, ok := expectedForAxis[config]; ok {
828 if !reflect.DeepEqual(expected, value) {
829 t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value)
830 }
831 } else {
832 t.Errorf("Got unexpected config %q for %s", config, axis)
833 }
834 }
835 }
836}