1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2021 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 "encoding/json" 19*333d2b36SAndroid Build Coastguard Worker "fmt" 20*333d2b36SAndroid Build Coastguard Worker "testing" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 23*333d2b36SAndroid Build Coastguard Worker) 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker// Tests for build_release.go 26*333d2b36SAndroid Build Coastguard Worker 27*333d2b36SAndroid Build Coastguard Workervar ( 28*333d2b36SAndroid Build Coastguard Worker // Some additional test specific releases that are added after the currently supported ones and 29*333d2b36SAndroid Build Coastguard Worker // so are treated as being for future releases. 30*333d2b36SAndroid Build Coastguard Worker buildReleaseFuture1 = initBuildRelease("F1") 31*333d2b36SAndroid Build Coastguard Worker buildReleaseFuture2 = initBuildRelease("F2") 32*333d2b36SAndroid Build Coastguard Worker) 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Workerfunc TestNameToRelease(t *testing.T) { 35*333d2b36SAndroid Build Coastguard Worker t.Run("single release", func(t *testing.T) { 36*333d2b36SAndroid Build Coastguard Worker release, err := nameToRelease("S") 37*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "errors", nil, err) 38*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "release", buildReleaseS, release) 39*333d2b36SAndroid Build Coastguard Worker }) 40*333d2b36SAndroid Build Coastguard Worker t.Run("invalid release", func(t *testing.T) { 41*333d2b36SAndroid Build Coastguard Worker release, err := nameToRelease("A") 42*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "release", (*buildRelease)(nil), release) 43*333d2b36SAndroid Build Coastguard Worker // Uses a wildcard in the error message to allow for additional build releases to be added to 44*333d2b36SAndroid Build Coastguard Worker // the supported set without breaking this test. 45*333d2b36SAndroid Build Coastguard Worker android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,Tiramisu,UpsideDownCake,F1,F2,current\]`, []error{err}) 46*333d2b36SAndroid Build Coastguard Worker }) 47*333d2b36SAndroid Build Coastguard Worker} 48*333d2b36SAndroid Build Coastguard Worker 49*333d2b36SAndroid Build Coastguard Workerfunc TestParseBuildReleaseSet(t *testing.T) { 50*333d2b36SAndroid Build Coastguard Worker t.Run("single release", func(t *testing.T) { 51*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("S") 52*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "errors", nil, err) 53*333d2b36SAndroid Build Coastguard Worker android.AssertStringEquals(t, "set", "[S]", set.String()) 54*333d2b36SAndroid Build Coastguard Worker }) 55*333d2b36SAndroid Build Coastguard Worker t.Run("open range", func(t *testing.T) { 56*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("F1+") 57*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "errors", nil, err) 58*333d2b36SAndroid Build Coastguard Worker android.AssertStringEquals(t, "set", "[F1,F2,current]", set.String()) 59*333d2b36SAndroid Build Coastguard Worker }) 60*333d2b36SAndroid Build Coastguard Worker t.Run("closed range", func(t *testing.T) { 61*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("S-F1") 62*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "errors", nil, err) 63*333d2b36SAndroid Build Coastguard Worker android.AssertStringEquals(t, "set", "[S,Tiramisu,UpsideDownCake,F1]", set.String()) 64*333d2b36SAndroid Build Coastguard Worker }) 65*333d2b36SAndroid Build Coastguard Worker invalidAReleaseMessage := `unknown release "A", expected one of ` + allBuildReleaseSet.String() 66*333d2b36SAndroid Build Coastguard Worker t.Run("invalid release", func(t *testing.T) { 67*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("A") 68*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set) 69*333d2b36SAndroid Build Coastguard Worker android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage) 70*333d2b36SAndroid Build Coastguard Worker }) 71*333d2b36SAndroid Build Coastguard Worker t.Run("invalid release in open range", func(t *testing.T) { 72*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("A+") 73*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set) 74*333d2b36SAndroid Build Coastguard Worker android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage) 75*333d2b36SAndroid Build Coastguard Worker }) 76*333d2b36SAndroid Build Coastguard Worker t.Run("invalid release in closed range start", func(t *testing.T) { 77*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("A-S") 78*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set) 79*333d2b36SAndroid Build Coastguard Worker android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage) 80*333d2b36SAndroid Build Coastguard Worker }) 81*333d2b36SAndroid Build Coastguard Worker t.Run("invalid release in closed range end", func(t *testing.T) { 82*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("Tiramisu-A") 83*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set) 84*333d2b36SAndroid Build Coastguard Worker android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage) 85*333d2b36SAndroid Build Coastguard Worker }) 86*333d2b36SAndroid Build Coastguard Worker t.Run("invalid closed range reversed", func(t *testing.T) { 87*333d2b36SAndroid Build Coastguard Worker set, err := parseBuildReleaseSet("F1-S") 88*333d2b36SAndroid Build Coastguard Worker android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set) 89*333d2b36SAndroid Build Coastguard Worker android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), `invalid closed range, start release "F1" is later than end release "S"`) 90*333d2b36SAndroid Build Coastguard Worker }) 91*333d2b36SAndroid Build Coastguard Worker} 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Workerfunc TestBuildReleaseSetContains(t *testing.T) { 94*333d2b36SAndroid Build Coastguard Worker t.Run("contains", func(t *testing.T) { 95*333d2b36SAndroid Build Coastguard Worker set, _ := parseBuildReleaseSet("F1-F2") 96*333d2b36SAndroid Build Coastguard Worker android.AssertBoolEquals(t, "set contains F1", true, set.contains(buildReleaseFuture1)) 97*333d2b36SAndroid Build Coastguard Worker android.AssertBoolEquals(t, "set does not contain S", false, set.contains(buildReleaseS)) 98*333d2b36SAndroid Build Coastguard Worker android.AssertBoolEquals(t, "set contains F2", true, set.contains(buildReleaseFuture2)) 99*333d2b36SAndroid Build Coastguard Worker android.AssertBoolEquals(t, "set does not contain T", false, set.contains(buildReleaseT)) 100*333d2b36SAndroid Build Coastguard Worker }) 101*333d2b36SAndroid Build Coastguard Worker} 102*333d2b36SAndroid Build Coastguard Worker 103*333d2b36SAndroid Build Coastguard Workerfunc TestPropertyPrunerInvalidTag(t *testing.T) { 104*333d2b36SAndroid Build Coastguard Worker type brokenStruct struct { 105*333d2b36SAndroid Build Coastguard Worker Broken string `supported_build_releases:"A"` 106*333d2b36SAndroid Build Coastguard Worker } 107*333d2b36SAndroid Build Coastguard Worker type containingStruct struct { 108*333d2b36SAndroid Build Coastguard Worker Nested brokenStruct 109*333d2b36SAndroid Build Coastguard Worker } 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Worker t.Run("broken struct", func(t *testing.T) { 112*333d2b36SAndroid Build Coastguard Worker android.AssertPanicMessageContains(t, "error", "invalid `supported_build_releases` tag on Broken of *sdk.brokenStruct: unknown release \"A\"", func() { 113*333d2b36SAndroid Build Coastguard Worker newPropertyPrunerByBuildRelease(&brokenStruct{}, buildReleaseS) 114*333d2b36SAndroid Build Coastguard Worker }) 115*333d2b36SAndroid Build Coastguard Worker }) 116*333d2b36SAndroid Build Coastguard Worker 117*333d2b36SAndroid Build Coastguard Worker t.Run("nested broken struct", func(t *testing.T) { 118*333d2b36SAndroid Build Coastguard Worker android.AssertPanicMessageContains(t, "error", "invalid `supported_build_releases` tag on Nested.Broken of *sdk.containingStruct: unknown release \"A\"", func() { 119*333d2b36SAndroid Build Coastguard Worker newPropertyPrunerByBuildRelease(&containingStruct{}, buildReleaseS) 120*333d2b36SAndroid Build Coastguard Worker }) 121*333d2b36SAndroid Build Coastguard Worker }) 122*333d2b36SAndroid Build Coastguard Worker} 123*333d2b36SAndroid Build Coastguard Worker 124*333d2b36SAndroid Build Coastguard Workerfunc TestPropertyPrunerByBuildRelease(t *testing.T) { 125*333d2b36SAndroid Build Coastguard Worker type nested struct { 126*333d2b36SAndroid Build Coastguard Worker F1_only string `supported_build_releases:"F1"` 127*333d2b36SAndroid Build Coastguard Worker } 128*333d2b36SAndroid Build Coastguard Worker 129*333d2b36SAndroid Build Coastguard Worker type mapped struct { 130*333d2b36SAndroid Build Coastguard Worker Default string 131*333d2b36SAndroid Build Coastguard Worker T_only string `supported_build_releases:"Tiramisu"` 132*333d2b36SAndroid Build Coastguard Worker } 133*333d2b36SAndroid Build Coastguard Worker 134*333d2b36SAndroid Build Coastguard Worker type testBuildReleasePruner struct { 135*333d2b36SAndroid Build Coastguard Worker Default string 136*333d2b36SAndroid Build Coastguard Worker S_and_T_only string `supported_build_releases:"S-Tiramisu"` 137*333d2b36SAndroid Build Coastguard Worker T_later string `supported_build_releases:"Tiramisu+"` 138*333d2b36SAndroid Build Coastguard Worker Nested nested 139*333d2b36SAndroid Build Coastguard Worker Mapped map[string]*mapped 140*333d2b36SAndroid Build Coastguard Worker } 141*333d2b36SAndroid Build Coastguard Worker 142*333d2b36SAndroid Build Coastguard Worker inputFactory := func() testBuildReleasePruner { 143*333d2b36SAndroid Build Coastguard Worker return testBuildReleasePruner{ 144*333d2b36SAndroid Build Coastguard Worker Default: "Default", 145*333d2b36SAndroid Build Coastguard Worker S_and_T_only: "S_and_T_only", 146*333d2b36SAndroid Build Coastguard Worker T_later: "T_later", 147*333d2b36SAndroid Build Coastguard Worker Nested: nested{ 148*333d2b36SAndroid Build Coastguard Worker F1_only: "F1_only", 149*333d2b36SAndroid Build Coastguard Worker }, 150*333d2b36SAndroid Build Coastguard Worker Mapped: map[string]*mapped{ 151*333d2b36SAndroid Build Coastguard Worker "one": { 152*333d2b36SAndroid Build Coastguard Worker Default: "one-default", 153*333d2b36SAndroid Build Coastguard Worker T_only: "one-t-only", 154*333d2b36SAndroid Build Coastguard Worker }, 155*333d2b36SAndroid Build Coastguard Worker "two": { 156*333d2b36SAndroid Build Coastguard Worker Default: "two-default", 157*333d2b36SAndroid Build Coastguard Worker T_only: "two-t-only", 158*333d2b36SAndroid Build Coastguard Worker }, 159*333d2b36SAndroid Build Coastguard Worker }, 160*333d2b36SAndroid Build Coastguard Worker } 161*333d2b36SAndroid Build Coastguard Worker } 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker marshal := func(t interface{}) string { 164*333d2b36SAndroid Build Coastguard Worker bytes, err := json.MarshalIndent(t, "", " ") 165*333d2b36SAndroid Build Coastguard Worker if err != nil { 166*333d2b36SAndroid Build Coastguard Worker panic(err) 167*333d2b36SAndroid Build Coastguard Worker } 168*333d2b36SAndroid Build Coastguard Worker return string(bytes) 169*333d2b36SAndroid Build Coastguard Worker } 170*333d2b36SAndroid Build Coastguard Worker 171*333d2b36SAndroid Build Coastguard Worker assertJsonEquals := func(t *testing.T, expected, actual interface{}) { 172*333d2b36SAndroid Build Coastguard Worker t.Helper() 173*333d2b36SAndroid Build Coastguard Worker expectedJson := marshal(expected) 174*333d2b36SAndroid Build Coastguard Worker actualJson := marshal(actual) 175*333d2b36SAndroid Build Coastguard Worker if actualJson != expectedJson { 176*333d2b36SAndroid Build Coastguard Worker t.Errorf("test struct: expected:\n%s\n got:\n%s", expectedJson, actualJson) 177*333d2b36SAndroid Build Coastguard Worker } 178*333d2b36SAndroid Build Coastguard Worker } 179*333d2b36SAndroid Build Coastguard Worker 180*333d2b36SAndroid Build Coastguard Worker t.Run("target S", func(t *testing.T) { 181*333d2b36SAndroid Build Coastguard Worker testStruct := inputFactory() 182*333d2b36SAndroid Build Coastguard Worker pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseS) 183*333d2b36SAndroid Build Coastguard Worker pruner.pruneProperties(&testStruct) 184*333d2b36SAndroid Build Coastguard Worker 185*333d2b36SAndroid Build Coastguard Worker expected := inputFactory() 186*333d2b36SAndroid Build Coastguard Worker expected.T_later = "" 187*333d2b36SAndroid Build Coastguard Worker expected.Nested.F1_only = "" 188*333d2b36SAndroid Build Coastguard Worker expected.Mapped["one"].T_only = "" 189*333d2b36SAndroid Build Coastguard Worker expected.Mapped["two"].T_only = "" 190*333d2b36SAndroid Build Coastguard Worker assertJsonEquals(t, expected, testStruct) 191*333d2b36SAndroid Build Coastguard Worker }) 192*333d2b36SAndroid Build Coastguard Worker 193*333d2b36SAndroid Build Coastguard Worker t.Run("target T", func(t *testing.T) { 194*333d2b36SAndroid Build Coastguard Worker testStruct := inputFactory() 195*333d2b36SAndroid Build Coastguard Worker pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseT) 196*333d2b36SAndroid Build Coastguard Worker pruner.pruneProperties(&testStruct) 197*333d2b36SAndroid Build Coastguard Worker 198*333d2b36SAndroid Build Coastguard Worker expected := inputFactory() 199*333d2b36SAndroid Build Coastguard Worker expected.Nested.F1_only = "" 200*333d2b36SAndroid Build Coastguard Worker assertJsonEquals(t, expected, testStruct) 201*333d2b36SAndroid Build Coastguard Worker }) 202*333d2b36SAndroid Build Coastguard Worker 203*333d2b36SAndroid Build Coastguard Worker t.Run("target F1", func(t *testing.T) { 204*333d2b36SAndroid Build Coastguard Worker testStruct := inputFactory() 205*333d2b36SAndroid Build Coastguard Worker pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseFuture1) 206*333d2b36SAndroid Build Coastguard Worker pruner.pruneProperties(&testStruct) 207*333d2b36SAndroid Build Coastguard Worker 208*333d2b36SAndroid Build Coastguard Worker expected := inputFactory() 209*333d2b36SAndroid Build Coastguard Worker expected.S_and_T_only = "" 210*333d2b36SAndroid Build Coastguard Worker expected.Mapped["one"].T_only = "" 211*333d2b36SAndroid Build Coastguard Worker expected.Mapped["two"].T_only = "" 212*333d2b36SAndroid Build Coastguard Worker assertJsonEquals(t, expected, testStruct) 213*333d2b36SAndroid Build Coastguard Worker }) 214*333d2b36SAndroid Build Coastguard Worker 215*333d2b36SAndroid Build Coastguard Worker t.Run("target F2", func(t *testing.T) { 216*333d2b36SAndroid Build Coastguard Worker testStruct := inputFactory() 217*333d2b36SAndroid Build Coastguard Worker pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseFuture2) 218*333d2b36SAndroid Build Coastguard Worker pruner.pruneProperties(&testStruct) 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Worker expected := inputFactory() 221*333d2b36SAndroid Build Coastguard Worker expected.S_and_T_only = "" 222*333d2b36SAndroid Build Coastguard Worker expected.Nested.F1_only = "" 223*333d2b36SAndroid Build Coastguard Worker expected.Mapped["one"].T_only = "" 224*333d2b36SAndroid Build Coastguard Worker expected.Mapped["two"].T_only = "" 225*333d2b36SAndroid Build Coastguard Worker assertJsonEquals(t, expected, testStruct) 226*333d2b36SAndroid Build Coastguard Worker }) 227*333d2b36SAndroid Build Coastguard Worker} 228