blob: 9df5288a13afe6106319084f4d5980483eadece1 [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) {
78 err := validateConfigAnnotations(&productVariables{})
79 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
Lukacs T. Berki720b3962021-03-17 13:34:30 +010091func verifyProductVariableMarshaling(t *testing.T, v productVariables) {
92 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
99 var v2 productVariables
100 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) {
106 v := productVariables{}
107 v.SetDefaultConfig()
108 verifyProductVariableMarshaling(t, v)
109}
110
111func TestBootJarsMarshaling(t *testing.T) {
112 v := productVariables{}
113 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
128func TestConfiguredJarList(t *testing.T) {
129 list1 := CreateTestConfiguredJarList([]string{"apex1:jarA"})
130
131 t.Run("create", func(t *testing.T) {
132 assertStringEquals(t, "apex1:jarA", list1.String())
133 })
134
Paul Duffin9c3ac962021-02-03 14:11:27 +0000135 t.Run("create invalid - missing apex", func(t *testing.T) {
136 defer func() {
137 err := recover().(error)
138 assertStringEquals(t, "malformed (apex, jar) pair: 'jarA', expected format: <apex>:<jar>", err.Error())
139 }()
140 CreateTestConfiguredJarList([]string{"jarA"})
141 })
142
143 t.Run("create invalid - empty apex", func(t *testing.T) {
144 defer func() {
145 err := recover().(error)
146 assertStringEquals(t, "invalid apex '' in <apex>:<jar> pair ':jarA', expected format: <apex>:<jar>", err.Error())
147 }()
148 CreateTestConfiguredJarList([]string{":jarA"})
149 })
150
Paul Duffin7d584e92020-10-23 18:26:03 +0100151 list2 := list1.Append("apex2", "jarB")
152 t.Run("append", func(t *testing.T) {
153 assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
154 })
155
156 t.Run("append does not modify", func(t *testing.T) {
157 assertStringEquals(t, "apex1:jarA", list1.String())
158 })
159
160 // Make sure that two lists created by appending to the same list do not share storage.
161 list3 := list1.Append("apex3", "jarC")
162 t.Run("append does not share", func(t *testing.T) {
163 assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
164 assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
165 })
166
167 list4 := list3.RemoveList(list1)
168 t.Run("remove", func(t *testing.T) {
169 assertStringEquals(t, "apex3:jarC", list4.String())
170 })
171
172 t.Run("remove does not modify", func(t *testing.T) {
173 assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
174 })
175
176 // Make sure that two lists created by removing from the same list do not share storage.
177 list5 := list3.RemoveList(CreateTestConfiguredJarList([]string{"apex3:jarC"}))
178 t.Run("remove", func(t *testing.T) {
179 assertStringEquals(t, "apex3:jarC", list4.String())
180 assertStringEquals(t, "apex1:jarA", list5.String())
181 })
182}