blob: f003314ba839d08f5296cd8fa6bbb6226f9cc241 [file] [log] [blame]
Bob Badour9ee7d032021-10-25 16:51:48 -07001// Copyright 2021 Google LLC
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 compliance
16
17import (
18 "bytes"
19 "fmt"
20 "sort"
21 "strings"
22 "testing"
Bob Badourdc62de42022-10-12 20:10:17 -070023
24 "android/soong/tools/compliance/testfs"
Bob Badour9ee7d032021-10-25 16:51:48 -070025)
26
27func TestPolicy_edgeConditions(t *testing.T) {
28 tests := []struct {
29 name string
30 edge annotated
31 treatAsAggregate bool
32 otherCondition string
33 expectedDepActions []string
34 expectedTargetConditions []string
35 }{
36 {
37 name: "firstparty",
38 edge: annotated{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -080039 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -070040 expectedTargetConditions: []string{},
41 },
42 {
43 name: "notice",
44 edge: annotated{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -080045 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -070046 expectedTargetConditions: []string{},
47 },
48 {
49 name: "fponlgpl",
50 edge: annotated{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
51 expectedDepActions: []string{
Bob Badourcac8a3c2022-11-22 12:04:10 -080052 "apacheBin.meta_lic:lgplLib.meta_lic:restricted_if_statically_linked",
53 "lgplLib.meta_lic:lgplLib.meta_lic:restricted_if_statically_linked",
Bob Badour9ee7d032021-10-25 16:51:48 -070054 },
55 expectedTargetConditions: []string{},
56 },
57 {
58 name: "fponlgpldynamic",
59 edge: annotated{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
60 expectedDepActions: []string{},
61 expectedTargetConditions: []string{},
62 },
63 {
64 name: "fpongpl",
65 edge: annotated{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
66 expectedDepActions: []string{
67 "apacheBin.meta_lic:gplLib.meta_lic:restricted",
68 "gplLib.meta_lic:gplLib.meta_lic:restricted",
69 },
70 expectedTargetConditions: []string{},
71 },
72 {
73 name: "fpongpldynamic",
74 edge: annotated{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
75 expectedDepActions: []string{
76 "apacheBin.meta_lic:gplLib.meta_lic:restricted",
77 "gplLib.meta_lic:gplLib.meta_lic:restricted",
78 },
79 expectedTargetConditions: []string{},
80 },
81 {
82 name: "independentmodule",
83 edge: annotated{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
84 expectedDepActions: []string{},
85 expectedTargetConditions: []string{},
86 },
87 {
Bob Badourcac8a3c2022-11-22 12:04:10 -080088 name: "independentmodulestatic",
89 edge: annotated{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
90 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -070091 expectedTargetConditions: []string{},
92 },
93 {
Bob Badourcac8a3c2022-11-22 12:04:10 -080094 name: "dependentmodule",
95 edge: annotated{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
96 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -070097 expectedTargetConditions: []string{},
98 },
99
100 {
101 name: "lgplonfp",
102 edge: annotated{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800103 expectedDepActions: []string{},
Bob Badourcac8a3c2022-11-22 12:04:10 -0800104 expectedTargetConditions: []string{"lgplBin.meta_lic:restricted_if_statically_linked"},
Bob Badour9ee7d032021-10-25 16:51:48 -0700105 },
106 {
107 name: "lgplonfpdynamic",
108 edge: annotated{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
109 expectedDepActions: []string{},
110 expectedTargetConditions: []string{},
111 },
112 {
113 name: "gplonfp",
114 edge: annotated{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800115 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700116 expectedTargetConditions: []string{"gplBin.meta_lic:restricted"},
117 },
118 {
119 name: "gplcontainer",
120 edge: annotated{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
121 treatAsAggregate: true,
Bob Badour103eb0f2022-01-10 13:50:57 -0800122 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700123 expectedTargetConditions: []string{"gplContainer.meta_lic:restricted"},
124 },
125 {
126 name: "gploncontainer",
127 edge: annotated{"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
128 treatAsAggregate: true,
129 otherCondition: "gplLib.meta_lic:restricted",
130 expectedDepActions: []string{
131 "apacheContainer.meta_lic:gplLib.meta_lic:restricted",
Bob Badour9ee7d032021-10-25 16:51:48 -0700132 "apacheLib.meta_lic:gplLib.meta_lic:restricted",
133 "gplLib.meta_lic:gplLib.meta_lic:restricted",
134 },
135 expectedTargetConditions: []string{},
136 },
137 {
138 name: "gplonbin",
139 edge: annotated{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
140 treatAsAggregate: false,
141 otherCondition: "gplLib.meta_lic:restricted",
142 expectedDepActions: []string{
143 "apacheBin.meta_lic:gplLib.meta_lic:restricted",
Bob Badour9ee7d032021-10-25 16:51:48 -0700144 "apacheLib.meta_lic:gplLib.meta_lic:restricted",
145 "gplLib.meta_lic:gplLib.meta_lic:restricted",
146 },
147 expectedTargetConditions: []string{"gplLib.meta_lic:restricted"},
148 },
149 {
150 name: "gplonfpdynamic",
151 edge: annotated{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
152 expectedDepActions: []string{},
153 expectedTargetConditions: []string{"gplBin.meta_lic:restricted"},
154 },
155 {
156 name: "independentmodulereverse",
157 edge: annotated{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
158 expectedDepActions: []string{},
159 expectedTargetConditions: []string{},
160 },
161 {
162 name: "independentmodulereversestatic",
163 edge: annotated{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800164 expectedDepActions: []string{},
Bob Badour10f5c482022-09-20 21:44:17 -0700165 expectedTargetConditions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700166 },
167 {
168 name: "dependentmodulereverse",
169 edge: annotated{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
170 expectedDepActions: []string{},
Bob Badour10f5c482022-09-20 21:44:17 -0700171 expectedTargetConditions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700172 },
173 {
174 name: "ponr",
175 edge: annotated{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
176 expectedDepActions: []string{
177 "proprietary.meta_lic:gplLib.meta_lic:restricted",
178 "gplLib.meta_lic:gplLib.meta_lic:restricted",
179 },
180 expectedTargetConditions: []string{},
181 },
182 {
183 name: "ronp",
184 edge: annotated{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800185 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700186 expectedTargetConditions: []string{"gplBin.meta_lic:restricted"},
187 },
188 {
189 name: "noticeonb_e_o",
190 edge: annotated{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800191 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700192 expectedTargetConditions: []string{},
193 },
194 {
195 name: "b_e_oonnotice",
196 edge: annotated{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800197 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700198 expectedTargetConditions: []string{},
199 },
200 {
201 name: "noticeonrecip",
202 edge: annotated{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800203 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700204 expectedTargetConditions: []string{},
205 },
206 {
207 name: "reciponnotice",
208 edge: annotated{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
Bob Badour103eb0f2022-01-10 13:50:57 -0800209 expectedDepActions: []string{},
Bob Badour9ee7d032021-10-25 16:51:48 -0700210 expectedTargetConditions: []string{},
211 },
212 }
213 for _, tt := range tests {
214 t.Run(tt.name, func(t *testing.T) {
Bob Badourdc62de42022-10-12 20:10:17 -0700215 fs := make(testfs.TestFS)
Bob Badour9ee7d032021-10-25 16:51:48 -0700216 stderr := &bytes.Buffer{}
217 target := meta[tt.edge.target] + fmt.Sprintf("deps: {\n file: \"%s\"\n", tt.edge.dep)
218 for _, ann := range tt.edge.annotations {
219 target += fmt.Sprintf(" annotations: \"%s\"\n", ann)
220 }
221 fs[tt.edge.target] = []byte(target + "}\n")
222 fs[tt.edge.dep] = []byte(meta[tt.edge.dep])
223 lg, err := ReadLicenseGraph(&fs, stderr, []string{tt.edge.target})
224 if err != nil {
Colin Cross179ec3e2022-01-27 15:47:09 -0800225 t.Errorf("unexpected error reading graph: %s", err)
Bob Badour9ee7d032021-10-25 16:51:48 -0700226 return
227 }
Bob Badour103eb0f2022-01-10 13:50:57 -0800228 edge := lg.Edges()[0]
Bob Badour9ee7d032021-10-25 16:51:48 -0700229 // simulate a condition inherited from another edge/dependency.
230 otherTarget := ""
231 otherCondition := ""
Bob Badour103eb0f2022-01-10 13:50:57 -0800232 var otn *TargetNode
Bob Badour9ee7d032021-10-25 16:51:48 -0700233 if len(tt.otherCondition) > 0 {
234 fields := strings.Split(tt.otherCondition, ":")
235 otherTarget = fields[0]
236 otherCondition = fields[1]
Bob Badour103eb0f2022-01-10 13:50:57 -0800237 otn = &TargetNode{name: otherTarget}
Bob Badour9ee7d032021-10-25 16:51:48 -0700238 // other target must exist in graph
Bob Badour103eb0f2022-01-10 13:50:57 -0800239 lg.targets[otherTarget] = otn
240 otn.licenseConditions = LicenseConditionSet(RecognizedConditionNames[otherCondition])
241 }
242 targets := make(map[string]*TargetNode)
243 targets[edge.target.name] = edge.target
244 targets[edge.dependency.name] = edge.dependency
245 if otn != nil {
246 targets[otn.name] = otn
Bob Badour9ee7d032021-10-25 16:51:48 -0700247 }
248 if tt.expectedDepActions != nil {
Bob Badour103eb0f2022-01-10 13:50:57 -0800249 t.Run("depConditionsPropagatingToTarget", func(t *testing.T) {
250 depConditions := edge.dependency.LicenseConditions()
251 if otherTarget != "" {
252 // simulate a sub-dependency's condition having already propagated up to dep and about to go to target
253 otherCs := otn.LicenseConditions()
254 depConditions |= otherCs
Bob Badour9ee7d032021-10-25 16:51:48 -0700255 }
Bob Badour10f5c482022-09-20 21:44:17 -0700256 t.Logf("calculate target actions for edge=%s, dep conditions=%#v %s, treatAsAggregate=%v", edge.String(), depConditions, depConditions, tt.treatAsAggregate)
Bob Badour103eb0f2022-01-10 13:50:57 -0800257 csActual := depConditionsPropagatingToTarget(lg, edge, depConditions, tt.treatAsAggregate)
Bob Badour10f5c482022-09-20 21:44:17 -0700258 t.Logf("calculated target conditions as %#v %s", csActual, csActual)
Bob Badour103eb0f2022-01-10 13:50:57 -0800259 csExpected := NewLicenseConditionSet()
260 for _, triple := range tt.expectedDepActions {
261 fields := strings.Split(triple, ":")
262 expectedConditions := NewLicenseConditionSet()
263 for _, cname := range fields[2:] {
264 expectedConditions = expectedConditions.Plus(RecognizedConditionNames[cname])
265 }
266 csExpected |= expectedConditions
267 }
Bob Badour10f5c482022-09-20 21:44:17 -0700268 t.Logf("expected target conditions as %#v %s", csExpected, csExpected)
Bob Badour103eb0f2022-01-10 13:50:57 -0800269 if csActual != csExpected {
Bob Badour10f5c482022-09-20 21:44:17 -0700270 t.Errorf("unexpected license conditions: got %#v, want %#v", csActual, csExpected)
Bob Badour103eb0f2022-01-10 13:50:57 -0800271 }
272 })
Bob Badour9ee7d032021-10-25 16:51:48 -0700273 }
274 if tt.expectedTargetConditions != nil {
Bob Badour103eb0f2022-01-10 13:50:57 -0800275 t.Run("targetConditionsPropagatingToDep", func(t *testing.T) {
276 targetConditions := edge.target.LicenseConditions()
277 if otherTarget != "" {
278 targetConditions = targetConditions.Union(otn.licenseConditions)
279 }
280 t.Logf("calculate dep conditions for edge=%s, target conditions=%v, treatAsAggregate=%v", edge.String(), targetConditions.Names(), tt.treatAsAggregate)
Bob Badourc8178452022-01-31 13:05:53 -0800281 cs := targetConditionsPropagatingToDep(lg, edge, targetConditions, tt.treatAsAggregate, AllResolutions)
Bob Badour103eb0f2022-01-10 13:50:57 -0800282 t.Logf("calculated dep conditions as %v", cs.Names())
283 actual := cs.Names()
284 sort.Strings(actual)
285 expected := make([]string, 0)
286 for _, expectedDepCondition := range tt.expectedTargetConditions {
287 expected = append(expected, strings.Split(expectedDepCondition, ":")[1])
288 }
289 sort.Strings(expected)
290 if len(actual) != len(expected) {
291 t.Errorf("unexpected number of target conditions: got %v with %d conditions, want %v with %d conditions",
292 actual, len(actual), expected, len(expected))
293 } else {
294 for i := 0; i < len(actual); i++ {
295 if actual[i] != expected[i] {
296 t.Errorf("unexpected target condition at element %d: got %q, want %q",
297 i, actual[i], expected[i])
298 }
Bob Badour9ee7d032021-10-25 16:51:48 -0700299 }
300 }
Bob Badour103eb0f2022-01-10 13:50:57 -0800301 })
Bob Badour9ee7d032021-10-25 16:51:48 -0700302 }
303 })
304 }
305}