blob: c98ae0ea26c8ae9602224915b9bbcde62d3e462a [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"},
36 },
37 expectedUniqueLabels: []Label{
38 {Label: "a"},
39 {Label: "b"},
40 {Label: "c"},
41 },
42 },
43 }
44 for _, tc := range testCases {
Jingwen Chened9c17d2021-04-13 07:14:55 +000045 actualUniqueLabels := UniqueSortedBazelLabels(tc.originalLabels)
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +000046 if !reflect.DeepEqual(tc.expectedUniqueLabels, actualUniqueLabels) {
47 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabels, actualUniqueLabels)
48 }
49 }
50}
51
Rupert Shuttleworthb8151682021-04-06 20:06:21 +000052func TestSubtractStrings(t *testing.T) {
53 testCases := []struct {
54 haystack []string
55 needle []string
56 expectedResult []string
57 }{
58 {
59 haystack: []string{
60 "a",
61 "b",
62 "c",
63 },
64 needle: []string{
65 "a",
66 },
67 expectedResult: []string{
68 "b", "c",
69 },
70 },
71 }
72 for _, tc := range testCases {
73 actualResult := SubtractStrings(tc.haystack, tc.needle)
74 if !reflect.DeepEqual(tc.expectedResult, actualResult) {
75 t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
76 }
77 }
78}
79
80func TestSubtractBazelLabelList(t *testing.T) {
81 testCases := []struct {
82 haystack LabelList
83 needle LabelList
84 expectedResult LabelList
85 }{
86 {
87 haystack: LabelList{
88 Includes: []Label{
89 {Label: "a"},
90 {Label: "b"},
91 {Label: "c"},
92 },
93 Excludes: []Label{
94 {Label: "x"},
95 {Label: "y"},
96 {Label: "z"},
97 },
98 },
99 needle: LabelList{
100 Includes: []Label{
101 {Label: "a"},
102 },
103 Excludes: []Label{
104 {Label: "z"},
105 },
106 },
107 // NOTE: Excludes are intentionally not subtracted
108 expectedResult: LabelList{
109 Includes: []Label{
110 {Label: "b"},
111 {Label: "c"},
112 },
113 Excludes: []Label{
114 {Label: "x"},
115 {Label: "y"},
116 {Label: "z"},
117 },
118 },
119 },
120 }
121 for _, tc := range testCases {
122 actualResult := SubtractBazelLabelList(tc.haystack, tc.needle)
123 if !reflect.DeepEqual(tc.expectedResult, actualResult) {
124 t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
125 }
126 }
127}
Liz Kammer5f5dbaa2023-07-17 17:44:08 -0400128
129func TestSubtractBazelLabelListAttribute(t *testing.T) {
130 testCases := []struct {
131 haystack LabelListAttribute
132 needle LabelListAttribute
133 expected LabelListAttribute
134 }{
135 {
136 haystack: LabelListAttribute{
137 Value: makeLabelList(
138 []string{"a", "b", "a", "c"},
139 []string{"x", "x", "y", "z"},
140 ),
141 ConfigurableValues: configurableLabelLists{
142 ArchConfigurationAxis: labelListSelectValues{
143 "arm": makeLabelList([]string{"arm_1", "arm_2"}, []string{}),
144 "x86": makeLabelList([]string{"x86_3", "x86_4", "x86_5"}, []string{"x86_5"}),
145 },
146 },
147 },
148 needle: LabelListAttribute{
149 Value: makeLabelList(
150 []string{"d", "a"},
151 []string{"x", "y2", "z2"},
152 ),
153 ConfigurableValues: configurableLabelLists{
154 ArchConfigurationAxis: labelListSelectValues{
155 "arm": makeLabelList([]string{"arm_1", "arm_3"}, []string{}),
156 "x86": makeLabelList([]string{"x86_3", "x86_4"}, []string{"x86_6"}),
157 },
158 },
159 },
160 expected: LabelListAttribute{
161 Value: makeLabelList(
162 []string{"b", "c"},
163 []string{"x", "x", "y", "z"},
164 ),
165 ConfigurableValues: configurableLabelLists{
166 ArchConfigurationAxis: labelListSelectValues{
167 "arm": makeLabelList([]string{"arm_2"}, []string{}),
168 "x86": makeLabelList([]string{"x86_5"}, []string{"x86_5"}),
169 },
170 },
171 ForceSpecifyEmptyList: false,
172 EmitEmptyList: false,
173 Prepend: false,
174 },
175 },
176 }
177 for _, tc := range testCases {
178 got := SubtractBazelLabelListAttribute(tc.haystack, tc.needle)
179 if !reflect.DeepEqual(tc.expected, got) {
180 t.Fatalf("Expected\n%v, but got\n%v", tc.expected, got)
181 }
182 }
183}
184
Liz Kammer9abd62d2021-05-21 08:37:59 -0400185func TestFirstUniqueBazelLabelList(t *testing.T) {
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000186 testCases := []struct {
187 originalLabelList LabelList
188 expectedUniqueLabelList LabelList
189 }{
190 {
191 originalLabelList: LabelList{
192 Includes: []Label{
193 {Label: "a"},
194 {Label: "b"},
195 {Label: "a"},
196 {Label: "c"},
197 },
198 Excludes: []Label{
199 {Label: "x"},
200 {Label: "x"},
201 {Label: "y"},
202 {Label: "z"},
203 },
204 },
205 expectedUniqueLabelList: LabelList{
206 Includes: []Label{
207 {Label: "a"},
208 {Label: "b"},
209 {Label: "c"},
210 },
211 Excludes: []Label{
212 {Label: "x"},
213 {Label: "y"},
214 {Label: "z"},
215 },
216 },
217 },
218 }
219 for _, tc := range testCases {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400220 actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList)
221 if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
222 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
223 }
224 }
225}
226
Liz Kammer5f5dbaa2023-07-17 17:44:08 -0400227func TestFirstUniqueBazelLabelListAttribute(t *testing.T) {
228 testCases := []struct {
229 originalLabelList LabelListAttribute
230 expectedUniqueLabelList LabelListAttribute
231 }{
232 {
233 originalLabelList: LabelListAttribute{
234 Value: makeLabelList(
235 []string{"a", "b", "a", "c"},
236 []string{"x", "x", "y", "z"},
237 ),
238 ConfigurableValues: configurableLabelLists{
239 ArchConfigurationAxis: labelListSelectValues{
240 "arm": makeLabelList([]string{"1", "2", "1"}, []string{}),
241 "x86": makeLabelList([]string{"3", "4", "4"}, []string{"5", "5"}),
242 },
243 },
244 },
245 expectedUniqueLabelList: LabelListAttribute{
246 Value: makeLabelList(
247 []string{"a", "b", "c"},
248 []string{"x", "y", "z"},
249 ),
250 ConfigurableValues: configurableLabelLists{
251 ArchConfigurationAxis: labelListSelectValues{
252 "arm": makeLabelList([]string{"1", "2"}, []string{}),
253 "x86": makeLabelList([]string{"3", "4"}, []string{"5"}),
254 },
255 },
256 },
257 },
258 }
259 for _, tc := range testCases {
260 actualUniqueLabelList := FirstUniqueBazelLabelListAttribute(tc.originalLabelList)
261 if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
262 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
263 }
264 }
265}
266
Liz Kammer9abd62d2021-05-21 08:37:59 -0400267func TestUniqueSortedBazelLabelList(t *testing.T) {
268 testCases := []struct {
269 originalLabelList LabelList
270 expectedUniqueLabelList LabelList
271 }{
272 {
273 originalLabelList: LabelList{
274 Includes: []Label{
275 {Label: "c"},
276 {Label: "a"},
277 {Label: "a"},
278 {Label: "b"},
279 },
280 Excludes: []Label{
281 {Label: "y"},
282 {Label: "z"},
283 {Label: "x"},
284 {Label: "x"},
285 },
286 },
287 expectedUniqueLabelList: LabelList{
288 Includes: []Label{
289 {Label: "a"},
290 {Label: "b"},
291 {Label: "c"},
292 },
293 Excludes: []Label{
294 {Label: "x"},
295 {Label: "y"},
296 {Label: "z"},
297 },
298 },
299 },
300 }
301 for _, tc := range testCases {
302 actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList)
Rupert Shuttleworth2e4219b2021-03-12 11:04:21 +0000303 if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
304 t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
305 }
306 }
307}
Liz Kammer74deed42021-06-02 13:02:03 -0400308
309func makeLabels(labels ...string) []Label {
310 var ret []Label
311 for _, l := range labels {
312 ret = append(ret, Label{Label: l})
313 }
314 return ret
315}
316
317func makeLabelList(includes, excludes []string) LabelList {
318 return LabelList{
319 Includes: makeLabels(includes...),
320 Excludes: makeLabels(excludes...),
321 }
322}
323
324func TestResolveExcludes(t *testing.T) {
325 attr := LabelListAttribute{
326 Value: makeLabelList(
327 []string{
328 "all_include",
329 "arm_exclude",
330 "android_exclude",
Liz Kammer748d7072023-01-25 12:07:43 -0500331 "product_config_exclude",
Liz Kammer74deed42021-06-02 13:02:03 -0400332 },
333 []string{"all_exclude"},
334 ),
335 ConfigurableValues: configurableLabelLists{
336 ArchConfigurationAxis: labelListSelectValues{
Jingwen Chen9af49a42021-11-02 10:27:17 +0000337 "arm": makeLabelList([]string{}, []string{"arm_exclude"}),
338 "x86": makeLabelList([]string{"x86_include"}, []string{}),
339 ConditionsDefaultConfigKey: makeLabelList([]string{"default_include"}, []string{}),
Liz Kammer74deed42021-06-02 13:02:03 -0400340 },
341 OsConfigurationAxis: labelListSelectValues{
342 "android": makeLabelList([]string{}, []string{"android_exclude"}),
343 "linux": makeLabelList([]string{"linux_include"}, []string{}),
344 },
345 OsArchConfigurationAxis: labelListSelectValues{
346 "linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
347 },
Cole Faust150f9a52023-04-26 10:52:24 -0700348 ProductVariableConfigurationAxis(false, "product_with_defaults"): labelListSelectValues{
Jingwen Chen9af49a42021-11-02 10:27:17 +0000349 "a": makeLabelList([]string{}, []string{"not_in_value"}),
350 "b": makeLabelList([]string{"b_val"}, []string{}),
351 "c": makeLabelList([]string{"c_val"}, []string{}),
Liz Kammer748d7072023-01-25 12:07:43 -0500352 ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2", "all_exclude"}, []string{}),
Jingwen Chen9af49a42021-11-02 10:27:17 +0000353 },
Cole Faust150f9a52023-04-26 10:52:24 -0700354 ProductVariableConfigurationAxis(false, "product_only_with_excludes"): labelListSelectValues{
Liz Kammer748d7072023-01-25 12:07:43 -0500355 "a": makeLabelList([]string{}, []string{"product_config_exclude"}),
Liz Kammer74deed42021-06-02 13:02:03 -0400356 },
357 },
358 }
359
360 attr.ResolveExcludes()
361
Jingwen Chen9af49a42021-11-02 10:27:17 +0000362 expectedBaseIncludes := []Label{{Label: "all_include"}}
Liz Kammer74deed42021-06-02 13:02:03 -0400363 if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
364 t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
365 }
366 var nilLabels []Label
367 expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
Jingwen Chen9af49a42021-11-02 10:27:17 +0000368 ArchConfigurationAxis: {
369 "arm": nilLabels,
370 "x86": makeLabels("arm_exclude", "x86_include"),
371 ConditionsDefaultConfigKey: makeLabels("arm_exclude", "default_include"),
Liz Kammer74deed42021-06-02 13:02:03 -0400372 },
Jingwen Chen9af49a42021-11-02 10:27:17 +0000373 OsConfigurationAxis: {
374 "android": nilLabels,
375 "linux": makeLabels("android_exclude", "linux_include"),
376 ConditionsDefaultConfigKey: makeLabels("android_exclude"),
Liz Kammer74deed42021-06-02 13:02:03 -0400377 },
Jingwen Chen9af49a42021-11-02 10:27:17 +0000378 OsArchConfigurationAxis: {
379 "linux_x86": makeLabels("linux_x86_include"),
380 ConditionsDefaultConfigKey: nilLabels,
381 },
Cole Faust150f9a52023-04-26 10:52:24 -0700382 ProductVariableConfigurationAxis(false, "product_with_defaults"): {
Jingwen Chen9af49a42021-11-02 10:27:17 +0000383 "a": nilLabels,
384 "b": makeLabels("b_val"),
385 "c": makeLabels("c_val"),
386 ConditionsDefaultConfigKey: makeLabels("c_val", "default", "default2"),
Liz Kammer74deed42021-06-02 13:02:03 -0400387 },
Cole Faust150f9a52023-04-26 10:52:24 -0700388 ProductVariableConfigurationAxis(false, "product_only_with_excludes"): {
Liz Kammer748d7072023-01-25 12:07:43 -0500389 "a": nilLabels,
390 ConditionsDefaultConfigKey: makeLabels("product_config_exclude"),
391 },
Liz Kammer74deed42021-06-02 13:02:03 -0400392 }
393 for _, axis := range attr.SortedConfigurationAxes() {
394 if _, ok := expectedConfiguredIncludes[axis]; !ok {
395 t.Errorf("Found unexpected axis %s", axis)
396 continue
397 }
398 expectedForAxis := expectedConfiguredIncludes[axis]
399 gotForAxis := attr.ConfigurableValues[axis]
400 if len(expectedForAxis) != len(gotForAxis) {
401 t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
402 }
403 for config, value := range gotForAxis {
404 if expected, ok := expectedForAxis[config]; ok {
405 if !reflect.DeepEqual(expected, value.Includes) {
Jingwen Chen9af49a42021-11-02 10:27:17 +0000406 t.Errorf("For %s,\nexpected: %#v\ngot %#v", axis, expected, value.Includes)
Liz Kammer74deed42021-06-02 13:02:03 -0400407 }
408 } else {
409 t.Errorf("Got unexpected config %q for %s", config, axis)
410 }
411 }
412 }
413}
Liz Kammer5fad5012021-09-09 14:08:21 -0400414
Sam Delmericoc1130dc2022-08-25 14:43:54 -0400415func TestLabelListAttributePartition(t *testing.T) {
416 testCases := []struct {
417 name string
418 input LabelListAttribute
419 predicated LabelListAttribute
420 unpredicated LabelListAttribute
421 predicate func(label Label) bool
422 }{
423 {
424 name: "move all to predicated partition",
425 input: MakeLabelListAttribute(makeLabelList(
426 []string{"keep1", "throw1", "keep2", "throw2"},
427 []string{"keep1", "throw1", "keep2", "throw2"},
428 )),
429 predicated: MakeLabelListAttribute(makeLabelList(
430 []string{"keep1", "throw1", "keep2", "throw2"},
431 []string{"keep1", "throw1", "keep2", "throw2"},
432 )),
433 unpredicated: LabelListAttribute{},
434 predicate: func(label Label) bool {
435 return true
436 },
437 },
438 {
439 name: "move all to unpredicated partition",
440 input: MakeLabelListAttribute(makeLabelList(
441 []string{"keep1", "throw1", "keep2", "throw2"},
442 []string{"keep1", "throw1", "keep2", "throw2"},
443 )),
444 predicated: LabelListAttribute{},
445 unpredicated: MakeLabelListAttribute(makeLabelList(
446 []string{"keep1", "throw1", "keep2", "throw2"},
447 []string{"keep1", "throw1", "keep2", "throw2"},
448 )),
449 predicate: func(label Label) bool {
450 return false
451 },
452 },
453 {
454 name: "partition includes and excludes",
455 input: MakeLabelListAttribute(makeLabelList(
456 []string{"keep1", "throw1", "keep2", "throw2"},
457 []string{"keep1", "throw1", "keep2", "throw2"},
458 )),
459 predicated: MakeLabelListAttribute(makeLabelList(
460 []string{"keep1", "keep2"},
461 []string{"keep1", "keep2"},
462 )),
463 unpredicated: MakeLabelListAttribute(makeLabelList(
464 []string{"throw1", "throw2"},
465 []string{"throw1", "throw2"},
466 )),
467 predicate: func(label Label) bool {
468 return strings.HasPrefix(label.Label, "keep")
469 },
470 },
471 {
472 name: "partition excludes only",
473 input: MakeLabelListAttribute(makeLabelList(
474 []string{},
475 []string{"keep1", "throw1", "keep2", "throw2"},
476 )),
477 predicated: MakeLabelListAttribute(makeLabelList(
478 []string{},
479 []string{"keep1", "keep2"},
480 )),
481 unpredicated: MakeLabelListAttribute(makeLabelList(
482 []string{},
483 []string{"throw1", "throw2"},
484 )),
485 predicate: func(label Label) bool {
486 return strings.HasPrefix(label.Label, "keep")
487 },
488 },
489 {
490 name: "partition includes only",
491 input: MakeLabelListAttribute(makeLabelList(
492 []string{"keep1", "throw1", "keep2", "throw2"},
493 []string{},
494 )),
495 predicated: MakeLabelListAttribute(makeLabelList(
496 []string{"keep1", "keep2"},
497 []string{},
498 )),
499 unpredicated: MakeLabelListAttribute(makeLabelList(
500 []string{"throw1", "throw2"},
501 []string{},
502 )),
503 predicate: func(label Label) bool {
504 return strings.HasPrefix(label.Label, "keep")
505 },
506 },
507 {
508 name: "empty partition",
509 input: MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
510 predicated: LabelListAttribute{},
511 unpredicated: LabelListAttribute{},
512 predicate: func(label Label) bool {
513 return true
514 },
515 },
516 }
517
518 for _, tc := range testCases {
519 t.Run(tc.name, func(t *testing.T) {
520 predicated, unpredicated := tc.input.Partition(tc.predicate)
521 if !predicated.Value.Equals(tc.predicated.Value) {
522 t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
523 }
524 for axis, configs := range predicated.ConfigurableValues {
525 tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
526 if !ok || !reflect.DeepEqual(configs, tcConfigs) {
527 t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
528 }
529 }
530 if !unpredicated.Value.Equals(tc.unpredicated.Value) {
531 t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
532 }
533 for axis, configs := range unpredicated.ConfigurableValues {
534 tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
535 if !ok || !reflect.DeepEqual(configs, tcConfigs) {
536 t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
537 }
538 }
539 })
540 }
541}
542
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400543// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
544// typ
545func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
Liz Kammer12615db2021-09-28 09:19:17 -0400546 return func(omc OtherModuleContext, label Label) (string, bool) {
547 m, ok := omc.ModuleFromName(label.Label)
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400548 if !ok {
Liz Kammer12615db2021-09-28 09:19:17 -0400549 return label.Label, false
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400550 }
551 mTyp := omc.OtherModuleType(m)
552 if typ == mTyp {
Liz Kammer12615db2021-09-28 09:19:17 -0400553 return label.Label + suffix, true
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400554 }
Liz Kammer12615db2021-09-28 09:19:17 -0400555 return label.Label, false
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400556 }
557}
558
559func TestPartitionLabelListAttribute(t *testing.T) {
560 testCases := []struct {
561 name string
Sam Delmericocc518432022-03-30 15:50:34 +0000562 ctx *OtherModuleTestContext
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400563 labelList LabelListAttribute
564 filters LabelPartitions
565 expected PartitionToLabelListAttribute
566 expectedErrMsg *string
567 }{
568 {
569 name: "no configurable values",
Sam Delmericocc518432022-03-30 15:50:34 +0000570 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400571 labelList: LabelListAttribute{
572 Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
573 },
574 filters: LabelPartitions{
575 "A": LabelPartition{Extensions: []string{".a"}},
576 "B": LabelPartition{Extensions: []string{".b"}},
577 "C": LabelPartition{Extensions: []string{".c"}},
578 },
579 expected: PartitionToLabelListAttribute{
580 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
581 "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
582 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
583 },
584 },
585 {
586 name: "no configurable values, remainder partition",
Sam Delmericocc518432022-03-30 15:50:34 +0000587 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400588 labelList: LabelListAttribute{
589 Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
590 },
591 filters: LabelPartitions{
592 "A": LabelPartition{Extensions: []string{".a"}, Keep_remainder: true},
593 "B": LabelPartition{Extensions: []string{".b"}},
594 "C": LabelPartition{Extensions: []string{".c"}},
595 },
596 expected: PartitionToLabelListAttribute{
597 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "d.d", "e.e"}, []string{})},
598 "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
599 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
600 },
601 },
602 {
603 name: "no configurable values, empty partition",
Sam Delmericocc518432022-03-30 15:50:34 +0000604 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400605 labelList: LabelListAttribute{
606 Value: makeLabelList([]string{"a.a", "c.c"}, []string{}),
607 },
608 filters: LabelPartitions{
609 "A": LabelPartition{Extensions: []string{".a"}},
610 "B": LabelPartition{Extensions: []string{".b"}},
611 "C": LabelPartition{Extensions: []string{".c"}},
612 },
613 expected: PartitionToLabelListAttribute{
614 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
615 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
616 },
617 },
618 {
619 name: "no configurable values, has map",
Sam Delmericocc518432022-03-30 15:50:34 +0000620 ctx: &OtherModuleTestContext{
621 Modules: []TestModuleInfo{{ModuleName: "srcs", Typ: "fg", Dir: "dir"}},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400622 },
623 labelList: LabelListAttribute{
624 Value: makeLabelList([]string{"a.a", "srcs", "b.b", "c.c"}, []string{}),
625 },
626 filters: LabelPartitions{
627 "A": LabelPartition{Extensions: []string{".a"}, LabelMapper: labelAddSuffixForTypeMapper("_a", "fg")},
628 "B": LabelPartition{Extensions: []string{".b"}},
629 "C": LabelPartition{Extensions: []string{".c"}},
630 },
631 expected: PartitionToLabelListAttribute{
632 "A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "srcs_a"}, []string{})},
633 "B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
634 "C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
635 },
636 },
637 {
638 name: "configurable values, keeps empty if excludes",
Sam Delmericocc518432022-03-30 15:50:34 +0000639 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400640 labelList: LabelListAttribute{
641 ConfigurableValues: configurableLabelLists{
642 ArchConfigurationAxis: labelListSelectValues{
643 "x86": makeLabelList([]string{"a.a", "c.c"}, []string{}),
644 "arm": makeLabelList([]string{"b.b"}, []string{}),
645 "x86_64": makeLabelList([]string{"b.b"}, []string{"d.d"}),
646 },
647 },
648 },
649 filters: LabelPartitions{
650 "A": LabelPartition{Extensions: []string{".a"}},
651 "B": LabelPartition{Extensions: []string{".b"}},
652 "C": LabelPartition{Extensions: []string{".c"}},
653 },
654 expected: PartitionToLabelListAttribute{
655 "A": LabelListAttribute{
656 ConfigurableValues: configurableLabelLists{
657 ArchConfigurationAxis: labelListSelectValues{
658 "x86": makeLabelList([]string{"a.a"}, []string{}),
659 "x86_64": makeLabelList([]string{}, []string{"c.c"}),
660 },
661 },
662 },
663 "B": LabelListAttribute{
664 ConfigurableValues: configurableLabelLists{
665 ArchConfigurationAxis: labelListSelectValues{
666 "arm": makeLabelList([]string{"b.b"}, []string{}),
667 "x86_64": makeLabelList([]string{"b.b"}, []string{"c.c"}),
668 },
669 },
670 },
671 "C": LabelListAttribute{
672 ConfigurableValues: configurableLabelLists{
673 ArchConfigurationAxis: labelListSelectValues{
674 "x86": makeLabelList([]string{"c.c"}, []string{}),
675 "x86_64": makeLabelList([]string{}, []string{"c.c"}),
676 },
677 },
678 },
679 },
680 },
681 {
682 name: "error for multiple partitions same value",
Sam Delmericocc518432022-03-30 15:50:34 +0000683 ctx: &OtherModuleTestContext{},
Liz Kammer57e2e7a2021-09-20 12:55:02 -0400684 labelList: LabelListAttribute{
685 Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
686 },
687 filters: LabelPartitions{
688 "A": LabelPartition{Extensions: []string{".a"}},
689 "other A": LabelPartition{Extensions: []string{".a"}},
690 },
691 expected: PartitionToLabelListAttribute{},
692 expectedErrMsg: proptools.StringPtr(`"a.a" was found in multiple partitions:`),
693 },
694 }
695
696 for _, tc := range testCases {
697 t.Run(tc.name, func(t *testing.T) {
698 got := PartitionLabelListAttribute(tc.ctx, &tc.labelList, tc.filters)
699
700 if hasErrors, expectsErr := len(tc.ctx.errors) > 0, tc.expectedErrMsg != nil; hasErrors != expectsErr {
701 t.Errorf("Unexpected error(s): %q, expected: %q", tc.ctx.errors, *tc.expectedErrMsg)
702 } else if tc.expectedErrMsg != nil {
703 found := false
704 for _, err := range tc.ctx.errors {
705 if strings.Contains(err, *tc.expectedErrMsg) {
706 found = true
707 break
708 }
709 }
710
711 if !found {
712 t.Errorf("Expected error message: %q, got %q", *tc.expectedErrMsg, tc.ctx.errors)
713 }
714 return
715 }
716
717 if len(tc.expected) != len(got) {
718 t.Errorf("Expected %d partitions, got %d partitions", len(tc.expected), len(got))
719 }
720 for partition, expectedLla := range tc.expected {
721 gotLla, ok := got[partition]
722 if !ok {
723 t.Errorf("Expected partition %q, but it was not found %v", partition, got)
724 continue
725 }
726 expectedLabelList := expectedLla.Value
727 gotLabelList := gotLla.Value
728 if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
729 t.Errorf("Expected no config includes %v, got %v", expectedLabelList.Includes, gotLabelList.Includes)
730 }
731 expectedAxes := expectedLla.SortedConfigurationAxes()
732 gotAxes := gotLla.SortedConfigurationAxes()
733 if !reflect.DeepEqual(expectedAxes, gotAxes) {
734 t.Errorf("Expected axes %v, got %v (%#v)", expectedAxes, gotAxes, gotLla)
735 }
736 for _, axis := range expectedLla.SortedConfigurationAxes() {
737 if _, exists := gotLla.ConfigurableValues[axis]; !exists {
738 t.Errorf("Expected %s to be a supported axis, but it was not found", axis)
739 }
740 if expected, got := expectedLla.ConfigurableValues[axis], gotLla.ConfigurableValues[axis]; len(expected) != len(got) {
741 t.Errorf("For axis %q: expected configs %v, got %v", axis, expected, got)
742 }
743 for config, expectedLabelList := range expectedLla.ConfigurableValues[axis] {
744 gotLabelList, exists := gotLla.ConfigurableValues[axis][config]
745 if !exists {
746 t.Errorf("Expected %s to be a supported config, but config was not found", config)
747 continue
748 }
749 if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
750 t.Errorf("Expected %s %s includes %v, got %v", axis, config, expectedLabelList.Includes, gotLabelList.Includes)
751 }
752 }
753 }
754 }
755 })
756 }
757}
758
Liz Kammer5fad5012021-09-09 14:08:21 -0400759func TestDeduplicateAxesFromBase(t *testing.T) {
760 attr := StringListAttribute{
761 Value: []string{
762 "all_include",
763 "arm_include",
764 "android_include",
765 "linux_x86_include",
766 },
767 ConfigurableValues: configurableStringLists{
768 ArchConfigurationAxis: stringListSelectValues{
769 "arm": []string{"arm_include"},
770 "x86": []string{"x86_include"},
771 },
772 OsConfigurationAxis: stringListSelectValues{
773 "android": []string{"android_include"},
774 "linux": []string{"linux_include"},
775 },
776 OsArchConfigurationAxis: stringListSelectValues{
777 "linux_x86": {"linux_x86_include"},
778 },
Cole Faust150f9a52023-04-26 10:52:24 -0700779 ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
Liz Kammer5fad5012021-09-09 14:08:21 -0400780 "a": []string{"not_in_value"},
781 },
782 },
783 }
784
785 attr.DeduplicateAxesFromBase()
786
787 expectedBaseIncludes := []string{
788 "all_include",
789 "arm_include",
790 "android_include",
791 "linux_x86_include",
792 }
793 if !reflect.DeepEqual(expectedBaseIncludes, attr.Value) {
794 t.Errorf("Expected Value includes %q, got %q", attr.Value, expectedBaseIncludes)
795 }
796 expectedConfiguredIncludes := configurableStringLists{
797 ArchConfigurationAxis: stringListSelectValues{
798 "x86": []string{"x86_include"},
799 },
800 OsConfigurationAxis: stringListSelectValues{
801 "linux": []string{"linux_include"},
802 },
803 OsArchConfigurationAxis: stringListSelectValues{},
Cole Faust150f9a52023-04-26 10:52:24 -0700804 ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
Liz Kammer5fad5012021-09-09 14:08:21 -0400805 "a": []string{"not_in_value"},
806 },
807 }
808 for _, axis := range attr.SortedConfigurationAxes() {
809 if _, ok := expectedConfiguredIncludes[axis]; !ok {
810 t.Errorf("Found unexpected axis %s", axis)
811 continue
812 }
813 expectedForAxis := expectedConfiguredIncludes[axis]
814 gotForAxis := attr.ConfigurableValues[axis]
815 if len(expectedForAxis) != len(gotForAxis) {
816 t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
817 }
818 for config, value := range gotForAxis {
819 if expected, ok := expectedForAxis[config]; ok {
820 if !reflect.DeepEqual(expected, value) {
821 t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value)
822 }
823 } else {
824 t.Errorf("Got unexpected config %q for %s", config, axis)
825 }
826 }
827 }
828}