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	"testing"
20)
21
22func TestResolveSourceSharing(t *testing.T) {
23	tests := []struct {
24		name                string
25		roots               []string
26		edges               []annotated
27		expectedResolutions []res
28	}{
29		{
30			name:  "independentmodulerestricted",
31			roots: []string{"apacheBin.meta_lic"},
32			edges: []annotated{
33				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
34			},
35			expectedResolutions: []res{},
36		},
37		{
38			name:  "independentmodulerestrictedshipped",
39			roots: []string{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic"},
40			edges: []annotated{
41				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
42			},
43			expectedResolutions: []res{},
44		},
45		{
46			name:  "independentmodulestaticrestricted",
47			roots: []string{"apacheBin.meta_lic"},
48			edges: []annotated{
49				{"apacheBin.meta_lic", "gplWithClasspathException.meta_lic", []string{"static"}},
50			},
51			expectedResolutions: []res{},
52		},
53		{
54			name:  "dependentmodulerestricted",
55			roots: []string{"dependentModule.meta_lic"},
56			edges: []annotated{
57				{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
58			},
59			expectedResolutions: []res{},
60		},
61		{
62			name:  "dependentmodulerestrictedshipclasspath",
63			roots: []string{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic"},
64			edges: []annotated{
65				{"dependentModule.meta_lic", "gplWithClasspathException.meta_lic", []string{"dynamic"}},
66			},
67			expectedResolutions: []res{},
68		},
69		{
70			name:  "lgplonfprestricted",
71			roots: []string{"lgplBin.meta_lic"},
72			edges: []annotated{
73				{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
74			},
75			expectedResolutions: []res{
76				{"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
77				{"lgplBin.meta_lic", "apacheLib.meta_lic", "restricted_if_statically_linked"},
78			},
79		},
80		{
81			name:  "lgplonfpdynamicrestricted",
82			roots: []string{"lgplBin.meta_lic"},
83			edges: []annotated{
84				{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
85			},
86			expectedResolutions: []res{
87				{"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
88			},
89		},
90		{
91			name:  "lgplonfpdynamicrestrictedshiplib",
92			roots: []string{"lgplBin.meta_lic", "apacheLib.meta_lic"},
93			edges: []annotated{
94				{"lgplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
95			},
96			expectedResolutions: []res{
97				{"lgplBin.meta_lic", "lgplBin.meta_lic", "restricted_if_statically_linked"},
98			},
99		},
100		{
101			name:  "gplonfprestricted",
102			roots: []string{"gplBin.meta_lic"},
103			edges: []annotated{
104				{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
105			},
106			expectedResolutions: []res{
107				{"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
108				{"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"},
109			},
110		},
111		{
112			name:  "gplcontainerrestricted",
113			roots: []string{"gplContainer.meta_lic"},
114			edges: []annotated{
115				{"gplContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
116			},
117			expectedResolutions: []res{
118				{"gplContainer.meta_lic", "gplContainer.meta_lic", "restricted"},
119				{"gplContainer.meta_lic", "apacheLib.meta_lic", "restricted"},
120				{"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"},
121			},
122		},
123		{
124			name:  "gploncontainerrestricted",
125			roots: []string{"apacheContainer.meta_lic"},
126			edges: []annotated{
127				{"apacheContainer.meta_lic", "apacheLib.meta_lic", []string{"static"}},
128				{"apacheContainer.meta_lic", "gplLib.meta_lic", []string{"static"}},
129			},
130			expectedResolutions: []res{
131				{"apacheContainer.meta_lic", "apacheContainer.meta_lic", "restricted"},
132				{"apacheContainer.meta_lic", "gplLib.meta_lic", "restricted"},
133				{"gplLib.meta_lic", "gplLib.meta_lic", "restricted"},
134			},
135		},
136		{
137			name:  "gplonbinrestricted",
138			roots: []string{"apacheBin.meta_lic"},
139			edges: []annotated{
140				{"apacheBin.meta_lic", "apacheLib.meta_lic", []string{"static"}},
141				{"apacheBin.meta_lic", "gplLib.meta_lic", []string{"static"}},
142			},
143			expectedResolutions: []res{
144				{"apacheBin.meta_lic", "apacheBin.meta_lic", "restricted"},
145				{"apacheBin.meta_lic", "gplLib.meta_lic", "restricted"},
146				{"apacheBin.meta_lic", "apacheLib.meta_lic", "restricted"},
147			},
148		},
149		{
150			name:  "gplonfpdynamicrestricted",
151			roots: []string{"gplBin.meta_lic"},
152			edges: []annotated{
153				{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
154			},
155			expectedResolutions: []res{
156				{"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
157			},
158		},
159		{
160			name:  "gplonfpdynamicrestrictedshiplib",
161			roots: []string{"gplBin.meta_lic", "apacheLib.meta_lic"},
162			edges: []annotated{
163				{"gplBin.meta_lic", "apacheLib.meta_lic", []string{"dynamic"}},
164			},
165			expectedResolutions: []res{
166				{"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
167				{"gplBin.meta_lic", "apacheLib.meta_lic", "restricted"},
168				{"apacheLib.meta_lic", "apacheLib.meta_lic", "restricted"},
169			},
170		},
171		{
172			name:  "independentmodulereverserestricted",
173			roots: []string{"gplWithClasspathException.meta_lic"},
174			edges: []annotated{
175				{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"dynamic"}},
176			},
177			expectedResolutions: []res{},
178		},
179		{
180			name:  "independentmodulereversestaticrestricted",
181			roots: []string{"gplWithClasspathException.meta_lic"},
182			edges: []annotated{
183				{"gplWithClasspathException.meta_lic", "apacheBin.meta_lic", []string{"static"}},
184			},
185			expectedResolutions: []res{},
186		},
187		{
188			name:  "dependentmodulereverserestricted",
189			roots: []string{"gplWithClasspathException.meta_lic"},
190			edges: []annotated{
191				{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
192			},
193			expectedResolutions: []res{},
194		},
195		{
196			name:  "dependentmodulereverserestrictedshipdependent",
197			roots: []string{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic"},
198			edges: []annotated{
199				{"gplWithClasspathException.meta_lic", "dependentModule.meta_lic", []string{"dynamic"}},
200			},
201			expectedResolutions: []res{},
202		},
203		{
204			name:  "ponrrestricted",
205			roots: []string{"proprietary.meta_lic"},
206			edges: []annotated{
207				{"proprietary.meta_lic", "gplLib.meta_lic", []string{"static"}},
208			},
209			expectedResolutions: []res{
210				{"proprietary.meta_lic", "proprietary.meta_lic", "restricted"},
211				{"proprietary.meta_lic", "gplLib.meta_lic", "restricted"},
212			},
213		},
214		{
215			name:  "ronprestricted",
216			roots: []string{"gplBin.meta_lic"},
217			edges: []annotated{
218				{"gplBin.meta_lic", "proprietary.meta_lic", []string{"static"}},
219			},
220			expectedResolutions: []res{
221				{"gplBin.meta_lic", "gplBin.meta_lic", "restricted"},
222				{"gplBin.meta_lic", "proprietary.meta_lic", "restricted"},
223			},
224		},
225		{
226			name:  "noticeonb_e_orestricted",
227			roots: []string{"mitBin.meta_lic"},
228			edges: []annotated{
229				{"mitBin.meta_lic", "by_exception.meta_lic", []string{"static"}},
230			},
231			expectedResolutions: []res{},
232		},
233		{
234			name:  "b_e_oonnoticerestricted",
235			roots: []string{"by_exception.meta_lic"},
236			edges: []annotated{
237				{"by_exception.meta_lic", "mitLib.meta_lic", []string{"static"}},
238			},
239			expectedResolutions: []res{},
240		},
241		{
242			name:  "noticeonreciprecip",
243			roots: []string{"mitBin.meta_lic"},
244			edges: []annotated{
245				{"mitBin.meta_lic", "mplLib.meta_lic", []string{"static"}},
246			},
247			expectedResolutions: []res{
248				{"mitBin.meta_lic", "mplLib.meta_lic", "reciprocal"},
249			},
250		},
251		{
252			name:  "reciponnoticerecip",
253			roots: []string{"mplBin.meta_lic"},
254			edges: []annotated{
255				{"mplBin.meta_lic", "mitLib.meta_lic", []string{"static"}},
256			},
257			expectedResolutions: []res{
258				{"mplBin.meta_lic", "mplBin.meta_lic", "reciprocal"},
259			},
260		},
261	}
262	for _, tt := range tests {
263		t.Run(tt.name, func(t *testing.T) {
264			stderr := &bytes.Buffer{}
265			lg, err := toGraph(stderr, tt.roots, tt.edges)
266			if err != nil {
267				t.Errorf("unexpected test data error: got %s, want no error", err)
268				return
269			}
270			expectedRs := toResolutionSet(lg, tt.expectedResolutions)
271			actualRs := ResolveSourceSharing(lg)
272			checkResolves(actualRs, expectedRs, t)
273		})
274	}
275}
276