blob: 7732168449955ddcd0bb178c77fcbebba4d726ac [file] [log] [blame]
Jeff Gastonf5f6e492017-11-20 14:31:11 -08001// Copyright 2017 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 android
16
17import (
18 "fmt"
Lukacs T. Berki720b3962021-03-17 13:34:30 +010019 "path/filepath"
Jeff Gastonf5f6e492017-11-20 14:31:11 -080020 "reflect"
21 "strings"
22 "testing"
23)
24
25func validateConfigAnnotations(configurable jsonConfigurable) (err error) {
26 reflectType := reflect.TypeOf(configurable)
27 reflectType = reflectType.Elem()
28 for i := 0; i < reflectType.NumField(); i++ {
29 field := reflectType.Field(i)
30 jsonTag := field.Tag.Get("json")
31 // Check for mistakes in the json tag
32 if jsonTag != "" && !strings.HasPrefix(jsonTag, ",") {
33 if !strings.Contains(jsonTag, ",") {
34 // Probably an accidental rename, most likely "omitempty" instead of ",omitempty"
35 return fmt.Errorf("Field %s.%s has tag %s which specifies to change its json field name to %q.\n"+
36 "Did you mean to use an annotation of %q?\n"+
37 "(Alternatively, to change the json name of the field, rename the field in source instead.)",
38 reflectType.Name(), field.Name, field.Tag, jsonTag, ","+jsonTag)
39 } else {
40 // Although this rename was probably intentional,
41 // a json annotation is still more confusing than renaming the source variable
42 requestedName := strings.Split(jsonTag, ",")[0]
43 return fmt.Errorf("Field %s.%s has tag %s which specifies to change its json field name to %q.\n"+
44 "To change the json name of the field, rename the field in source instead.",
45 reflectType.Name(), field.Name, field.Tag, requestedName)
46
47 }
48 }
49 }
50 return nil
51}
52
53type configType struct {
Dan Willemsen59339a22018-07-22 21:18:45 -070054 PopulateMe *bool `json:"omitempty"`
Jeff Gastonf5f6e492017-11-20 14:31:11 -080055}
56
57func (c *configType) SetDefaultConfig() {
58}
59
60// tests that ValidateConfigAnnotation works
61func TestValidateConfigAnnotations(t *testing.T) {
62 config := configType{}
63 err := validateConfigAnnotations(&config)
Dan Willemsen59339a22018-07-22 21:18:45 -070064 expectedError := `Field configType.PopulateMe has tag json:"omitempty" which specifies to change its json field name to "omitempty".
Jeff Gastonf5f6e492017-11-20 14:31:11 -080065Did you mean to use an annotation of ",omitempty"?
66(Alternatively, to change the json name of the field, rename the field in source instead.)`
67 if err.Error() != expectedError {
68 t.Errorf("Incorrect error; expected:\n"+
69 "%s\n"+
70 "got:\n"+
71 "%s",
72 expectedError, err.Error())
73 }
74}
75
76// run validateConfigAnnotations against each type that might have json annotations
77func TestProductConfigAnnotations(t *testing.T) {
Cole Faustf8231dd2023-04-21 17:37:11 -070078 err := validateConfigAnnotations(&ProductVariables{})
Jeff Gastonf5f6e492017-11-20 14:31:11 -080079 if err != nil {
80 t.Errorf(err.Error())
81 }
Jeff Gastonf5f6e492017-11-20 14:31:11 -080082}
Dan Willemsen0fe78662018-03-26 12:41:18 -070083
84func TestMissingVendorConfig(t *testing.T) {
85 c := &config{}
86 if c.VendorConfig("test").Bool("not_set") {
87 t.Errorf("Expected false")
88 }
89}
Paul Duffin7d584e92020-10-23 18:26:03 +010090
Cole Faustf8231dd2023-04-21 17:37:11 -070091func verifyProductVariableMarshaling(t *testing.T, v ProductVariables) {
Lukacs T. Berki720b3962021-03-17 13:34:30 +010092 dir := t.TempDir()
93 path := filepath.Join(dir, "test.variables")
94 err := saveToConfigFile(&v, path)
95 if err != nil {
96 t.Errorf("Couldn't save default product config: %q", err)
97 }
98
Cole Faustf8231dd2023-04-21 17:37:11 -070099 var v2 ProductVariables
Lukacs T. Berki720b3962021-03-17 13:34:30 +0100100 err = loadFromConfigFile(&v2, path)
101 if err != nil {
102 t.Errorf("Couldn't load default product config: %q", err)
103 }
104}
105func TestDefaultProductVariableMarshaling(t *testing.T) {
Cole Faustf8231dd2023-04-21 17:37:11 -0700106 v := ProductVariables{}
Lukacs T. Berki720b3962021-03-17 13:34:30 +0100107 v.SetDefaultConfig()
108 verifyProductVariableMarshaling(t, v)
109}
110
111func TestBootJarsMarshaling(t *testing.T) {
Cole Faustf8231dd2023-04-21 17:37:11 -0700112 v := ProductVariables{}
Lukacs T. Berki720b3962021-03-17 13:34:30 +0100113 v.SetDefaultConfig()
114 v.BootJars = ConfiguredJarList{
115 apexes: []string{"apex"},
116 jars: []string{"jar"},
117 }
118
119 verifyProductVariableMarshaling(t, v)
120}
121
Paul Duffin7d584e92020-10-23 18:26:03 +0100122func assertStringEquals(t *testing.T, expected, actual string) {
123 if actual != expected {
124 t.Errorf("expected %q found %q", expected, actual)
125 }
126}
127
LaMont Jones21d04d92024-06-11 11:28:54 -0700128func TestReleaseAconfigExtraReleaseConfigs(t *testing.T) {
129 testCases := []struct {
130 name string
131 flag string
132 expected []string
133 }{
134 {
135 name: "empty",
136 flag: "",
137 expected: []string{},
138 },
139 {
140 name: "specified",
141 flag: "bar foo",
142 expected: []string{"bar", "foo"},
143 },
144 {
145 name: "duplicates",
146 flag: "foo bar foo",
147 expected: []string{"foo", "bar"},
148 },
149 }
150
151 for _, tc := range testCases {
152 fixture := GroupFixturePreparers(
Colin Crossa66b4632024-08-08 15:50:47 -0700153 PrepareForTestWithBuildFlag("RELEASE_ACONFIG_EXTRA_RELEASE_CONFIGS", tc.flag),
LaMont Jones21d04d92024-06-11 11:28:54 -0700154 )
155 actual := fixture.RunTest(t).Config.ReleaseAconfigExtraReleaseConfigs()
156 AssertArrayString(t, tc.name, tc.expected, actual)
157 }
158}
159
Paul Duffin7d584e92020-10-23 18:26:03 +0100160func TestConfiguredJarList(t *testing.T) {
161 list1 := CreateTestConfiguredJarList([]string{"apex1:jarA"})
162
163 t.Run("create", func(t *testing.T) {
164 assertStringEquals(t, "apex1:jarA", list1.String())
165 })
166
Paul Duffin9c3ac962021-02-03 14:11:27 +0000167 t.Run("create invalid - missing apex", func(t *testing.T) {
168 defer func() {
169 err := recover().(error)
170 assertStringEquals(t, "malformed (apex, jar) pair: 'jarA', expected format: <apex>:<jar>", err.Error())
171 }()
172 CreateTestConfiguredJarList([]string{"jarA"})
173 })
174
175 t.Run("create invalid - empty apex", func(t *testing.T) {
176 defer func() {
177 err := recover().(error)
178 assertStringEquals(t, "invalid apex '' in <apex>:<jar> pair ':jarA', expected format: <apex>:<jar>", err.Error())
179 }()
180 CreateTestConfiguredJarList([]string{":jarA"})
181 })
182
Paul Duffin7d584e92020-10-23 18:26:03 +0100183 list2 := list1.Append("apex2", "jarB")
184 t.Run("append", func(t *testing.T) {
185 assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
186 })
187
188 t.Run("append does not modify", func(t *testing.T) {
189 assertStringEquals(t, "apex1:jarA", list1.String())
190 })
191
192 // Make sure that two lists created by appending to the same list do not share storage.
193 list3 := list1.Append("apex3", "jarC")
194 t.Run("append does not share", func(t *testing.T) {
195 assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
196 assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
197 })
198
199 list4 := list3.RemoveList(list1)
200 t.Run("remove", func(t *testing.T) {
201 assertStringEquals(t, "apex3:jarC", list4.String())
202 })
203
204 t.Run("remove does not modify", func(t *testing.T) {
205 assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
206 })
207
208 // Make sure that two lists created by removing from the same list do not share storage.
209 list5 := list3.RemoveList(CreateTestConfiguredJarList([]string{"apex3:jarC"}))
210 t.Run("remove", func(t *testing.T) {
211 assertStringEquals(t, "apex3:jarC", list4.String())
212 assertStringEquals(t, "apex1:jarA", list5.String())
213 })
214}