1// 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" 19 "path/filepath" 20 "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 { 54 PopulateMe *bool `json:"omitempty"` 55} 56 57func (c *configType) SetDefaultConfig() { 58} 59 60// tests that ValidateConfigAnnotation works 61func TestValidateConfigAnnotations(t *testing.T) { 62 config := configType{} 63 err := validateConfigAnnotations(&config) 64 expectedError := `Field configType.PopulateMe has tag json:"omitempty" which specifies to change its json field name to "omitempty". 65Did 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 } 82} 83 84func TestMissingVendorConfig(t *testing.T) { 85 c := &config{} 86 if c.VendorConfig("test").Bool("not_set") { 87 t.Errorf("Expected false") 88 } 89} 90 91func 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 122func 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 135 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 151 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} 183