xref: /aosp_15_r20/build/soong/android/soongconfig/modules_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage soongconfig
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"reflect"
19*333d2b36SAndroid Build Coastguard Worker	"testing"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
22*333d2b36SAndroid Build Coastguard Worker)
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Workerfunc Test_CanonicalizeToProperty(t *testing.T) {
25*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
26*333d2b36SAndroid Build Coastguard Worker		name string
27*333d2b36SAndroid Build Coastguard Worker		arg  string
28*333d2b36SAndroid Build Coastguard Worker		want string
29*333d2b36SAndroid Build Coastguard Worker	}{
30*333d2b36SAndroid Build Coastguard Worker		{
31*333d2b36SAndroid Build Coastguard Worker			name: "lowercase",
32*333d2b36SAndroid Build Coastguard Worker			arg:  "board",
33*333d2b36SAndroid Build Coastguard Worker			want: "board",
34*333d2b36SAndroid Build Coastguard Worker		},
35*333d2b36SAndroid Build Coastguard Worker		{
36*333d2b36SAndroid Build Coastguard Worker			name: "uppercase",
37*333d2b36SAndroid Build Coastguard Worker			arg:  "BOARD",
38*333d2b36SAndroid Build Coastguard Worker			want: "BOARD",
39*333d2b36SAndroid Build Coastguard Worker		},
40*333d2b36SAndroid Build Coastguard Worker		{
41*333d2b36SAndroid Build Coastguard Worker			name: "numbers",
42*333d2b36SAndroid Build Coastguard Worker			arg:  "BOARD123",
43*333d2b36SAndroid Build Coastguard Worker			want: "BOARD123",
44*333d2b36SAndroid Build Coastguard Worker		},
45*333d2b36SAndroid Build Coastguard Worker		{
46*333d2b36SAndroid Build Coastguard Worker			name: "underscore",
47*333d2b36SAndroid Build Coastguard Worker			arg:  "TARGET_BOARD",
48*333d2b36SAndroid Build Coastguard Worker			want: "TARGET_BOARD",
49*333d2b36SAndroid Build Coastguard Worker		},
50*333d2b36SAndroid Build Coastguard Worker		{
51*333d2b36SAndroid Build Coastguard Worker			name: "dash",
52*333d2b36SAndroid Build Coastguard Worker			arg:  "TARGET-BOARD",
53*333d2b36SAndroid Build Coastguard Worker			want: "TARGET_BOARD",
54*333d2b36SAndroid Build Coastguard Worker		},
55*333d2b36SAndroid Build Coastguard Worker		{
56*333d2b36SAndroid Build Coastguard Worker			name: "unicode",
57*333d2b36SAndroid Build Coastguard Worker			arg:  "boardλ",
58*333d2b36SAndroid Build Coastguard Worker			want: "board_",
59*333d2b36SAndroid Build Coastguard Worker		},
60*333d2b36SAndroid Build Coastguard Worker	}
61*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
62*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
63*333d2b36SAndroid Build Coastguard Worker			if got := CanonicalizeToProperty(tt.arg); got != tt.want {
64*333d2b36SAndroid Build Coastguard Worker				t.Errorf("canonicalizeToProperty() = %v, want %v", got, tt.want)
65*333d2b36SAndroid Build Coastguard Worker			}
66*333d2b36SAndroid Build Coastguard Worker		})
67*333d2b36SAndroid Build Coastguard Worker	}
68*333d2b36SAndroid Build Coastguard Worker}
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard Workerfunc Test_typeForPropertyFromPropertyStruct(t *testing.T) {
71*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
72*333d2b36SAndroid Build Coastguard Worker		name     string
73*333d2b36SAndroid Build Coastguard Worker		ps       interface{}
74*333d2b36SAndroid Build Coastguard Worker		property string
75*333d2b36SAndroid Build Coastguard Worker		want     string
76*333d2b36SAndroid Build Coastguard Worker	}{
77*333d2b36SAndroid Build Coastguard Worker		{
78*333d2b36SAndroid Build Coastguard Worker			name: "string",
79*333d2b36SAndroid Build Coastguard Worker			ps: struct {
80*333d2b36SAndroid Build Coastguard Worker				A string
81*333d2b36SAndroid Build Coastguard Worker			}{},
82*333d2b36SAndroid Build Coastguard Worker			property: "a",
83*333d2b36SAndroid Build Coastguard Worker			want:     "string",
84*333d2b36SAndroid Build Coastguard Worker		},
85*333d2b36SAndroid Build Coastguard Worker		{
86*333d2b36SAndroid Build Coastguard Worker			name: "list",
87*333d2b36SAndroid Build Coastguard Worker			ps: struct {
88*333d2b36SAndroid Build Coastguard Worker				A []string
89*333d2b36SAndroid Build Coastguard Worker			}{},
90*333d2b36SAndroid Build Coastguard Worker			property: "a",
91*333d2b36SAndroid Build Coastguard Worker			want:     "[]string",
92*333d2b36SAndroid Build Coastguard Worker		},
93*333d2b36SAndroid Build Coastguard Worker		{
94*333d2b36SAndroid Build Coastguard Worker			name: "missing",
95*333d2b36SAndroid Build Coastguard Worker			ps: struct {
96*333d2b36SAndroid Build Coastguard Worker				A []string
97*333d2b36SAndroid Build Coastguard Worker			}{},
98*333d2b36SAndroid Build Coastguard Worker			property: "b",
99*333d2b36SAndroid Build Coastguard Worker			want:     "",
100*333d2b36SAndroid Build Coastguard Worker		},
101*333d2b36SAndroid Build Coastguard Worker		{
102*333d2b36SAndroid Build Coastguard Worker			name: "nested",
103*333d2b36SAndroid Build Coastguard Worker			ps: struct {
104*333d2b36SAndroid Build Coastguard Worker				A struct {
105*333d2b36SAndroid Build Coastguard Worker					B string
106*333d2b36SAndroid Build Coastguard Worker				}
107*333d2b36SAndroid Build Coastguard Worker			}{},
108*333d2b36SAndroid Build Coastguard Worker			property: "a.b",
109*333d2b36SAndroid Build Coastguard Worker			want:     "string",
110*333d2b36SAndroid Build Coastguard Worker		},
111*333d2b36SAndroid Build Coastguard Worker		{
112*333d2b36SAndroid Build Coastguard Worker			name: "missing nested",
113*333d2b36SAndroid Build Coastguard Worker			ps: struct {
114*333d2b36SAndroid Build Coastguard Worker				A struct {
115*333d2b36SAndroid Build Coastguard Worker					B string
116*333d2b36SAndroid Build Coastguard Worker				}
117*333d2b36SAndroid Build Coastguard Worker			}{},
118*333d2b36SAndroid Build Coastguard Worker			property: "a.c",
119*333d2b36SAndroid Build Coastguard Worker			want:     "",
120*333d2b36SAndroid Build Coastguard Worker		},
121*333d2b36SAndroid Build Coastguard Worker		{
122*333d2b36SAndroid Build Coastguard Worker			name: "not a struct",
123*333d2b36SAndroid Build Coastguard Worker			ps: struct {
124*333d2b36SAndroid Build Coastguard Worker				A string
125*333d2b36SAndroid Build Coastguard Worker			}{},
126*333d2b36SAndroid Build Coastguard Worker			property: "a.b",
127*333d2b36SAndroid Build Coastguard Worker			want:     "",
128*333d2b36SAndroid Build Coastguard Worker		},
129*333d2b36SAndroid Build Coastguard Worker		{
130*333d2b36SAndroid Build Coastguard Worker			name: "nested pointer",
131*333d2b36SAndroid Build Coastguard Worker			ps: struct {
132*333d2b36SAndroid Build Coastguard Worker				A *struct {
133*333d2b36SAndroid Build Coastguard Worker					B string
134*333d2b36SAndroid Build Coastguard Worker				}
135*333d2b36SAndroid Build Coastguard Worker			}{},
136*333d2b36SAndroid Build Coastguard Worker			property: "a.b",
137*333d2b36SAndroid Build Coastguard Worker			want:     "string",
138*333d2b36SAndroid Build Coastguard Worker		},
139*333d2b36SAndroid Build Coastguard Worker		{
140*333d2b36SAndroid Build Coastguard Worker			name: "nested interface",
141*333d2b36SAndroid Build Coastguard Worker			ps: struct {
142*333d2b36SAndroid Build Coastguard Worker				A interface{}
143*333d2b36SAndroid Build Coastguard Worker			}{
144*333d2b36SAndroid Build Coastguard Worker				A: struct {
145*333d2b36SAndroid Build Coastguard Worker					B string
146*333d2b36SAndroid Build Coastguard Worker				}{},
147*333d2b36SAndroid Build Coastguard Worker			},
148*333d2b36SAndroid Build Coastguard Worker			property: "a.b",
149*333d2b36SAndroid Build Coastguard Worker			want:     "string",
150*333d2b36SAndroid Build Coastguard Worker		},
151*333d2b36SAndroid Build Coastguard Worker		{
152*333d2b36SAndroid Build Coastguard Worker			name: "nested interface pointer",
153*333d2b36SAndroid Build Coastguard Worker			ps: struct {
154*333d2b36SAndroid Build Coastguard Worker				A interface{}
155*333d2b36SAndroid Build Coastguard Worker			}{
156*333d2b36SAndroid Build Coastguard Worker				A: &struct {
157*333d2b36SAndroid Build Coastguard Worker					B string
158*333d2b36SAndroid Build Coastguard Worker				}{},
159*333d2b36SAndroid Build Coastguard Worker			},
160*333d2b36SAndroid Build Coastguard Worker			property: "a.b",
161*333d2b36SAndroid Build Coastguard Worker			want:     "string",
162*333d2b36SAndroid Build Coastguard Worker		},
163*333d2b36SAndroid Build Coastguard Worker		{
164*333d2b36SAndroid Build Coastguard Worker			name: "nested interface nil pointer",
165*333d2b36SAndroid Build Coastguard Worker			ps: struct {
166*333d2b36SAndroid Build Coastguard Worker				A interface{}
167*333d2b36SAndroid Build Coastguard Worker			}{
168*333d2b36SAndroid Build Coastguard Worker				A: (*struct {
169*333d2b36SAndroid Build Coastguard Worker					B string
170*333d2b36SAndroid Build Coastguard Worker				})(nil),
171*333d2b36SAndroid Build Coastguard Worker			},
172*333d2b36SAndroid Build Coastguard Worker			property: "a.b",
173*333d2b36SAndroid Build Coastguard Worker			want:     "string",
174*333d2b36SAndroid Build Coastguard Worker		},
175*333d2b36SAndroid Build Coastguard Worker	}
176*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
177*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
178*333d2b36SAndroid Build Coastguard Worker			typ := typeForPropertyFromPropertyStruct(tt.ps, tt.property)
179*333d2b36SAndroid Build Coastguard Worker			got := ""
180*333d2b36SAndroid Build Coastguard Worker			if typ != nil {
181*333d2b36SAndroid Build Coastguard Worker				got = typ.String()
182*333d2b36SAndroid Build Coastguard Worker			}
183*333d2b36SAndroid Build Coastguard Worker			if got != tt.want {
184*333d2b36SAndroid Build Coastguard Worker				t.Errorf("typeForPropertyFromPropertyStruct() = %v, want %v", got, tt.want)
185*333d2b36SAndroid Build Coastguard Worker			}
186*333d2b36SAndroid Build Coastguard Worker		})
187*333d2b36SAndroid Build Coastguard Worker	}
188*333d2b36SAndroid Build Coastguard Worker}
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Workerfunc Test_createAffectablePropertiesType(t *testing.T) {
191*333d2b36SAndroid Build Coastguard Worker	tests := []struct {
192*333d2b36SAndroid Build Coastguard Worker		name                 string
193*333d2b36SAndroid Build Coastguard Worker		affectableProperties []string
194*333d2b36SAndroid Build Coastguard Worker		factoryProps         interface{}
195*333d2b36SAndroid Build Coastguard Worker		want                 string
196*333d2b36SAndroid Build Coastguard Worker	}{
197*333d2b36SAndroid Build Coastguard Worker		{
198*333d2b36SAndroid Build Coastguard Worker			name:                 "string",
199*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{"cflags"},
200*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
201*333d2b36SAndroid Build Coastguard Worker				Cflags string
202*333d2b36SAndroid Build Coastguard Worker			}{},
203*333d2b36SAndroid Build Coastguard Worker			want: "*struct { Cflags string }",
204*333d2b36SAndroid Build Coastguard Worker		},
205*333d2b36SAndroid Build Coastguard Worker		{
206*333d2b36SAndroid Build Coastguard Worker			name:                 "list",
207*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{"cflags"},
208*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
209*333d2b36SAndroid Build Coastguard Worker				Cflags []string
210*333d2b36SAndroid Build Coastguard Worker			}{},
211*333d2b36SAndroid Build Coastguard Worker			want: "*struct { Cflags []string }",
212*333d2b36SAndroid Build Coastguard Worker		},
213*333d2b36SAndroid Build Coastguard Worker		{
214*333d2b36SAndroid Build Coastguard Worker			name:                 "string pointer",
215*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{"cflags"},
216*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
217*333d2b36SAndroid Build Coastguard Worker				Cflags *string
218*333d2b36SAndroid Build Coastguard Worker			}{},
219*333d2b36SAndroid Build Coastguard Worker			want: "*struct { Cflags *string }",
220*333d2b36SAndroid Build Coastguard Worker		},
221*333d2b36SAndroid Build Coastguard Worker		{
222*333d2b36SAndroid Build Coastguard Worker			name:                 "subset",
223*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{"cflags"},
224*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
225*333d2b36SAndroid Build Coastguard Worker				Cflags  string
226*333d2b36SAndroid Build Coastguard Worker				Ldflags string
227*333d2b36SAndroid Build Coastguard Worker			}{},
228*333d2b36SAndroid Build Coastguard Worker			want: "*struct { Cflags string }",
229*333d2b36SAndroid Build Coastguard Worker		},
230*333d2b36SAndroid Build Coastguard Worker		{
231*333d2b36SAndroid Build Coastguard Worker			name:                 "none",
232*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{"cflags"},
233*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
234*333d2b36SAndroid Build Coastguard Worker				Ldflags string
235*333d2b36SAndroid Build Coastguard Worker			}{},
236*333d2b36SAndroid Build Coastguard Worker			want: "",
237*333d2b36SAndroid Build Coastguard Worker		},
238*333d2b36SAndroid Build Coastguard Worker		{
239*333d2b36SAndroid Build Coastguard Worker			name:                 "nested",
240*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{"multilib.lib32.cflags"},
241*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
242*333d2b36SAndroid Build Coastguard Worker				Multilib struct {
243*333d2b36SAndroid Build Coastguard Worker					Lib32 struct {
244*333d2b36SAndroid Build Coastguard Worker						Cflags string
245*333d2b36SAndroid Build Coastguard Worker					}
246*333d2b36SAndroid Build Coastguard Worker				}
247*333d2b36SAndroid Build Coastguard Worker			}{},
248*333d2b36SAndroid Build Coastguard Worker			want: "*struct { Multilib struct { Lib32 struct { Cflags string } } }",
249*333d2b36SAndroid Build Coastguard Worker		},
250*333d2b36SAndroid Build Coastguard Worker		{
251*333d2b36SAndroid Build Coastguard Worker			name: "complex",
252*333d2b36SAndroid Build Coastguard Worker			affectableProperties: []string{
253*333d2b36SAndroid Build Coastguard Worker				"cflags",
254*333d2b36SAndroid Build Coastguard Worker				"multilib.lib32.cflags",
255*333d2b36SAndroid Build Coastguard Worker				"multilib.lib32.ldflags",
256*333d2b36SAndroid Build Coastguard Worker				"multilib.lib64.cflags",
257*333d2b36SAndroid Build Coastguard Worker				"multilib.lib64.ldflags",
258*333d2b36SAndroid Build Coastguard Worker				"zflags",
259*333d2b36SAndroid Build Coastguard Worker			},
260*333d2b36SAndroid Build Coastguard Worker			factoryProps: struct {
261*333d2b36SAndroid Build Coastguard Worker				Cflags   string
262*333d2b36SAndroid Build Coastguard Worker				Multilib struct {
263*333d2b36SAndroid Build Coastguard Worker					Lib32 struct {
264*333d2b36SAndroid Build Coastguard Worker						Cflags  string
265*333d2b36SAndroid Build Coastguard Worker						Ldflags string
266*333d2b36SAndroid Build Coastguard Worker					}
267*333d2b36SAndroid Build Coastguard Worker					Lib64 struct {
268*333d2b36SAndroid Build Coastguard Worker						Cflags  string
269*333d2b36SAndroid Build Coastguard Worker						Ldflags string
270*333d2b36SAndroid Build Coastguard Worker					}
271*333d2b36SAndroid Build Coastguard Worker				}
272*333d2b36SAndroid Build Coastguard Worker				Zflags string
273*333d2b36SAndroid Build Coastguard Worker			}{},
274*333d2b36SAndroid Build Coastguard Worker			want: "*struct { Cflags string; Multilib struct { Lib32 struct { Cflags string; Ldflags string }; Lib64 struct { Cflags string; Ldflags string } }; Zflags string }",
275*333d2b36SAndroid Build Coastguard Worker		},
276*333d2b36SAndroid Build Coastguard Worker	}
277*333d2b36SAndroid Build Coastguard Worker	for _, tt := range tests {
278*333d2b36SAndroid Build Coastguard Worker		t.Run(tt.name, func(t *testing.T) {
279*333d2b36SAndroid Build Coastguard Worker			typ := createAffectablePropertiesType(tt.affectableProperties, []interface{}{tt.factoryProps})
280*333d2b36SAndroid Build Coastguard Worker			got := ""
281*333d2b36SAndroid Build Coastguard Worker			if typ != nil {
282*333d2b36SAndroid Build Coastguard Worker				got = typ.String()
283*333d2b36SAndroid Build Coastguard Worker			}
284*333d2b36SAndroid Build Coastguard Worker			if !reflect.DeepEqual(got, tt.want) {
285*333d2b36SAndroid Build Coastguard Worker				t.Errorf("createAffectablePropertiesType() = %v, want %v", got, tt.want)
286*333d2b36SAndroid Build Coastguard Worker			}
287*333d2b36SAndroid Build Coastguard Worker		})
288*333d2b36SAndroid Build Coastguard Worker	}
289*333d2b36SAndroid Build Coastguard Worker}
290*333d2b36SAndroid Build Coastguard Worker
291*333d2b36SAndroid Build Coastguard Workertype properties struct {
292*333d2b36SAndroid Build Coastguard Worker	A *string
293*333d2b36SAndroid Build Coastguard Worker	B bool
294*333d2b36SAndroid Build Coastguard Worker	C []string
295*333d2b36SAndroid Build Coastguard Worker}
296*333d2b36SAndroid Build Coastguard Worker
297*333d2b36SAndroid Build Coastguard Workertype varProps struct {
298*333d2b36SAndroid Build Coastguard Worker	A                  *string
299*333d2b36SAndroid Build Coastguard Worker	B                  bool
300*333d2b36SAndroid Build Coastguard Worker	C                  []string
301*333d2b36SAndroid Build Coastguard Worker	Conditions_default *properties
302*333d2b36SAndroid Build Coastguard Worker}
303*333d2b36SAndroid Build Coastguard Worker
304*333d2b36SAndroid Build Coastguard Workertype boolSoongConfigVars struct {
305*333d2b36SAndroid Build Coastguard Worker	Bool_var interface{}
306*333d2b36SAndroid Build Coastguard Worker}
307*333d2b36SAndroid Build Coastguard Worker
308*333d2b36SAndroid Build Coastguard Workertype stringSoongConfigVars struct {
309*333d2b36SAndroid Build Coastguard Worker	String_var interface{}
310*333d2b36SAndroid Build Coastguard Worker}
311*333d2b36SAndroid Build Coastguard Worker
312*333d2b36SAndroid Build Coastguard Workertype valueSoongConfigVars struct {
313*333d2b36SAndroid Build Coastguard Worker	My_value_var interface{}
314*333d2b36SAndroid Build Coastguard Worker}
315*333d2b36SAndroid Build Coastguard Worker
316*333d2b36SAndroid Build Coastguard Workertype listProperties struct {
317*333d2b36SAndroid Build Coastguard Worker	C []string
318*333d2b36SAndroid Build Coastguard Worker}
319*333d2b36SAndroid Build Coastguard Worker
320*333d2b36SAndroid Build Coastguard Workertype listVarProps struct {
321*333d2b36SAndroid Build Coastguard Worker	C                  []string
322*333d2b36SAndroid Build Coastguard Worker	Conditions_default *listProperties
323*333d2b36SAndroid Build Coastguard Worker}
324*333d2b36SAndroid Build Coastguard Worker
325*333d2b36SAndroid Build Coastguard Workertype listSoongConfigVars struct {
326*333d2b36SAndroid Build Coastguard Worker	List_var interface{}
327*333d2b36SAndroid Build Coastguard Worker}
328*333d2b36SAndroid Build Coastguard Worker
329*333d2b36SAndroid Build Coastguard Workerfunc Test_PropertiesToApply_Bool(t *testing.T) {
330*333d2b36SAndroid Build Coastguard Worker	mt, _ := newModuleType(&ModuleTypeProperties{
331*333d2b36SAndroid Build Coastguard Worker		Module_type:      "foo",
332*333d2b36SAndroid Build Coastguard Worker		Config_namespace: "bar",
333*333d2b36SAndroid Build Coastguard Worker		Bool_variables:   []string{"bool_var"},
334*333d2b36SAndroid Build Coastguard Worker		Properties:       []string{"a", "b"},
335*333d2b36SAndroid Build Coastguard Worker	})
336*333d2b36SAndroid Build Coastguard Worker	boolVarPositive := &properties{
337*333d2b36SAndroid Build Coastguard Worker		A: proptools.StringPtr("A"),
338*333d2b36SAndroid Build Coastguard Worker		B: true,
339*333d2b36SAndroid Build Coastguard Worker	}
340*333d2b36SAndroid Build Coastguard Worker	conditionsDefault := &properties{
341*333d2b36SAndroid Build Coastguard Worker		A: proptools.StringPtr("default"),
342*333d2b36SAndroid Build Coastguard Worker		B: false,
343*333d2b36SAndroid Build Coastguard Worker	}
344*333d2b36SAndroid Build Coastguard Worker	actualProps := &struct {
345*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables boolSoongConfigVars
346*333d2b36SAndroid Build Coastguard Worker	}{
347*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables: boolSoongConfigVars{
348*333d2b36SAndroid Build Coastguard Worker			Bool_var: &varProps{
349*333d2b36SAndroid Build Coastguard Worker				A:                  boolVarPositive.A,
350*333d2b36SAndroid Build Coastguard Worker				B:                  boolVarPositive.B,
351*333d2b36SAndroid Build Coastguard Worker				Conditions_default: conditionsDefault,
352*333d2b36SAndroid Build Coastguard Worker			},
353*333d2b36SAndroid Build Coastguard Worker		},
354*333d2b36SAndroid Build Coastguard Worker	}
355*333d2b36SAndroid Build Coastguard Worker	props := reflect.ValueOf(actualProps)
356*333d2b36SAndroid Build Coastguard Worker
357*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
358*333d2b36SAndroid Build Coastguard Worker		name      string
359*333d2b36SAndroid Build Coastguard Worker		config    SoongConfig
360*333d2b36SAndroid Build Coastguard Worker		wantProps []interface{}
361*333d2b36SAndroid Build Coastguard Worker	}{
362*333d2b36SAndroid Build Coastguard Worker		{
363*333d2b36SAndroid Build Coastguard Worker			name:      "no_vendor_config",
364*333d2b36SAndroid Build Coastguard Worker			config:    Config(map[string]string{}),
365*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{conditionsDefault},
366*333d2b36SAndroid Build Coastguard Worker		},
367*333d2b36SAndroid Build Coastguard Worker		{
368*333d2b36SAndroid Build Coastguard Worker			name:      "vendor_config_false",
369*333d2b36SAndroid Build Coastguard Worker			config:    Config(map[string]string{"bool_var": "n"}),
370*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{conditionsDefault},
371*333d2b36SAndroid Build Coastguard Worker		},
372*333d2b36SAndroid Build Coastguard Worker		{
373*333d2b36SAndroid Build Coastguard Worker			name:      "bool_var_true",
374*333d2b36SAndroid Build Coastguard Worker			config:    Config(map[string]string{"bool_var": "y"}),
375*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{boolVarPositive},
376*333d2b36SAndroid Build Coastguard Worker		},
377*333d2b36SAndroid Build Coastguard Worker	}
378*333d2b36SAndroid Build Coastguard Worker
379*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
380*333d2b36SAndroid Build Coastguard Worker		gotProps, err := PropertiesToApply(mt, props, tc.config)
381*333d2b36SAndroid Build Coastguard Worker		if err != nil {
382*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
383*333d2b36SAndroid Build Coastguard Worker		}
384*333d2b36SAndroid Build Coastguard Worker
385*333d2b36SAndroid Build Coastguard Worker		if !reflect.DeepEqual(gotProps, tc.wantProps) {
386*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
387*333d2b36SAndroid Build Coastguard Worker		}
388*333d2b36SAndroid Build Coastguard Worker	}
389*333d2b36SAndroid Build Coastguard Worker}
390*333d2b36SAndroid Build Coastguard Worker
391*333d2b36SAndroid Build Coastguard Workerfunc Test_PropertiesToApply_List(t *testing.T) {
392*333d2b36SAndroid Build Coastguard Worker	mt, _ := newModuleType(&ModuleTypeProperties{
393*333d2b36SAndroid Build Coastguard Worker		Module_type:      "foo",
394*333d2b36SAndroid Build Coastguard Worker		Config_namespace: "bar",
395*333d2b36SAndroid Build Coastguard Worker		List_variables:   []string{"my_list_var"},
396*333d2b36SAndroid Build Coastguard Worker		Properties:       []string{"c"},
397*333d2b36SAndroid Build Coastguard Worker	})
398*333d2b36SAndroid Build Coastguard Worker	conditionsDefault := &listProperties{
399*333d2b36SAndroid Build Coastguard Worker		C: []string{"default"},
400*333d2b36SAndroid Build Coastguard Worker	}
401*333d2b36SAndroid Build Coastguard Worker	actualProps := &struct {
402*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables listSoongConfigVars
403*333d2b36SAndroid Build Coastguard Worker	}{
404*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables: listSoongConfigVars{
405*333d2b36SAndroid Build Coastguard Worker			List_var: &listVarProps{
406*333d2b36SAndroid Build Coastguard Worker				C:                  []string{"A=%s", "B=%s"},
407*333d2b36SAndroid Build Coastguard Worker				Conditions_default: conditionsDefault,
408*333d2b36SAndroid Build Coastguard Worker			},
409*333d2b36SAndroid Build Coastguard Worker		},
410*333d2b36SAndroid Build Coastguard Worker	}
411*333d2b36SAndroid Build Coastguard Worker	props := reflect.ValueOf(actualProps)
412*333d2b36SAndroid Build Coastguard Worker
413*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
414*333d2b36SAndroid Build Coastguard Worker		name      string
415*333d2b36SAndroid Build Coastguard Worker		config    SoongConfig
416*333d2b36SAndroid Build Coastguard Worker		wantProps []interface{}
417*333d2b36SAndroid Build Coastguard Worker	}{
418*333d2b36SAndroid Build Coastguard Worker		{
419*333d2b36SAndroid Build Coastguard Worker			name:      "no_vendor_config",
420*333d2b36SAndroid Build Coastguard Worker			config:    Config(map[string]string{}),
421*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{conditionsDefault},
422*333d2b36SAndroid Build Coastguard Worker		},
423*333d2b36SAndroid Build Coastguard Worker		{
424*333d2b36SAndroid Build Coastguard Worker			name:   "value_var_set",
425*333d2b36SAndroid Build Coastguard Worker			config: Config(map[string]string{"my_list_var": "hello there"}),
426*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{&listProperties{
427*333d2b36SAndroid Build Coastguard Worker				C: []string{"A=hello", "A=there", "B=hello", "B=there"},
428*333d2b36SAndroid Build Coastguard Worker			}},
429*333d2b36SAndroid Build Coastguard Worker		},
430*333d2b36SAndroid Build Coastguard Worker	}
431*333d2b36SAndroid Build Coastguard Worker
432*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
433*333d2b36SAndroid Build Coastguard Worker		gotProps, err := PropertiesToApply(mt, props, tc.config)
434*333d2b36SAndroid Build Coastguard Worker		if err != nil {
435*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
436*333d2b36SAndroid Build Coastguard Worker		}
437*333d2b36SAndroid Build Coastguard Worker
438*333d2b36SAndroid Build Coastguard Worker		if !reflect.DeepEqual(gotProps, tc.wantProps) {
439*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
440*333d2b36SAndroid Build Coastguard Worker		}
441*333d2b36SAndroid Build Coastguard Worker	}
442*333d2b36SAndroid Build Coastguard Worker}
443*333d2b36SAndroid Build Coastguard Worker
444*333d2b36SAndroid Build Coastguard Workerfunc Test_PropertiesToApply_Value(t *testing.T) {
445*333d2b36SAndroid Build Coastguard Worker	mt, _ := newModuleType(&ModuleTypeProperties{
446*333d2b36SAndroid Build Coastguard Worker		Module_type:      "foo",
447*333d2b36SAndroid Build Coastguard Worker		Config_namespace: "bar",
448*333d2b36SAndroid Build Coastguard Worker		Value_variables:  []string{"my_value_var"},
449*333d2b36SAndroid Build Coastguard Worker		Properties:       []string{"a", "b"},
450*333d2b36SAndroid Build Coastguard Worker	})
451*333d2b36SAndroid Build Coastguard Worker	conditionsDefault := &properties{
452*333d2b36SAndroid Build Coastguard Worker		A: proptools.StringPtr("default"),
453*333d2b36SAndroid Build Coastguard Worker		B: false,
454*333d2b36SAndroid Build Coastguard Worker	}
455*333d2b36SAndroid Build Coastguard Worker	actualProps := &struct {
456*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables valueSoongConfigVars
457*333d2b36SAndroid Build Coastguard Worker	}{
458*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables: valueSoongConfigVars{
459*333d2b36SAndroid Build Coastguard Worker			My_value_var: &varProps{
460*333d2b36SAndroid Build Coastguard Worker				A:                  proptools.StringPtr("A=%s"),
461*333d2b36SAndroid Build Coastguard Worker				B:                  true,
462*333d2b36SAndroid Build Coastguard Worker				Conditions_default: conditionsDefault,
463*333d2b36SAndroid Build Coastguard Worker			},
464*333d2b36SAndroid Build Coastguard Worker		},
465*333d2b36SAndroid Build Coastguard Worker	}
466*333d2b36SAndroid Build Coastguard Worker	props := reflect.ValueOf(actualProps)
467*333d2b36SAndroid Build Coastguard Worker
468*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
469*333d2b36SAndroid Build Coastguard Worker		name      string
470*333d2b36SAndroid Build Coastguard Worker		config    SoongConfig
471*333d2b36SAndroid Build Coastguard Worker		wantProps []interface{}
472*333d2b36SAndroid Build Coastguard Worker	}{
473*333d2b36SAndroid Build Coastguard Worker		{
474*333d2b36SAndroid Build Coastguard Worker			name:      "no_vendor_config",
475*333d2b36SAndroid Build Coastguard Worker			config:    Config(map[string]string{}),
476*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{conditionsDefault},
477*333d2b36SAndroid Build Coastguard Worker		},
478*333d2b36SAndroid Build Coastguard Worker		{
479*333d2b36SAndroid Build Coastguard Worker			name:   "value_var_set",
480*333d2b36SAndroid Build Coastguard Worker			config: Config(map[string]string{"my_value_var": "Hello"}),
481*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{&properties{
482*333d2b36SAndroid Build Coastguard Worker				A: proptools.StringPtr("A=Hello"),
483*333d2b36SAndroid Build Coastguard Worker				B: true,
484*333d2b36SAndroid Build Coastguard Worker			}},
485*333d2b36SAndroid Build Coastguard Worker		},
486*333d2b36SAndroid Build Coastguard Worker	}
487*333d2b36SAndroid Build Coastguard Worker
488*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
489*333d2b36SAndroid Build Coastguard Worker		gotProps, err := PropertiesToApply(mt, props, tc.config)
490*333d2b36SAndroid Build Coastguard Worker		if err != nil {
491*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
492*333d2b36SAndroid Build Coastguard Worker		}
493*333d2b36SAndroid Build Coastguard Worker
494*333d2b36SAndroid Build Coastguard Worker		if !reflect.DeepEqual(gotProps, tc.wantProps) {
495*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
496*333d2b36SAndroid Build Coastguard Worker		}
497*333d2b36SAndroid Build Coastguard Worker	}
498*333d2b36SAndroid Build Coastguard Worker}
499*333d2b36SAndroid Build Coastguard Worker
500*333d2b36SAndroid Build Coastguard Workerfunc Test_PropertiesToApply_Value_Nested(t *testing.T) {
501*333d2b36SAndroid Build Coastguard Worker	mt, _ := newModuleType(&ModuleTypeProperties{
502*333d2b36SAndroid Build Coastguard Worker		Module_type:      "foo",
503*333d2b36SAndroid Build Coastguard Worker		Config_namespace: "bar",
504*333d2b36SAndroid Build Coastguard Worker		Value_variables:  []string{"my_value_var"},
505*333d2b36SAndroid Build Coastguard Worker		Properties:       []string{"a.b"},
506*333d2b36SAndroid Build Coastguard Worker	})
507*333d2b36SAndroid Build Coastguard Worker	type properties struct {
508*333d2b36SAndroid Build Coastguard Worker		A struct {
509*333d2b36SAndroid Build Coastguard Worker			B string
510*333d2b36SAndroid Build Coastguard Worker		}
511*333d2b36SAndroid Build Coastguard Worker	}
512*333d2b36SAndroid Build Coastguard Worker	conditionsDefault := &properties{
513*333d2b36SAndroid Build Coastguard Worker		A: struct{ B string }{
514*333d2b36SAndroid Build Coastguard Worker			B: "default",
515*333d2b36SAndroid Build Coastguard Worker		},
516*333d2b36SAndroid Build Coastguard Worker	}
517*333d2b36SAndroid Build Coastguard Worker	type valueVarProps struct {
518*333d2b36SAndroid Build Coastguard Worker		A struct {
519*333d2b36SAndroid Build Coastguard Worker			B string
520*333d2b36SAndroid Build Coastguard Worker		}
521*333d2b36SAndroid Build Coastguard Worker		Conditions_default *properties
522*333d2b36SAndroid Build Coastguard Worker	}
523*333d2b36SAndroid Build Coastguard Worker	actualProps := &struct {
524*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables valueSoongConfigVars
525*333d2b36SAndroid Build Coastguard Worker	}{
526*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables: valueSoongConfigVars{
527*333d2b36SAndroid Build Coastguard Worker			My_value_var: &valueVarProps{
528*333d2b36SAndroid Build Coastguard Worker				A: struct{ B string }{
529*333d2b36SAndroid Build Coastguard Worker					B: "A.B=%s",
530*333d2b36SAndroid Build Coastguard Worker				},
531*333d2b36SAndroid Build Coastguard Worker				Conditions_default: conditionsDefault,
532*333d2b36SAndroid Build Coastguard Worker			},
533*333d2b36SAndroid Build Coastguard Worker		},
534*333d2b36SAndroid Build Coastguard Worker	}
535*333d2b36SAndroid Build Coastguard Worker	props := reflect.ValueOf(actualProps)
536*333d2b36SAndroid Build Coastguard Worker
537*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
538*333d2b36SAndroid Build Coastguard Worker		name      string
539*333d2b36SAndroid Build Coastguard Worker		config    SoongConfig
540*333d2b36SAndroid Build Coastguard Worker		wantProps []interface{}
541*333d2b36SAndroid Build Coastguard Worker	}{
542*333d2b36SAndroid Build Coastguard Worker		{
543*333d2b36SAndroid Build Coastguard Worker			name:      "no_vendor_config",
544*333d2b36SAndroid Build Coastguard Worker			config:    Config(map[string]string{}),
545*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{conditionsDefault},
546*333d2b36SAndroid Build Coastguard Worker		},
547*333d2b36SAndroid Build Coastguard Worker		{
548*333d2b36SAndroid Build Coastguard Worker			name:   "value_var_set",
549*333d2b36SAndroid Build Coastguard Worker			config: Config(map[string]string{"my_value_var": "Hello"}),
550*333d2b36SAndroid Build Coastguard Worker			wantProps: []interface{}{&properties{
551*333d2b36SAndroid Build Coastguard Worker				A: struct{ B string }{
552*333d2b36SAndroid Build Coastguard Worker					B: "A.B=Hello",
553*333d2b36SAndroid Build Coastguard Worker				},
554*333d2b36SAndroid Build Coastguard Worker			}},
555*333d2b36SAndroid Build Coastguard Worker		},
556*333d2b36SAndroid Build Coastguard Worker	}
557*333d2b36SAndroid Build Coastguard Worker
558*333d2b36SAndroid Build Coastguard Worker	for _, tc := range testCases {
559*333d2b36SAndroid Build Coastguard Worker		gotProps, err := PropertiesToApply(mt, props, tc.config)
560*333d2b36SAndroid Build Coastguard Worker		if err != nil {
561*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
562*333d2b36SAndroid Build Coastguard Worker		}
563*333d2b36SAndroid Build Coastguard Worker
564*333d2b36SAndroid Build Coastguard Worker		if !reflect.DeepEqual(gotProps, tc.wantProps) {
565*333d2b36SAndroid Build Coastguard Worker			t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
566*333d2b36SAndroid Build Coastguard Worker		}
567*333d2b36SAndroid Build Coastguard Worker	}
568*333d2b36SAndroid Build Coastguard Worker}
569*333d2b36SAndroid Build Coastguard Worker
570*333d2b36SAndroid Build Coastguard Workerfunc Test_PropertiesToApply_String_Error(t *testing.T) {
571*333d2b36SAndroid Build Coastguard Worker	mt, _ := newModuleType(&ModuleTypeProperties{
572*333d2b36SAndroid Build Coastguard Worker		Module_type:      "foo",
573*333d2b36SAndroid Build Coastguard Worker		Config_namespace: "bar",
574*333d2b36SAndroid Build Coastguard Worker		Variables:        []string{"string_var"},
575*333d2b36SAndroid Build Coastguard Worker		Properties:       []string{"a", "b"},
576*333d2b36SAndroid Build Coastguard Worker	})
577*333d2b36SAndroid Build Coastguard Worker	mt.Variables = append(mt.Variables, &stringVariable{
578*333d2b36SAndroid Build Coastguard Worker		baseVariable: baseVariable{
579*333d2b36SAndroid Build Coastguard Worker			variable: "string_var",
580*333d2b36SAndroid Build Coastguard Worker		},
581*333d2b36SAndroid Build Coastguard Worker		values: []string{"a", "b", "c"},
582*333d2b36SAndroid Build Coastguard Worker	})
583*333d2b36SAndroid Build Coastguard Worker	stringVarPositive := &properties{
584*333d2b36SAndroid Build Coastguard Worker		A: proptools.StringPtr("A"),
585*333d2b36SAndroid Build Coastguard Worker		B: true,
586*333d2b36SAndroid Build Coastguard Worker	}
587*333d2b36SAndroid Build Coastguard Worker	conditionsDefault := &properties{
588*333d2b36SAndroid Build Coastguard Worker		A: proptools.StringPtr("default"),
589*333d2b36SAndroid Build Coastguard Worker		B: false,
590*333d2b36SAndroid Build Coastguard Worker	}
591*333d2b36SAndroid Build Coastguard Worker	actualProps := &struct {
592*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables stringSoongConfigVars
593*333d2b36SAndroid Build Coastguard Worker	}{
594*333d2b36SAndroid Build Coastguard Worker		Soong_config_variables: stringSoongConfigVars{
595*333d2b36SAndroid Build Coastguard Worker			String_var: &varProps{
596*333d2b36SAndroid Build Coastguard Worker				A:                  stringVarPositive.A,
597*333d2b36SAndroid Build Coastguard Worker				B:                  stringVarPositive.B,
598*333d2b36SAndroid Build Coastguard Worker				Conditions_default: conditionsDefault,
599*333d2b36SAndroid Build Coastguard Worker			},
600*333d2b36SAndroid Build Coastguard Worker		},
601*333d2b36SAndroid Build Coastguard Worker	}
602*333d2b36SAndroid Build Coastguard Worker	props := reflect.ValueOf(actualProps)
603*333d2b36SAndroid Build Coastguard Worker
604*333d2b36SAndroid Build Coastguard Worker	_, err := PropertiesToApply(mt, props, Config(map[string]string{
605*333d2b36SAndroid Build Coastguard Worker		"string_var": "x",
606*333d2b36SAndroid Build Coastguard Worker	}))
607*333d2b36SAndroid Build Coastguard Worker	expected := `Soong config property "string_var" must be one of [a b c], found "x"`
608*333d2b36SAndroid Build Coastguard Worker	if err == nil {
609*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("Expected an error, got nil")
610*333d2b36SAndroid Build Coastguard Worker	} else if err.Error() != expected {
611*333d2b36SAndroid Build Coastguard Worker		t.Fatalf("Error message was not correct, expected %q, got %q", expected, err.Error())
612*333d2b36SAndroid Build Coastguard Worker	}
613*333d2b36SAndroid Build Coastguard Worker}
614