blob: 0ec10409fefdd105c74bf9bfa8d2d2f4786513fd [file] [log] [blame]
Paul Duffin18122942021-08-24 19:01:25 +01001// Copyright (C) 2021 The Android Open Source Project
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 sdk
16
17import (
Paul Duffin545c5922022-01-27 16:51:51 +000018 "encoding/json"
Paul Duffin18122942021-08-24 19:01:25 +010019 "fmt"
20 "testing"
21
22 "android/soong/android"
23)
24
25// Tests for build_release.go
26
27var (
28 // Some additional test specific releases that are added after the currently supported ones and
29 // so are treated as being for future releases.
30 buildReleaseFuture1 = initBuildRelease("F1")
31 buildReleaseFuture2 = initBuildRelease("F2")
32)
33
34func TestNameToRelease(t *testing.T) {
35 t.Run("single release", func(t *testing.T) {
36 release, err := nameToRelease("S")
37 android.AssertDeepEquals(t, "errors", nil, err)
38 android.AssertDeepEquals(t, "release", buildReleaseS, release)
39 })
40 t.Run("invalid release", func(t *testing.T) {
41 release, err := nameToRelease("A")
42 android.AssertDeepEquals(t, "release", (*buildRelease)(nil), release)
43 // Uses a wildcard in the error message to allow for additional build releases to be added to
44 // the supported set without breaking this test.
45 android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,T.*,F1,F2\]`, []error{err})
46 })
47}
48
49func TestParseBuildReleaseSet(t *testing.T) {
50 t.Run("single release", func(t *testing.T) {
51 set, err := parseBuildReleaseSet("S")
52 android.AssertDeepEquals(t, "errors", nil, err)
53 android.AssertStringEquals(t, "set", "[S]", set.String())
54 })
55 t.Run("open range", func(t *testing.T) {
56 set, err := parseBuildReleaseSet("F1+")
57 android.AssertDeepEquals(t, "errors", nil, err)
58 android.AssertStringEquals(t, "set", "[F1,F2]", set.String())
59 })
60 t.Run("closed range", func(t *testing.T) {
61 set, err := parseBuildReleaseSet("S-F1")
62 android.AssertDeepEquals(t, "errors", nil, err)
63 android.AssertStringEquals(t, "set", "[S,T,F1]", set.String())
64 })
65 invalidAReleaseMessage := `unknown release "A", expected one of ` + allBuildReleaseSet.String()
66 t.Run("invalid release", func(t *testing.T) {
67 set, err := parseBuildReleaseSet("A")
68 android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
69 android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
70 })
71 t.Run("invalid release in open range", func(t *testing.T) {
72 set, err := parseBuildReleaseSet("A+")
73 android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
74 android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
75 })
76 t.Run("invalid release in closed range start", func(t *testing.T) {
77 set, err := parseBuildReleaseSet("A-S")
78 android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
79 android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
80 })
81 t.Run("invalid release in closed range end", func(t *testing.T) {
82 set, err := parseBuildReleaseSet("T-A")
83 android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
84 android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
85 })
86 t.Run("invalid closed range reversed", func(t *testing.T) {
87 set, err := parseBuildReleaseSet("F1-S")
88 android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
89 android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), `invalid closed range, start release "F1" is later than end release "S"`)
90 })
91}
92
93func TestBuildReleaseSetContains(t *testing.T) {
94 t.Run("contains", func(t *testing.T) {
95 set, _ := parseBuildReleaseSet("F1-F2")
96 android.AssertBoolEquals(t, "set contains F1", true, set.contains(buildReleaseFuture1))
97 android.AssertBoolEquals(t, "set does not contain S", false, set.contains(buildReleaseS))
98 android.AssertBoolEquals(t, "set contains F2", true, set.contains(buildReleaseFuture2))
99 android.AssertBoolEquals(t, "set does not contain T", false, set.contains(buildReleaseT))
100 })
101}
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100102
103func TestPropertyPrunerInvalidTag(t *testing.T) {
104 type brokenStruct struct {
105 Broken string `supported_build_releases:"A"`
106 }
107 type containingStruct struct {
108 Nested brokenStruct
109 }
110
111 t.Run("broken struct", func(t *testing.T) {
112 android.AssertPanicMessageContains(t, "error", "invalid `supported_build_releases` tag on Broken of *sdk.brokenStruct: unknown release \"A\"", func() {
113 newPropertyPrunerByBuildRelease(&brokenStruct{}, buildReleaseS)
114 })
115 })
116
117 t.Run("nested broken struct", func(t *testing.T) {
118 android.AssertPanicMessageContains(t, "error", "invalid `supported_build_releases` tag on Nested.Broken of *sdk.containingStruct: unknown release \"A\"", func() {
119 newPropertyPrunerByBuildRelease(&containingStruct{}, buildReleaseS)
120 })
121 })
122}
123
124func TestPropertyPrunerByBuildRelease(t *testing.T) {
125 type nested struct {
126 F1_only string `supported_build_releases:"F1"`
127 }
128
129 type testBuildReleasePruner struct {
130 Default string
131 S_and_T_only string `supported_build_releases:"S-T"`
132 T_later string `supported_build_releases:"T+"`
133 Nested nested
134 }
135
Paul Duffin545c5922022-01-27 16:51:51 +0000136 inputFactory := func() testBuildReleasePruner {
137 return testBuildReleasePruner{
138 Default: "Default",
139 S_and_T_only: "S_and_T_only",
140 T_later: "T_later",
141 Nested: nested{
142 F1_only: "F1_only",
143 },
144 }
145 }
146
147 marshal := func(t interface{}) string {
148 bytes, err := json.MarshalIndent(t, "", " ")
149 if err != nil {
150 panic(err)
151 }
152 return string(bytes)
153 }
154
155 assertJsonEquals := func(t *testing.T, expected, actual interface{}) {
156 t.Helper()
157 expectedJson := marshal(expected)
158 actualJson := marshal(actual)
159 if actualJson != expectedJson {
160 t.Errorf("test struct: expected:\n%s\n got:\n%s", expectedJson, actualJson)
161 }
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100162 }
163
164 t.Run("target S", func(t *testing.T) {
Paul Duffin545c5922022-01-27 16:51:51 +0000165 testStruct := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100166 pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseS)
167 pruner.pruneProperties(&testStruct)
168
Paul Duffin545c5922022-01-27 16:51:51 +0000169 expected := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100170 expected.T_later = ""
171 expected.Nested.F1_only = ""
Paul Duffin545c5922022-01-27 16:51:51 +0000172 assertJsonEquals(t, expected, testStruct)
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100173 })
174
175 t.Run("target T", func(t *testing.T) {
Paul Duffin545c5922022-01-27 16:51:51 +0000176 testStruct := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100177 pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseT)
178 pruner.pruneProperties(&testStruct)
179
Paul Duffin545c5922022-01-27 16:51:51 +0000180 expected := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100181 expected.Nested.F1_only = ""
Paul Duffin545c5922022-01-27 16:51:51 +0000182 assertJsonEquals(t, expected, testStruct)
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100183 })
184
185 t.Run("target F1", func(t *testing.T) {
Paul Duffin545c5922022-01-27 16:51:51 +0000186 testStruct := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100187 pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseFuture1)
188 pruner.pruneProperties(&testStruct)
189
Paul Duffin545c5922022-01-27 16:51:51 +0000190 expected := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100191 expected.S_and_T_only = ""
Paul Duffin545c5922022-01-27 16:51:51 +0000192 assertJsonEquals(t, expected, testStruct)
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100193 })
194
195 t.Run("target F2", func(t *testing.T) {
Paul Duffin545c5922022-01-27 16:51:51 +0000196 testStruct := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100197 pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseFuture2)
198 pruner.pruneProperties(&testStruct)
199
Paul Duffin545c5922022-01-27 16:51:51 +0000200 expected := inputFactory()
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100201 expected.S_and_T_only = ""
202 expected.Nested.F1_only = ""
Paul Duffin545c5922022-01-27 16:51:51 +0000203 assertJsonEquals(t, expected, testStruct)
Paul Duffin0c3acbf2021-08-24 19:01:25 +0100204 })
205}