xref: /aosp_15_r20/build/make/tools/compliance/policy_resolve_test.go (revision 9e94795a3d4ef5c1d47486f9a02bb378756cea8a)
1// 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	"sort"
20	"testing"
21)
22
23func TestResolveBottomUpConditions(t *testing.T) {
24	tests := []struct {
25		name            string
26		roots           []string
27		edges           []annotated
28		expectedActions []tcond
29	}{
30		{
31			name:  "firstparty",
32			roots: []string{"apacheBin.meta_lic"},
33			edges: []annotated{
34				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
35			},
36			expectedActions: []tcond{
37				{"apacheBin.meta_lic", "notice"},
38				{"apacheLib.meta_lic", "notice"},
39			},
40		},
41		{
42			name:  "firstpartytool",
43			roots: []string{"apacheBin.meta_lic"},
44			edges: []annotated{
45				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"toolchain"}},
46			},
47			expectedActions: []tcond{
48				{"apacheBin.meta_lic", "notice"},
49				{"apacheLib.meta_lic", "notice"},
50			},
51		},
52		{
53			name:  "firstpartydeep",
54			roots: []string{"apacheContainer.meta_lic"},
55			edges: []annotated{
56				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
57				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
58			},
59			expectedActions: []tcond{
60				{"apacheContainer.meta_lic", "notice"},
61				{"apacheBin.meta_lic", "notice"},
62				{"apacheLib.meta_lic", "notice"},
63			},
64		},
65		{
66			name:  "firstpartywide",
67			roots: []string{"apacheContainer.meta_lic"},
68			edges: []annotated{
69				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
70				{"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
71			},
72			expectedActions: []tcond{
73				{"apacheContainer.meta_lic", "notice"},
74				{"apacheBin.meta_lic", "notice"},
75				{"apacheLib.meta_lic", "notice"},
76			},
77		},
78		{
79			name:  "firstpartydynamic",
80			roots: []string{"apacheBin.meta_lic"},
81			edges: []annotated{
82				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
83			},
84			expectedActions: []tcond{
85				{"apacheBin.meta_lic", "notice"},
86				{"apacheLib.meta_lic", "notice"},
87			},
88		},
89		{
90			name:  "firstpartydynamicdeep",
91			roots: []string{"apacheContainer.meta_lic"},
92			edges: []annotated{
93				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
94				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
95			},
96			expectedActions: []tcond{
97				{"apacheContainer.meta_lic", "notice"},
98				{"apacheBin.meta_lic", "notice"},
99				{"apacheLib.meta_lic", "notice"},
100			},
101		},
102		{
103			name:  "firstpartydynamicwide",
104			roots: []string{"apacheContainer.meta_lic"},
105			edges: []annotated{
106				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
107				{"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
108			},
109			expectedActions: []tcond{
110				{"apacheContainer.meta_lic", "notice"},
111				{"apacheBin.meta_lic", "notice"},
112				{"apacheLib.meta_lic", "notice"},
113			},
114		},
115		{
116			name:  "restricted",
117			roots: []string{"apacheBin.meta_lic"},
118			edges: []annotated{
119				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
120			},
121			expectedActions: []tcond{
122				{"apacheBin.meta_lic", "notice|restricted"},
123				{"gplLib.meta_lic", "restricted"},
124			},
125		},
126		{
127			name:  "restrictedtool",
128			roots: []string{"apacheBin.meta_lic"},
129			edges: []annotated{
130				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"toolchain"}},
131			},
132			expectedActions: []tcond{
133				{"apacheBin.meta_lic", "notice"},
134				{"gplLib.meta_lic", "restricted"},
135			},
136		},
137		{
138			name:  "restricteddeep",
139			roots: []string{"apacheContainer.meta_lic"},
140			edges: []annotated{
141				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
142				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
143			},
144			expectedActions: []tcond{
145				{"apacheContainer.meta_lic", "notice|restricted"},
146				{"apacheBin.meta_lic", "notice|restricted"},
147				{"gplLib.meta_lic", "restricted"},
148			},
149		},
150		{
151			name:  "restrictedwide",
152			roots: []string{"apacheContainer.meta_lic"},
153			edges: []annotated{
154				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
155				{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
156			},
157			expectedActions: []tcond{
158				{"apacheContainer.meta_lic", "notice|restricted"},
159				{"apacheBin.meta_lic", "notice"},
160				{"gplLib.meta_lic", "restricted"},
161			},
162		},
163		{
164			name:  "restricteddynamic",
165			roots: []string{"apacheBin.meta_lic"},
166			edges: []annotated{
167				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
168			},
169			expectedActions: []tcond{
170				{"apacheBin.meta_lic", "notice|restricted"},
171				{"gplLib.meta_lic", "restricted"},
172			},
173		},
174		{
175			name:  "restricteddynamicdeep",
176			roots: []string{"apacheContainer.meta_lic"},
177			edges: []annotated{
178				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
179				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
180			},
181			expectedActions: []tcond{
182				{"apacheContainer.meta_lic", "notice|restricted"},
183				{"apacheBin.meta_lic", "notice|restricted"},
184				{"gplLib.meta_lic", "restricted"},
185			},
186		},
187		{
188			name:  "restricteddynamicwide",
189			roots: []string{"apacheContainer.meta_lic"},
190			edges: []annotated{
191				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
192				{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
193			},
194			expectedActions: []tcond{
195				{"apacheContainer.meta_lic", "notice|restricted"},
196				{"apacheBin.meta_lic", "notice"},
197				{"gplLib.meta_lic", "restricted"},
198			},
199		},
200		{
201			name:  "weakrestricted",
202			roots: []string{"apacheBin.meta_lic"},
203			edges: []annotated{
204				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
205			},
206			expectedActions: []tcond{
207				{"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
208				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
209			},
210		},
211		{
212			name:  "weakrestrictedtool",
213			roots: []string{"apacheBin.meta_lic"},
214			edges: []annotated{
215				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"toolchain"}},
216			},
217			expectedActions: []tcond{
218				{"apacheBin.meta_lic", "notice"},
219				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
220			},
221		},
222		{
223			name:  "weakrestricteddeep",
224			roots: []string{"apacheContainer.meta_lic"},
225			edges: []annotated{
226				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
227				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
228			},
229			expectedActions: []tcond{
230				{"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
231				{"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
232				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
233			},
234		},
235		{
236			name:  "weakrestrictedwide",
237			roots: []string{"apacheContainer.meta_lic"},
238			edges: []annotated{
239				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
240				{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
241			},
242			expectedActions: []tcond{
243				{"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
244				{"apacheBin.meta_lic", "notice"},
245				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
246			},
247		},
248		{
249			name:  "weakrestricteddynamic",
250			roots: []string{"apacheBin.meta_lic"},
251			edges: []annotated{
252				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
253			},
254			expectedActions: []tcond{
255				{"apacheBin.meta_lic", "notice"},
256				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
257			},
258		},
259		{
260			name:  "weakrestricteddynamicdeep",
261			roots: []string{"apacheContainer.meta_lic"},
262			edges: []annotated{
263				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
264				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
265			},
266			expectedActions: []tcond{
267				{"apacheContainer.meta_lic", "notice"},
268				{"apacheBin.meta_lic", "notice"},
269				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
270			},
271		},
272		{
273			name:  "weakrestricteddynamicwide",
274			roots: []string{"apacheContainer.meta_lic"},
275			edges: []annotated{
276				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
277				{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
278			},
279			expectedActions: []tcond{
280				{"apacheContainer.meta_lic", "notice"},
281				{"apacheBin.meta_lic", "notice"},
282				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
283			},
284		},
285		{
286			name:  "classpath",
287			roots: []string{"apacheBin.meta_lic"},
288			edges: []annotated{
289				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
290			},
291			expectedActions: []tcond{
292				{"apacheBin.meta_lic", "notice"},
293				{"gplWithClasspathException.meta_lic", "permissive"},
294			},
295		},
296		{
297			name:  "classpathdependent",
298			roots: []string{"dependentModule.meta_lic"},
299			edges: []annotated{
300				{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
301			},
302			expectedActions: []tcond{
303				{"dependentModule.meta_lic", "notice"},
304				{"gplWithClasspathException.meta_lic", "permissive"},
305			},
306		},
307		{
308			name:  "classpathdynamic",
309			roots: []string{"apacheBin.meta_lic"},
310			edges: []annotated{
311				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
312			},
313			expectedActions: []tcond{
314				{"apacheBin.meta_lic", "notice"},
315				{"gplWithClasspathException.meta_lic", "permissive"},
316			},
317		},
318		{
319			name:  "classpathdependentdynamic",
320			roots: []string{"dependentModule.meta_lic"},
321			edges: []annotated{
322				{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
323			},
324			expectedActions: []tcond{
325				{"dependentModule.meta_lic", "notice"},
326				{"gplWithClasspathException.meta_lic", "permissive"},
327			},
328		},
329	}
330	for _, tt := range tests {
331		t.Run(tt.name, func(t *testing.T) {
332			stderr := &bytes.Buffer{}
333			lg, err := toGraph(stderr, tt.roots, tt.edges)
334			if err != nil {
335				t.Errorf("unexpected test data error: got %s, want no error", err)
336				return
337			}
338
339			logGraph(lg, t)
340
341			ResolveBottomUpConditions(lg)
342			actual := asActionList(lg)
343			sort.Sort(actual)
344			t.Logf("actual: %s", actual.String())
345
346			expected := toActionList(lg, tt.expectedActions)
347			sort.Sort(expected)
348			t.Logf("expected: %s", expected.String())
349
350			if len(actual) != len(expected) {
351				t.Errorf("unexpected number of actions: got %d, want %d", len(actual), len(expected))
352				return
353			}
354			for i := 0; i < len(actual); i++ {
355				if actual[i] != expected[i] {
356					t.Errorf("unexpected action at index %d: got %s, want %s", i, actual[i].String(), expected[i].String())
357				}
358			}
359		})
360	}
361}
362
363func TestResolveTopDownConditions(t *testing.T) {
364	tests := []struct {
365		name            string
366		roots           []string
367		edges           []annotated
368		expectedActions []tcond
369	}{
370		{
371			name:  "firstparty",
372			roots: []string{"apacheBin.meta_lic"},
373			edges: []annotated{
374				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
375			},
376			expectedActions: []tcond{
377				{"apacheBin.meta_lic", "notice"},
378				{"apacheLib.meta_lic", "notice"},
379			},
380		},
381		{
382			name:  "firstpartydynamic",
383			roots: []string{"apacheBin.meta_lic"},
384			edges: []annotated{
385				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
386			},
387			expectedActions: []tcond{
388				{"apacheBin.meta_lic", "notice"},
389				{"apacheLib.meta_lic", "notice"},
390			},
391		},
392		{
393			name:  "restricted",
394			roots: []string{"apacheBin.meta_lic"},
395			edges: []annotated{
396				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
397				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
398			},
399			expectedActions: []tcond{
400				{"apacheBin.meta_lic", "notice|restricted"},
401				{"mitLib.meta_lic", "notice|restricted"},
402				{"gplLib.meta_lic", "restricted"},
403			},
404		},
405		{
406			name:  "restrictedtool",
407			roots: []string{"apacheBin.meta_lic"},
408			edges: []annotated{
409				{"apacheBin.meta_lic", "gplBin.meta_lic", []string{"toolchain"}},
410				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
411			},
412			expectedActions: []tcond{
413				{"apacheBin.meta_lic", "notice"},
414				{"mitLib.meta_lic", "notice"},
415				{"gplBin.meta_lic", "restricted"},
416			},
417		},
418		{
419			name:  "restricteddeep",
420			roots: []string{"apacheContainer.meta_lic"},
421			edges: []annotated{
422				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
423				{"apacheContainer.meta_lic", "mitBin.meta_lic", []string{"static"}},
424				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
425				{"apacheBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
426				{"mitBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
427			},
428			expectedActions: []tcond{
429				{"apacheContainer.meta_lic", "notice|restricted"},
430				{"apacheBin.meta_lic", "notice|restricted"},
431				{"mitBin.meta_lic", "notice"},
432				{"gplLib.meta_lic", "restricted"},
433				{"mplLib.meta_lic", "reciprocal|restricted"},
434				{"mitLib.meta_lic", "notice"},
435			},
436		},
437		{
438			name:  "restrictedwide",
439			roots: []string{"apacheContainer.meta_lic"},
440			edges: []annotated{
441				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
442				{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
443			},
444			expectedActions: []tcond{
445				{"apacheContainer.meta_lic", "notice|restricted"},
446				{"apacheBin.meta_lic", "notice"},
447				{"gplLib.meta_lic", "restricted"},
448			},
449		},
450		{
451			name:  "restricteddynamic",
452			roots: []string{"apacheBin.meta_lic"},
453			edges: []annotated{
454				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
455				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
456			},
457			expectedActions: []tcond{
458				{"apacheBin.meta_lic", "notice|restricted"},
459				{"gplLib.meta_lic", "restricted"},
460				{"mitLib.meta_lic", "notice|restricted"},
461			},
462		},
463		{
464			name:  "restricteddynamicdeep",
465			roots: []string{"apacheContainer.meta_lic"},
466			edges: []annotated{
467				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
468				{"apacheContainer.meta_lic", "mitBin.meta_lic", []string{"static"}},
469				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
470				{"apacheBin.meta_lic", "mplLib.meta_lic", []string{"dynamic"}},
471				{"mitBin.meta_lic", "mitLib.meta_lic", []string{"dynamic"}},
472			},
473			expectedActions: []tcond{
474				{"apacheContainer.meta_lic", "notice|restricted"},
475				{"apacheBin.meta_lic", "notice|restricted"},
476				{"mitBin.meta_lic", "notice"},
477				{"gplLib.meta_lic", "restricted"},
478				{"mplLib.meta_lic", "reciprocal|restricted"},
479				{"mitLib.meta_lic", "notice"},
480			},
481		},
482		{
483			name:  "restricteddynamicwide",
484			roots: []string{"apacheContainer.meta_lic"},
485			edges: []annotated{
486				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
487				{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"dynamic"}},
488			},
489			expectedActions: []tcond{
490				{"apacheContainer.meta_lic", "notice|restricted"},
491				{"apacheBin.meta_lic", "notice"},
492				{"gplLib.meta_lic", "restricted"},
493			},
494		},
495		{
496			name:  "weakrestricted",
497			roots: []string{"apacheBin.meta_lic"},
498			edges: []annotated{
499				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
500				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
501			},
502			expectedActions: []tcond{
503				{"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
504				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
505				{"mitLib.meta_lic", "notice|restricted_if_statically_linked"},
506			},
507		},
508		{
509			name:  "weakrestrictedtool",
510			roots: []string{"apacheBin.meta_lic"},
511			edges: []annotated{
512				{"apacheBin.meta_lic", "lgplBin.meta_lic", []string{"toolchain"}},
513				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
514			},
515			expectedActions: []tcond{
516				{"apacheBin.meta_lic", "notice"},
517				{"lgplBin.meta_lic", "restricted_if_statically_linked"},
518				{"mitLib.meta_lic", "notice"},
519			},
520		},
521		{
522			name:  "weakrestricteddeep",
523			roots: []string{"apacheContainer.meta_lic"},
524			edges: []annotated{
525				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
526				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"static"}},
527				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
528			},
529			expectedActions: []tcond{
530				{"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
531				{"apacheBin.meta_lic", "notice|restricted_if_statically_linked"},
532				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
533				{"mitLib.meta_lic", "notice|restricted_if_statically_linked"},
534			},
535		},
536		{
537			name:  "weakrestrictedwide",
538			roots: []string{"apacheContainer.meta_lic"},
539			edges: []annotated{
540				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
541				{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"static"}},
542			},
543			expectedActions: []tcond{
544				{"apacheContainer.meta_lic", "notice|restricted_if_statically_linked"},
545				{"apacheBin.meta_lic", "notice"},
546				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
547			},
548		},
549		{
550			name:  "weakrestricteddynamic",
551			roots: []string{"apacheBin.meta_lic"},
552			edges: []annotated{
553				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
554				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
555			},
556			expectedActions: []tcond{
557				{"apacheBin.meta_lic", "notice"},
558				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
559				{"mitLib.meta_lic", "notice"},
560			},
561		},
562		{
563			name:  "weakrestricteddynamicdeep",
564			roots: []string{"apacheContainer.meta_lic"},
565			edges: []annotated{
566				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
567				{"apacheBin.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
568			},
569			expectedActions: []tcond{
570				{"apacheContainer.meta_lic", "notice"},
571				{"apacheBin.meta_lic", "notice"},
572				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
573			},
574		},
575		{
576			name:  "weakrestricteddynamicwide",
577			roots: []string{"apacheContainer.meta_lic"},
578			edges: []annotated{
579				{"apacheContainer.meta_lic", "apacheBin.meta_lic", []string{"static"}},
580				{"apacheContainer.meta_lic", "lgplLib.meta_lic", []string{"dynamic"}},
581			},
582			expectedActions: []tcond{
583				{"apacheContainer.meta_lic", "notice"},
584				{"apacheBin.meta_lic", "notice"},
585				{"lgplLib.meta_lic", "restricted_if_statically_linked"},
586			},
587		},
588		{
589			name:  "classpath",
590			roots: []string{"apacheBin.meta_lic"},
591			edges: []annotated{
592				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
593				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
594			},
595			expectedActions: []tcond{
596				{"apacheBin.meta_lic", "notice"},
597				{"gplWithClasspathException.meta_lic", "permissive"},
598				{"mitLib.meta_lic", "notice"},
599			},
600		},
601		{
602			name:  "classpathdependent",
603			roots: []string{"dependentModule.meta_lic"},
604			edges: []annotated{
605				{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
606				{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
607			},
608			expectedActions: []tcond{
609				{"dependentModule.meta_lic", "notice"},
610				{"gplWithClasspathException.meta_lic", "permissive"},
611				{"mitLib.meta_lic", "notice"},
612			},
613		},
614		{
615			name:  "classpathdynamic",
616			roots: []string{"apacheBin.meta_lic"},
617			edges: []annotated{
618				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
619				{"apacheBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
620			},
621			expectedActions: []tcond{
622				{"apacheBin.meta_lic", "notice"},
623				{"gplWithClasspathException.meta_lic", "permissive"},
624				{"mitLib.meta_lic", "notice"},
625			},
626		},
627		{
628			name:  "classpathdependentdynamic",
629			roots: []string{"dependentModule.meta_lic"},
630			edges: []annotated{
631				{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
632				{"dependentModule.meta_lic", "mitLib.meta_lic", []string{"static"}},
633			},
634			expectedActions: []tcond{
635				{"dependentModule.meta_lic", "notice"},
636				{"gplWithClasspathException.meta_lic", "permissive"},
637				{"mitLib.meta_lic", "notice"},
638			},
639		},
640	}
641	for _, tt := range tests {
642		t.Run(tt.name, func(t *testing.T) {
643			stderr := &bytes.Buffer{}
644			lg, err := toGraph(stderr, tt.roots, tt.edges)
645			if err != nil {
646				t.Errorf("unexpected test data error: got %s, want no error", err)
647				return
648			}
649
650			logGraph(lg, t)
651
652			ResolveTopDownConditions(lg)
653			actual := asActionList(lg)
654			sort.Sort(actual)
655			t.Logf("actual: %s", actual.String())
656
657			expected := toActionList(lg, tt.expectedActions)
658			sort.Sort(expected)
659			t.Logf("expected: %s", expected.String())
660
661			if len(actual) != len(expected) {
662				t.Errorf("unexpected number of actions: got %d, want %d", len(actual), len(expected))
663				return
664			}
665			for i := 0; i < len(actual); i++ {
666				if actual[i] != expected[i] {
667					t.Errorf("unexpected action at index %d: got %s, want %s", i, actual[i].String(), expected[i].String())
668				}
669			}
670		})
671	}
672}
673