1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2020 The Android Open Source Project 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 sdk 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "testing" 19*333d2b36SAndroid Build Coastguard Worker 20*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 23*333d2b36SAndroid Build Coastguard Worker) 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Workerfunc propertySetFixture() interface{} { 26*333d2b36SAndroid Build Coastguard Worker set := newPropertySet() 27*333d2b36SAndroid Build Coastguard Worker set.AddProperty("x", "taxi") 28*333d2b36SAndroid Build Coastguard Worker set.AddPropertyWithTag("y", 1729, "tag_y") 29*333d2b36SAndroid Build Coastguard Worker subset := set.AddPropertySet("sub") 30*333d2b36SAndroid Build Coastguard Worker subset.AddPropertyWithTag("x", "taxi", "tag_x") 31*333d2b36SAndroid Build Coastguard Worker subset.AddProperty("y", 1729) 32*333d2b36SAndroid Build Coastguard Worker return set 33*333d2b36SAndroid Build Coastguard Worker} 34*333d2b36SAndroid Build Coastguard Worker 35*333d2b36SAndroid Build Coastguard Workerfunc intPtr(i int) *int { return &i } 36*333d2b36SAndroid Build Coastguard Worker 37*333d2b36SAndroid Build Coastguard Workertype propertyStruct struct { 38*333d2b36SAndroid Build Coastguard Worker X *string 39*333d2b36SAndroid Build Coastguard Worker Y *int 40*333d2b36SAndroid Build Coastguard Worker Unset *bool 41*333d2b36SAndroid Build Coastguard Worker Sub struct { 42*333d2b36SAndroid Build Coastguard Worker X *string 43*333d2b36SAndroid Build Coastguard Worker Y *int 44*333d2b36SAndroid Build Coastguard Worker Unset *bool 45*333d2b36SAndroid Build Coastguard Worker } 46*333d2b36SAndroid Build Coastguard Worker} 47*333d2b36SAndroid Build Coastguard Worker 48*333d2b36SAndroid Build Coastguard Workerfunc propertyStructFixture() interface{} { 49*333d2b36SAndroid Build Coastguard Worker str := &propertyStruct{} 50*333d2b36SAndroid Build Coastguard Worker str.X = proptools.StringPtr("taxi") 51*333d2b36SAndroid Build Coastguard Worker str.Y = intPtr(1729) 52*333d2b36SAndroid Build Coastguard Worker str.Sub.X = proptools.StringPtr("taxi") 53*333d2b36SAndroid Build Coastguard Worker str.Sub.Y = intPtr(1729) 54*333d2b36SAndroid Build Coastguard Worker return str 55*333d2b36SAndroid Build Coastguard Worker} 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Workerfunc checkPropertySetFixture(t *testing.T, val interface{}, hasTags bool) { 58*333d2b36SAndroid Build Coastguard Worker set := val.(*bpPropertySet) 59*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong x value", "taxi", set.getValue("x")) 60*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong y value", 1729, set.getValue("y")) 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Worker subset := set.getValue("sub").(*bpPropertySet) 63*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong sub.x value", "taxi", subset.getValue("x")) 64*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong sub.y value", 1729, subset.getValue("y")) 65*333d2b36SAndroid Build Coastguard Worker 66*333d2b36SAndroid Build Coastguard Worker if hasTags { 67*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong y tag", "tag_y", set.getTag("y")) 68*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong sub.x tag", "tag_x", subset.getTag("x")) 69*333d2b36SAndroid Build Coastguard Worker } else { 70*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong y tag", nil, set.getTag("y")) 71*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong sub.x tag", nil, subset.getTag("x")) 72*333d2b36SAndroid Build Coastguard Worker } 73*333d2b36SAndroid Build Coastguard Worker} 74*333d2b36SAndroid Build Coastguard Worker 75*333d2b36SAndroid Build Coastguard Workerfunc TestAddPropertySimple(t *testing.T) { 76*333d2b36SAndroid Build Coastguard Worker set := newPropertySet() 77*333d2b36SAndroid Build Coastguard Worker for name, val := range map[string]interface{}{ 78*333d2b36SAndroid Build Coastguard Worker "x": "taxi", 79*333d2b36SAndroid Build Coastguard Worker "y": 1729, 80*333d2b36SAndroid Build Coastguard Worker "t": true, 81*333d2b36SAndroid Build Coastguard Worker "f": false, 82*333d2b36SAndroid Build Coastguard Worker "arr": []string{"a", "b", "c"}, 83*333d2b36SAndroid Build Coastguard Worker } { 84*333d2b36SAndroid Build Coastguard Worker set.AddProperty(name, val) 85*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong value", val, set.getValue(name)) 86*333d2b36SAndroid Build Coastguard Worker } 87*333d2b36SAndroid Build Coastguard Worker android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`, 88*333d2b36SAndroid Build Coastguard Worker func() { set.AddProperty("x", "taxi") }) 89*333d2b36SAndroid Build Coastguard Worker android.AssertPanicMessageContains(t, "adding arr again should panic", `Property "arr" already exists in property set`, 90*333d2b36SAndroid Build Coastguard Worker func() { set.AddProperty("arr", []string{"d"}) }) 91*333d2b36SAndroid Build Coastguard Worker} 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Workerfunc TestAddPropertySubset(t *testing.T) { 94*333d2b36SAndroid Build Coastguard Worker getFixtureMap := map[string]func() interface{}{ 95*333d2b36SAndroid Build Coastguard Worker "property set": propertySetFixture, 96*333d2b36SAndroid Build Coastguard Worker "property struct": propertyStructFixture, 97*333d2b36SAndroid Build Coastguard Worker } 98*333d2b36SAndroid Build Coastguard Worker 99*333d2b36SAndroid Build Coastguard Worker t.Run("add new subset", func(t *testing.T) { 100*333d2b36SAndroid Build Coastguard Worker for name, getFixture := range getFixtureMap { 101*333d2b36SAndroid Build Coastguard Worker t.Run(name, func(t *testing.T) { 102*333d2b36SAndroid Build Coastguard Worker set := propertySetFixture().(*bpPropertySet) 103*333d2b36SAndroid Build Coastguard Worker set.AddProperty("new", getFixture()) 104*333d2b36SAndroid Build Coastguard Worker checkPropertySetFixture(t, set, true) 105*333d2b36SAndroid Build Coastguard Worker checkPropertySetFixture(t, set.getValue("new"), name == "property set") 106*333d2b36SAndroid Build Coastguard Worker }) 107*333d2b36SAndroid Build Coastguard Worker } 108*333d2b36SAndroid Build Coastguard Worker }) 109*333d2b36SAndroid Build Coastguard Worker 110*333d2b36SAndroid Build Coastguard Worker t.Run("merge existing subset", func(t *testing.T) { 111*333d2b36SAndroid Build Coastguard Worker for name, getFixture := range getFixtureMap { 112*333d2b36SAndroid Build Coastguard Worker t.Run(name, func(t *testing.T) { 113*333d2b36SAndroid Build Coastguard Worker set := newPropertySet() 114*333d2b36SAndroid Build Coastguard Worker subset := set.AddPropertySet("sub") 115*333d2b36SAndroid Build Coastguard Worker subset.AddProperty("flag", false) 116*333d2b36SAndroid Build Coastguard Worker subset.AddPropertySet("sub") 117*333d2b36SAndroid Build Coastguard Worker set.AddProperty("sub", getFixture()) 118*333d2b36SAndroid Build Coastguard Worker merged := set.getValue("sub").(*bpPropertySet) 119*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong flag value", false, merged.getValue("flag")) 120*333d2b36SAndroid Build Coastguard Worker checkPropertySetFixture(t, merged, name == "property set") 121*333d2b36SAndroid Build Coastguard Worker }) 122*333d2b36SAndroid Build Coastguard Worker } 123*333d2b36SAndroid Build Coastguard Worker }) 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Worker t.Run("add conflicting subset", func(t *testing.T) { 126*333d2b36SAndroid Build Coastguard Worker set := propertySetFixture().(*bpPropertySet) 127*333d2b36SAndroid Build Coastguard Worker android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`, 128*333d2b36SAndroid Build Coastguard Worker func() { set.AddProperty("x", propertySetFixture()) }) 129*333d2b36SAndroid Build Coastguard Worker }) 130*333d2b36SAndroid Build Coastguard Worker 131*333d2b36SAndroid Build Coastguard Worker t.Run("add non-pointer struct", func(t *testing.T) { 132*333d2b36SAndroid Build Coastguard Worker set := propertySetFixture().(*bpPropertySet) 133*333d2b36SAndroid Build Coastguard Worker str := propertyStructFixture().(*propertyStruct) 134*333d2b36SAndroid Build Coastguard Worker android.AssertPanicMessageContains(t, "adding a non-pointer struct should panic", "Value is a struct, not a pointer to one:", 135*333d2b36SAndroid Build Coastguard Worker func() { set.AddProperty("new", *str) }) 136*333d2b36SAndroid Build Coastguard Worker }) 137*333d2b36SAndroid Build Coastguard Worker} 138*333d2b36SAndroid Build Coastguard Worker 139*333d2b36SAndroid Build Coastguard Workerfunc TestAddPropertySetNew(t *testing.T) { 140*333d2b36SAndroid Build Coastguard Worker set := newPropertySet() 141*333d2b36SAndroid Build Coastguard Worker subset := set.AddPropertySet("sub") 142*333d2b36SAndroid Build Coastguard Worker subset.AddProperty("new", "d^^b") 143*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong sub.new value", "d^^b", set.getValue("sub").(*bpPropertySet).getValue("new")) 144*333d2b36SAndroid Build Coastguard Worker} 145*333d2b36SAndroid Build Coastguard Worker 146*333d2b36SAndroid Build Coastguard Workerfunc TestAddPropertySetExisting(t *testing.T) { 147*333d2b36SAndroid Build Coastguard Worker set := propertySetFixture().(*bpPropertySet) 148*333d2b36SAndroid Build Coastguard Worker subset := set.AddPropertySet("sub") 149*333d2b36SAndroid Build Coastguard Worker subset.AddProperty("new", "d^^b") 150*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "wrong sub.new value", "d^^b", set.getValue("sub").(*bpPropertySet).getValue("new")) 151*333d2b36SAndroid Build Coastguard Worker} 152*333d2b36SAndroid Build Coastguard Worker 153*333d2b36SAndroid Build Coastguard Workertype removeFredTransformation struct { 154*333d2b36SAndroid Build Coastguard Worker identityTransformation 155*333d2b36SAndroid Build Coastguard Worker} 156*333d2b36SAndroid Build Coastguard Worker 157*333d2b36SAndroid Build Coastguard Workerfunc (t removeFredTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { 158*333d2b36SAndroid Build Coastguard Worker if name == "fred" { 159*333d2b36SAndroid Build Coastguard Worker return nil, nil 160*333d2b36SAndroid Build Coastguard Worker } 161*333d2b36SAndroid Build Coastguard Worker return value, tag 162*333d2b36SAndroid Build Coastguard Worker} 163*333d2b36SAndroid Build Coastguard Worker 164*333d2b36SAndroid Build Coastguard Workerfunc (t removeFredTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { 165*333d2b36SAndroid Build Coastguard Worker if name == "fred" { 166*333d2b36SAndroid Build Coastguard Worker return nil, nil 167*333d2b36SAndroid Build Coastguard Worker } 168*333d2b36SAndroid Build Coastguard Worker return propertySet, tag 169*333d2b36SAndroid Build Coastguard Worker} 170*333d2b36SAndroid Build Coastguard Worker 171*333d2b36SAndroid Build Coastguard Workerfunc (t removeFredTransformation) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { 172*333d2b36SAndroid Build Coastguard Worker if len(propertySet.properties) == 0 { 173*333d2b36SAndroid Build Coastguard Worker return nil, nil 174*333d2b36SAndroid Build Coastguard Worker } 175*333d2b36SAndroid Build Coastguard Worker return propertySet, tag 176*333d2b36SAndroid Build Coastguard Worker} 177*333d2b36SAndroid Build Coastguard Worker 178*333d2b36SAndroid Build Coastguard Workerfunc TestTransformRemoveProperty(t *testing.T) { 179*333d2b36SAndroid Build Coastguard Worker set := newPropertySet() 180*333d2b36SAndroid Build Coastguard Worker set.AddProperty("name", "name") 181*333d2b36SAndroid Build Coastguard Worker set.AddProperty("fred", "12") 182*333d2b36SAndroid Build Coastguard Worker 183*333d2b36SAndroid Build Coastguard Worker set.transformContents(removeFredTransformation{}) 184*333d2b36SAndroid Build Coastguard Worker 185*333d2b36SAndroid Build Coastguard Worker contents := &generatedContents{} 186*333d2b36SAndroid Build Coastguard Worker outputPropertySet(contents, set) 187*333d2b36SAndroid Build Coastguard Worker android.AssertTrimmedStringEquals(t, "removing property failed", "name: \"name\",\n", contents.content.String()) 188*333d2b36SAndroid Build Coastguard Worker} 189*333d2b36SAndroid Build Coastguard Worker 190*333d2b36SAndroid Build Coastguard Workerfunc TestTransformRemovePropertySet(t *testing.T) { 191*333d2b36SAndroid Build Coastguard Worker set := newPropertySet() 192*333d2b36SAndroid Build Coastguard Worker set.AddProperty("name", "name") 193*333d2b36SAndroid Build Coastguard Worker set.AddPropertySet("fred") 194*333d2b36SAndroid Build Coastguard Worker 195*333d2b36SAndroid Build Coastguard Worker set.transformContents(removeFredTransformation{}) 196*333d2b36SAndroid Build Coastguard Worker 197*333d2b36SAndroid Build Coastguard Worker contents := &generatedContents{} 198*333d2b36SAndroid Build Coastguard Worker outputPropertySet(contents, set) 199*333d2b36SAndroid Build Coastguard Worker android.AssertTrimmedStringEquals(t, "removing property set failed", "name: \"name\",\n", contents.content.String()) 200*333d2b36SAndroid Build Coastguard Worker} 201