150f9a5a63
For converting the art plugins to pure soong, it would be useful to have a property that's qualified on both a soong config variable and the OS. Soong had very little-known support for this by saying your soong config variable changes the "target.android.cflags" property, and we didn't supporting bp2building that. Add the bp2build support. This cl also refactors product variable and soong variable bp2building so that they're separate from each other, which I think makes the code easier to understand. Test: go test Change-Id: Ic74dc75da8103fa2523da95c3560c9ce3c5e5672
731 lines
22 KiB
Go
731 lines
22 KiB
Go
// Copyright 2021 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package bazel
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/google/blueprint/proptools"
|
|
)
|
|
|
|
func TestUniqueBazelLabels(t *testing.T) {
|
|
testCases := []struct {
|
|
originalLabels []Label
|
|
expectedUniqueLabels []Label
|
|
}{
|
|
{
|
|
originalLabels: []Label{
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
{Label: "a"},
|
|
{Label: "c"},
|
|
},
|
|
expectedUniqueLabels: []Label{
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
{Label: "c"},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
actualUniqueLabels := UniqueSortedBazelLabels(tc.originalLabels)
|
|
if !reflect.DeepEqual(tc.expectedUniqueLabels, actualUniqueLabels) {
|
|
t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabels, actualUniqueLabels)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSubtractStrings(t *testing.T) {
|
|
testCases := []struct {
|
|
haystack []string
|
|
needle []string
|
|
expectedResult []string
|
|
}{
|
|
{
|
|
haystack: []string{
|
|
"a",
|
|
"b",
|
|
"c",
|
|
},
|
|
needle: []string{
|
|
"a",
|
|
},
|
|
expectedResult: []string{
|
|
"b", "c",
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
actualResult := SubtractStrings(tc.haystack, tc.needle)
|
|
if !reflect.DeepEqual(tc.expectedResult, actualResult) {
|
|
t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSubtractBazelLabelList(t *testing.T) {
|
|
testCases := []struct {
|
|
haystack LabelList
|
|
needle LabelList
|
|
expectedResult LabelList
|
|
}{
|
|
{
|
|
haystack: LabelList{
|
|
Includes: []Label{
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
{Label: "c"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "x"},
|
|
{Label: "y"},
|
|
{Label: "z"},
|
|
},
|
|
},
|
|
needle: LabelList{
|
|
Includes: []Label{
|
|
{Label: "a"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "z"},
|
|
},
|
|
},
|
|
// NOTE: Excludes are intentionally not subtracted
|
|
expectedResult: LabelList{
|
|
Includes: []Label{
|
|
{Label: "b"},
|
|
{Label: "c"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "x"},
|
|
{Label: "y"},
|
|
{Label: "z"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
actualResult := SubtractBazelLabelList(tc.haystack, tc.needle)
|
|
if !reflect.DeepEqual(tc.expectedResult, actualResult) {
|
|
t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
|
|
}
|
|
}
|
|
}
|
|
func TestFirstUniqueBazelLabelList(t *testing.T) {
|
|
testCases := []struct {
|
|
originalLabelList LabelList
|
|
expectedUniqueLabelList LabelList
|
|
}{
|
|
{
|
|
originalLabelList: LabelList{
|
|
Includes: []Label{
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
{Label: "a"},
|
|
{Label: "c"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "x"},
|
|
{Label: "x"},
|
|
{Label: "y"},
|
|
{Label: "z"},
|
|
},
|
|
},
|
|
expectedUniqueLabelList: LabelList{
|
|
Includes: []Label{
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
{Label: "c"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "x"},
|
|
{Label: "y"},
|
|
{Label: "z"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList)
|
|
if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
|
|
t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUniqueSortedBazelLabelList(t *testing.T) {
|
|
testCases := []struct {
|
|
originalLabelList LabelList
|
|
expectedUniqueLabelList LabelList
|
|
}{
|
|
{
|
|
originalLabelList: LabelList{
|
|
Includes: []Label{
|
|
{Label: "c"},
|
|
{Label: "a"},
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "y"},
|
|
{Label: "z"},
|
|
{Label: "x"},
|
|
{Label: "x"},
|
|
},
|
|
},
|
|
expectedUniqueLabelList: LabelList{
|
|
Includes: []Label{
|
|
{Label: "a"},
|
|
{Label: "b"},
|
|
{Label: "c"},
|
|
},
|
|
Excludes: []Label{
|
|
{Label: "x"},
|
|
{Label: "y"},
|
|
{Label: "z"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList)
|
|
if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
|
|
t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
|
|
}
|
|
}
|
|
}
|
|
|
|
func makeLabels(labels ...string) []Label {
|
|
var ret []Label
|
|
for _, l := range labels {
|
|
ret = append(ret, Label{Label: l})
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func makeLabelList(includes, excludes []string) LabelList {
|
|
return LabelList{
|
|
Includes: makeLabels(includes...),
|
|
Excludes: makeLabels(excludes...),
|
|
}
|
|
}
|
|
|
|
func TestResolveExcludes(t *testing.T) {
|
|
attr := LabelListAttribute{
|
|
Value: makeLabelList(
|
|
[]string{
|
|
"all_include",
|
|
"arm_exclude",
|
|
"android_exclude",
|
|
"product_config_exclude",
|
|
},
|
|
[]string{"all_exclude"},
|
|
),
|
|
ConfigurableValues: configurableLabelLists{
|
|
ArchConfigurationAxis: labelListSelectValues{
|
|
"arm": makeLabelList([]string{}, []string{"arm_exclude"}),
|
|
"x86": makeLabelList([]string{"x86_include"}, []string{}),
|
|
ConditionsDefaultConfigKey: makeLabelList([]string{"default_include"}, []string{}),
|
|
},
|
|
OsConfigurationAxis: labelListSelectValues{
|
|
"android": makeLabelList([]string{}, []string{"android_exclude"}),
|
|
"linux": makeLabelList([]string{"linux_include"}, []string{}),
|
|
},
|
|
OsArchConfigurationAxis: labelListSelectValues{
|
|
"linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
|
|
},
|
|
ProductVariableConfigurationAxis(false, "product_with_defaults"): labelListSelectValues{
|
|
"a": makeLabelList([]string{}, []string{"not_in_value"}),
|
|
"b": makeLabelList([]string{"b_val"}, []string{}),
|
|
"c": makeLabelList([]string{"c_val"}, []string{}),
|
|
ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2", "all_exclude"}, []string{}),
|
|
},
|
|
ProductVariableConfigurationAxis(false, "product_only_with_excludes"): labelListSelectValues{
|
|
"a": makeLabelList([]string{}, []string{"product_config_exclude"}),
|
|
},
|
|
},
|
|
}
|
|
|
|
attr.ResolveExcludes()
|
|
|
|
expectedBaseIncludes := []Label{{Label: "all_include"}}
|
|
if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
|
|
t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
|
|
}
|
|
var nilLabels []Label
|
|
expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
|
|
ArchConfigurationAxis: {
|
|
"arm": nilLabels,
|
|
"x86": makeLabels("arm_exclude", "x86_include"),
|
|
ConditionsDefaultConfigKey: makeLabels("arm_exclude", "default_include"),
|
|
},
|
|
OsConfigurationAxis: {
|
|
"android": nilLabels,
|
|
"linux": makeLabels("android_exclude", "linux_include"),
|
|
ConditionsDefaultConfigKey: makeLabels("android_exclude"),
|
|
},
|
|
OsArchConfigurationAxis: {
|
|
"linux_x86": makeLabels("linux_x86_include"),
|
|
ConditionsDefaultConfigKey: nilLabels,
|
|
},
|
|
ProductVariableConfigurationAxis(false, "product_with_defaults"): {
|
|
"a": nilLabels,
|
|
"b": makeLabels("b_val"),
|
|
"c": makeLabels("c_val"),
|
|
ConditionsDefaultConfigKey: makeLabels("c_val", "default", "default2"),
|
|
},
|
|
ProductVariableConfigurationAxis(false, "product_only_with_excludes"): {
|
|
"a": nilLabels,
|
|
ConditionsDefaultConfigKey: makeLabels("product_config_exclude"),
|
|
},
|
|
}
|
|
for _, axis := range attr.SortedConfigurationAxes() {
|
|
if _, ok := expectedConfiguredIncludes[axis]; !ok {
|
|
t.Errorf("Found unexpected axis %s", axis)
|
|
continue
|
|
}
|
|
expectedForAxis := expectedConfiguredIncludes[axis]
|
|
gotForAxis := attr.ConfigurableValues[axis]
|
|
if len(expectedForAxis) != len(gotForAxis) {
|
|
t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
|
|
}
|
|
for config, value := range gotForAxis {
|
|
if expected, ok := expectedForAxis[config]; ok {
|
|
if !reflect.DeepEqual(expected, value.Includes) {
|
|
t.Errorf("For %s,\nexpected: %#v\ngot %#v", axis, expected, value.Includes)
|
|
}
|
|
} else {
|
|
t.Errorf("Got unexpected config %q for %s", config, axis)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLabelListAttributePartition(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
input LabelListAttribute
|
|
predicated LabelListAttribute
|
|
unpredicated LabelListAttribute
|
|
predicate func(label Label) bool
|
|
}{
|
|
{
|
|
name: "move all to predicated partition",
|
|
input: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
)),
|
|
predicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
)),
|
|
unpredicated: LabelListAttribute{},
|
|
predicate: func(label Label) bool {
|
|
return true
|
|
},
|
|
},
|
|
{
|
|
name: "move all to unpredicated partition",
|
|
input: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
)),
|
|
predicated: LabelListAttribute{},
|
|
unpredicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
)),
|
|
predicate: func(label Label) bool {
|
|
return false
|
|
},
|
|
},
|
|
{
|
|
name: "partition includes and excludes",
|
|
input: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
)),
|
|
predicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "keep2"},
|
|
[]string{"keep1", "keep2"},
|
|
)),
|
|
unpredicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"throw1", "throw2"},
|
|
[]string{"throw1", "throw2"},
|
|
)),
|
|
predicate: func(label Label) bool {
|
|
return strings.HasPrefix(label.Label, "keep")
|
|
},
|
|
},
|
|
{
|
|
name: "partition excludes only",
|
|
input: MakeLabelListAttribute(makeLabelList(
|
|
[]string{},
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
)),
|
|
predicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{},
|
|
[]string{"keep1", "keep2"},
|
|
)),
|
|
unpredicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{},
|
|
[]string{"throw1", "throw2"},
|
|
)),
|
|
predicate: func(label Label) bool {
|
|
return strings.HasPrefix(label.Label, "keep")
|
|
},
|
|
},
|
|
{
|
|
name: "partition includes only",
|
|
input: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "throw1", "keep2", "throw2"},
|
|
[]string{},
|
|
)),
|
|
predicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"keep1", "keep2"},
|
|
[]string{},
|
|
)),
|
|
unpredicated: MakeLabelListAttribute(makeLabelList(
|
|
[]string{"throw1", "throw2"},
|
|
[]string{},
|
|
)),
|
|
predicate: func(label Label) bool {
|
|
return strings.HasPrefix(label.Label, "keep")
|
|
},
|
|
},
|
|
{
|
|
name: "empty partition",
|
|
input: MakeLabelListAttribute(makeLabelList([]string{}, []string{})),
|
|
predicated: LabelListAttribute{},
|
|
unpredicated: LabelListAttribute{},
|
|
predicate: func(label Label) bool {
|
|
return true
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
predicated, unpredicated := tc.input.Partition(tc.predicate)
|
|
if !predicated.Value.Equals(tc.predicated.Value) {
|
|
t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
|
|
}
|
|
for axis, configs := range predicated.ConfigurableValues {
|
|
tcConfigs, ok := tc.predicated.ConfigurableValues[axis]
|
|
if !ok || !reflect.DeepEqual(configs, tcConfigs) {
|
|
t.Errorf("expected predicated labels to be %v; got %v", tc.predicated, predicated)
|
|
}
|
|
}
|
|
if !unpredicated.Value.Equals(tc.unpredicated.Value) {
|
|
t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
|
|
}
|
|
for axis, configs := range unpredicated.ConfigurableValues {
|
|
tcConfigs, ok := tc.unpredicated.ConfigurableValues[axis]
|
|
if !ok || !reflect.DeepEqual(configs, tcConfigs) {
|
|
t.Errorf("expected unpredicated labels to be %v; got %v", tc.unpredicated, unpredicated)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// labelAddSuffixForTypeMapper returns a LabelMapper that adds suffix to label name for modules of
|
|
// typ
|
|
func labelAddSuffixForTypeMapper(suffix, typ string) LabelMapper {
|
|
return func(omc OtherModuleContext, label Label) (string, bool) {
|
|
m, ok := omc.ModuleFromName(label.Label)
|
|
if !ok {
|
|
return label.Label, false
|
|
}
|
|
mTyp := omc.OtherModuleType(m)
|
|
if typ == mTyp {
|
|
return label.Label + suffix, true
|
|
}
|
|
return label.Label, false
|
|
}
|
|
}
|
|
|
|
func TestPartitionLabelListAttribute(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
ctx *OtherModuleTestContext
|
|
labelList LabelListAttribute
|
|
filters LabelPartitions
|
|
expected PartitionToLabelListAttribute
|
|
expectedErrMsg *string
|
|
}{
|
|
{
|
|
name: "no configurable values",
|
|
ctx: &OtherModuleTestContext{},
|
|
labelList: LabelListAttribute{
|
|
Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
|
|
},
|
|
filters: LabelPartitions{
|
|
"A": LabelPartition{Extensions: []string{".a"}},
|
|
"B": LabelPartition{Extensions: []string{".b"}},
|
|
"C": LabelPartition{Extensions: []string{".c"}},
|
|
},
|
|
expected: PartitionToLabelListAttribute{
|
|
"A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
|
|
"B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
|
|
"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
|
|
},
|
|
},
|
|
{
|
|
name: "no configurable values, remainder partition",
|
|
ctx: &OtherModuleTestContext{},
|
|
labelList: LabelListAttribute{
|
|
Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
|
|
},
|
|
filters: LabelPartitions{
|
|
"A": LabelPartition{Extensions: []string{".a"}, Keep_remainder: true},
|
|
"B": LabelPartition{Extensions: []string{".b"}},
|
|
"C": LabelPartition{Extensions: []string{".c"}},
|
|
},
|
|
expected: PartitionToLabelListAttribute{
|
|
"A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "d.d", "e.e"}, []string{})},
|
|
"B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
|
|
"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
|
|
},
|
|
},
|
|
{
|
|
name: "no configurable values, empty partition",
|
|
ctx: &OtherModuleTestContext{},
|
|
labelList: LabelListAttribute{
|
|
Value: makeLabelList([]string{"a.a", "c.c"}, []string{}),
|
|
},
|
|
filters: LabelPartitions{
|
|
"A": LabelPartition{Extensions: []string{".a"}},
|
|
"B": LabelPartition{Extensions: []string{".b"}},
|
|
"C": LabelPartition{Extensions: []string{".c"}},
|
|
},
|
|
expected: PartitionToLabelListAttribute{
|
|
"A": LabelListAttribute{Value: makeLabelList([]string{"a.a"}, []string{})},
|
|
"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
|
|
},
|
|
},
|
|
{
|
|
name: "no configurable values, has map",
|
|
ctx: &OtherModuleTestContext{
|
|
Modules: []TestModuleInfo{{ModuleName: "srcs", Typ: "fg", Dir: "dir"}},
|
|
},
|
|
labelList: LabelListAttribute{
|
|
Value: makeLabelList([]string{"a.a", "srcs", "b.b", "c.c"}, []string{}),
|
|
},
|
|
filters: LabelPartitions{
|
|
"A": LabelPartition{Extensions: []string{".a"}, LabelMapper: labelAddSuffixForTypeMapper("_a", "fg")},
|
|
"B": LabelPartition{Extensions: []string{".b"}},
|
|
"C": LabelPartition{Extensions: []string{".c"}},
|
|
},
|
|
expected: PartitionToLabelListAttribute{
|
|
"A": LabelListAttribute{Value: makeLabelList([]string{"a.a", "srcs_a"}, []string{})},
|
|
"B": LabelListAttribute{Value: makeLabelList([]string{"b.b"}, []string{})},
|
|
"C": LabelListAttribute{Value: makeLabelList([]string{"c.c"}, []string{})},
|
|
},
|
|
},
|
|
{
|
|
name: "configurable values, keeps empty if excludes",
|
|
ctx: &OtherModuleTestContext{},
|
|
labelList: LabelListAttribute{
|
|
ConfigurableValues: configurableLabelLists{
|
|
ArchConfigurationAxis: labelListSelectValues{
|
|
"x86": makeLabelList([]string{"a.a", "c.c"}, []string{}),
|
|
"arm": makeLabelList([]string{"b.b"}, []string{}),
|
|
"x86_64": makeLabelList([]string{"b.b"}, []string{"d.d"}),
|
|
},
|
|
},
|
|
},
|
|
filters: LabelPartitions{
|
|
"A": LabelPartition{Extensions: []string{".a"}},
|
|
"B": LabelPartition{Extensions: []string{".b"}},
|
|
"C": LabelPartition{Extensions: []string{".c"}},
|
|
},
|
|
expected: PartitionToLabelListAttribute{
|
|
"A": LabelListAttribute{
|
|
ConfigurableValues: configurableLabelLists{
|
|
ArchConfigurationAxis: labelListSelectValues{
|
|
"x86": makeLabelList([]string{"a.a"}, []string{}),
|
|
"x86_64": makeLabelList([]string{}, []string{"c.c"}),
|
|
},
|
|
},
|
|
},
|
|
"B": LabelListAttribute{
|
|
ConfigurableValues: configurableLabelLists{
|
|
ArchConfigurationAxis: labelListSelectValues{
|
|
"arm": makeLabelList([]string{"b.b"}, []string{}),
|
|
"x86_64": makeLabelList([]string{"b.b"}, []string{"c.c"}),
|
|
},
|
|
},
|
|
},
|
|
"C": LabelListAttribute{
|
|
ConfigurableValues: configurableLabelLists{
|
|
ArchConfigurationAxis: labelListSelectValues{
|
|
"x86": makeLabelList([]string{"c.c"}, []string{}),
|
|
"x86_64": makeLabelList([]string{}, []string{"c.c"}),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "error for multiple partitions same value",
|
|
ctx: &OtherModuleTestContext{},
|
|
labelList: LabelListAttribute{
|
|
Value: makeLabelList([]string{"a.a", "b.b", "c.c", "d.d", "e.e"}, []string{}),
|
|
},
|
|
filters: LabelPartitions{
|
|
"A": LabelPartition{Extensions: []string{".a"}},
|
|
"other A": LabelPartition{Extensions: []string{".a"}},
|
|
},
|
|
expected: PartitionToLabelListAttribute{},
|
|
expectedErrMsg: proptools.StringPtr(`"a.a" was found in multiple partitions:`),
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := PartitionLabelListAttribute(tc.ctx, &tc.labelList, tc.filters)
|
|
|
|
if hasErrors, expectsErr := len(tc.ctx.errors) > 0, tc.expectedErrMsg != nil; hasErrors != expectsErr {
|
|
t.Errorf("Unexpected error(s): %q, expected: %q", tc.ctx.errors, *tc.expectedErrMsg)
|
|
} else if tc.expectedErrMsg != nil {
|
|
found := false
|
|
for _, err := range tc.ctx.errors {
|
|
if strings.Contains(err, *tc.expectedErrMsg) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
t.Errorf("Expected error message: %q, got %q", *tc.expectedErrMsg, tc.ctx.errors)
|
|
}
|
|
return
|
|
}
|
|
|
|
if len(tc.expected) != len(got) {
|
|
t.Errorf("Expected %d partitions, got %d partitions", len(tc.expected), len(got))
|
|
}
|
|
for partition, expectedLla := range tc.expected {
|
|
gotLla, ok := got[partition]
|
|
if !ok {
|
|
t.Errorf("Expected partition %q, but it was not found %v", partition, got)
|
|
continue
|
|
}
|
|
expectedLabelList := expectedLla.Value
|
|
gotLabelList := gotLla.Value
|
|
if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
|
|
t.Errorf("Expected no config includes %v, got %v", expectedLabelList.Includes, gotLabelList.Includes)
|
|
}
|
|
expectedAxes := expectedLla.SortedConfigurationAxes()
|
|
gotAxes := gotLla.SortedConfigurationAxes()
|
|
if !reflect.DeepEqual(expectedAxes, gotAxes) {
|
|
t.Errorf("Expected axes %v, got %v (%#v)", expectedAxes, gotAxes, gotLla)
|
|
}
|
|
for _, axis := range expectedLla.SortedConfigurationAxes() {
|
|
if _, exists := gotLla.ConfigurableValues[axis]; !exists {
|
|
t.Errorf("Expected %s to be a supported axis, but it was not found", axis)
|
|
}
|
|
if expected, got := expectedLla.ConfigurableValues[axis], gotLla.ConfigurableValues[axis]; len(expected) != len(got) {
|
|
t.Errorf("For axis %q: expected configs %v, got %v", axis, expected, got)
|
|
}
|
|
for config, expectedLabelList := range expectedLla.ConfigurableValues[axis] {
|
|
gotLabelList, exists := gotLla.ConfigurableValues[axis][config]
|
|
if !exists {
|
|
t.Errorf("Expected %s to be a supported config, but config was not found", config)
|
|
continue
|
|
}
|
|
if !reflect.DeepEqual(expectedLabelList.Includes, gotLabelList.Includes) {
|
|
t.Errorf("Expected %s %s includes %v, got %v", axis, config, expectedLabelList.Includes, gotLabelList.Includes)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeduplicateAxesFromBase(t *testing.T) {
|
|
attr := StringListAttribute{
|
|
Value: []string{
|
|
"all_include",
|
|
"arm_include",
|
|
"android_include",
|
|
"linux_x86_include",
|
|
},
|
|
ConfigurableValues: configurableStringLists{
|
|
ArchConfigurationAxis: stringListSelectValues{
|
|
"arm": []string{"arm_include"},
|
|
"x86": []string{"x86_include"},
|
|
},
|
|
OsConfigurationAxis: stringListSelectValues{
|
|
"android": []string{"android_include"},
|
|
"linux": []string{"linux_include"},
|
|
},
|
|
OsArchConfigurationAxis: stringListSelectValues{
|
|
"linux_x86": {"linux_x86_include"},
|
|
},
|
|
ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
|
|
"a": []string{"not_in_value"},
|
|
},
|
|
},
|
|
}
|
|
|
|
attr.DeduplicateAxesFromBase()
|
|
|
|
expectedBaseIncludes := []string{
|
|
"all_include",
|
|
"arm_include",
|
|
"android_include",
|
|
"linux_x86_include",
|
|
}
|
|
if !reflect.DeepEqual(expectedBaseIncludes, attr.Value) {
|
|
t.Errorf("Expected Value includes %q, got %q", attr.Value, expectedBaseIncludes)
|
|
}
|
|
expectedConfiguredIncludes := configurableStringLists{
|
|
ArchConfigurationAxis: stringListSelectValues{
|
|
"x86": []string{"x86_include"},
|
|
},
|
|
OsConfigurationAxis: stringListSelectValues{
|
|
"linux": []string{"linux_include"},
|
|
},
|
|
OsArchConfigurationAxis: stringListSelectValues{},
|
|
ProductVariableConfigurationAxis(false, "a"): stringListSelectValues{
|
|
"a": []string{"not_in_value"},
|
|
},
|
|
}
|
|
for _, axis := range attr.SortedConfigurationAxes() {
|
|
if _, ok := expectedConfiguredIncludes[axis]; !ok {
|
|
t.Errorf("Found unexpected axis %s", axis)
|
|
continue
|
|
}
|
|
expectedForAxis := expectedConfiguredIncludes[axis]
|
|
gotForAxis := attr.ConfigurableValues[axis]
|
|
if len(expectedForAxis) != len(gotForAxis) {
|
|
t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
|
|
}
|
|
for config, value := range gotForAxis {
|
|
if expected, ok := expectedForAxis[config]; ok {
|
|
if !reflect.DeepEqual(expected, value) {
|
|
t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value)
|
|
}
|
|
} else {
|
|
t.Errorf("Got unexpected config %q for %s", config, axis)
|
|
}
|
|
}
|
|
}
|
|
}
|