xref: /aosp_15_r20/build/make/tools/compliance/cmd/listshare/listshare_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 main
16
17import (
18	"bytes"
19	"fmt"
20	"os"
21	"strings"
22	"testing"
23
24	"android/soong/tools/compliance"
25)
26
27func TestMain(m *testing.M) {
28	// Change into the parent directory before running the tests
29	// so they can find the testdata directory.
30	if err := os.Chdir(".."); err != nil {
31		fmt.Printf("failed to change to testdata directory: %s\n", err)
32		os.Exit(1)
33	}
34	os.Exit(m.Run())
35}
36
37func Test(t *testing.T) {
38	type projectShare struct {
39		project    string
40		conditions []string
41	}
42	tests := []struct {
43		condition   string
44		name        string
45		outDir      string
46		roots       []string
47		expectedOut []projectShare
48	}{
49		{
50			condition:   "firstparty",
51			name:        "apex",
52			roots:       []string{"highest.apex.meta_lic"},
53			expectedOut: []projectShare{},
54		},
55		{
56			condition:   "firstparty",
57			name:        "container",
58			roots:       []string{"container.zip.meta_lic"},
59			expectedOut: []projectShare{},
60		},
61		{
62			condition:   "firstparty",
63			name:        "application",
64			roots:       []string{"application.meta_lic"},
65			expectedOut: []projectShare{},
66		},
67		{
68			condition:   "firstparty",
69			name:        "binary",
70			roots:       []string{"bin/bin1.meta_lic"},
71			expectedOut: []projectShare{},
72		},
73		{
74			condition:   "firstparty",
75			name:        "library",
76			roots:       []string{"lib/libd.so.meta_lic"},
77			expectedOut: []projectShare{},
78		},
79		{
80			condition:   "notice",
81			name:        "apex",
82			roots:       []string{"highest.apex.meta_lic"},
83			expectedOut: []projectShare{},
84		},
85		{
86			condition:   "notice",
87			name:        "container",
88			roots:       []string{"container.zip.meta_lic"},
89			expectedOut: []projectShare{},
90		},
91		{
92			condition:   "notice",
93			name:        "application",
94			roots:       []string{"application.meta_lic"},
95			expectedOut: []projectShare{},
96		},
97		{
98			condition:   "notice",
99			name:        "binary",
100			roots:       []string{"bin/bin1.meta_lic"},
101			expectedOut: []projectShare{},
102		},
103		{
104			condition:   "notice",
105			name:        "library",
106			roots:       []string{"lib/libd.so.meta_lic"},
107			expectedOut: []projectShare{},
108		},
109		{
110			condition: "reciprocal",
111			name:      "apex",
112			roots:     []string{"highest.apex.meta_lic"},
113			expectedOut: []projectShare{
114				{
115					project:    "device/library",
116					conditions: []string{"reciprocal"},
117				},
118				{
119					project: "static/library",
120					conditions: []string{
121						"reciprocal",
122					},
123				},
124			},
125		},
126		{
127			condition: "reciprocal",
128			name:      "container",
129			roots:     []string{"container.zip.meta_lic"},
130			expectedOut: []projectShare{
131				{
132					project:    "device/library",
133					conditions: []string{"reciprocal"},
134				},
135				{
136					project: "static/library",
137					conditions: []string{
138						"reciprocal",
139					},
140				},
141			},
142		},
143		{
144			condition: "reciprocal",
145			name:      "application",
146			roots:     []string{"application.meta_lic"},
147			expectedOut: []projectShare{
148				{
149					project:    "device/library",
150					conditions: []string{"reciprocal"},
151				},
152			},
153		},
154		{
155			condition: "reciprocal",
156			name:      "binary",
157			roots:     []string{"bin/bin1.meta_lic"},
158			expectedOut: []projectShare{
159				{
160					project: "device/library",
161					conditions: []string{
162						"reciprocal",
163					},
164				},
165				{
166					project: "static/library",
167					conditions: []string{
168						"reciprocal",
169					},
170				},
171			},
172		},
173		{
174			condition:   "reciprocal",
175			name:        "library",
176			roots:       []string{"lib/libd.so.meta_lic"},
177			expectedOut: []projectShare{},
178		},
179		{
180			condition: "restricted",
181			name:      "apex",
182			roots:     []string{"highest.apex.meta_lic"},
183			expectedOut: []projectShare{
184				{
185					project:    "base/library",
186					conditions: []string{"restricted"},
187				},
188				{
189					project:    "device/library",
190					conditions: []string{"restricted_if_statically_linked"},
191				},
192				{
193					project:    "dynamic/binary",
194					conditions: []string{"restricted"},
195				},
196				{
197					project: "static/binary",
198					conditions: []string{
199						"restricted_if_statically_linked",
200					},
201				},
202				{
203					project: "static/library",
204					conditions: []string{
205						"reciprocal",
206						"restricted_if_statically_linked",
207					},
208				},
209			},
210		},
211		{
212			condition: "restricted",
213			name:      "container",
214			roots:     []string{"container.zip.meta_lic"},
215			expectedOut: []projectShare{
216				{
217					project:    "base/library",
218					conditions: []string{"restricted"},
219				},
220				{
221					project:    "device/library",
222					conditions: []string{"restricted_if_statically_linked"},
223				},
224				{
225					project:    "dynamic/binary",
226					conditions: []string{"restricted"},
227				},
228				{
229					project: "static/binary",
230					conditions: []string{
231						"restricted_if_statically_linked",
232					},
233				},
234				{
235					project: "static/library",
236					conditions: []string{
237						"reciprocal",
238						"restricted_if_statically_linked",
239					},
240				},
241			},
242		},
243		{
244			condition: "restricted",
245			name:      "application",
246			roots:     []string{"application.meta_lic"},
247			expectedOut: []projectShare{
248				{
249					project: "device/library",
250					conditions: []string{
251						"restricted",
252						"restricted_if_statically_linked",
253					},
254				},
255				{
256					project: "distributable/application",
257					conditions: []string{
258						"restricted",
259						"restricted_if_statically_linked",
260					},
261				},
262			},
263		},
264		{
265			condition: "restricted",
266			name:      "binary",
267			roots:     []string{"bin/bin1.meta_lic"},
268			expectedOut: []projectShare{
269				{
270					project: "device/library",
271					conditions: []string{
272						"restricted_if_statically_linked",
273					},
274				},
275				{
276					project: "static/binary",
277					conditions: []string{
278						"restricted_if_statically_linked",
279					},
280				},
281				{
282					project: "static/library",
283					conditions: []string{
284						"reciprocal",
285						"restricted_if_statically_linked",
286					},
287				},
288			},
289		},
290		{
291			condition:   "restricted",
292			name:        "library",
293			roots:       []string{"lib/libd.so.meta_lic"},
294			expectedOut: []projectShare{},
295		},
296		{
297			condition: "proprietary",
298			name:      "apex",
299			roots:     []string{"highest.apex.meta_lic"},
300			expectedOut: []projectShare{
301				{
302					project:    "base/library",
303					conditions: []string{"restricted"},
304				},
305				{
306					project:    "dynamic/binary",
307					conditions: []string{"restricted"},
308				},
309			},
310		},
311		{
312			condition: "proprietary",
313			name:      "container",
314			roots:     []string{"container.zip.meta_lic"},
315			expectedOut: []projectShare{
316				{
317					project:    "base/library",
318					conditions: []string{"restricted"},
319				},
320				{
321					project:    "dynamic/binary",
322					conditions: []string{"restricted"},
323				},
324			},
325		},
326		{
327			condition: "proprietary",
328			name:      "application",
329			roots:     []string{"application.meta_lic"},
330			expectedOut: []projectShare{
331				{
332					project:    "device/library",
333					conditions: []string{"restricted"},
334				},
335				{
336					project:    "distributable/application",
337					conditions: []string{"restricted"},
338				},
339			},
340		},
341		{
342			condition:   "proprietary",
343			name:        "binary",
344			roots:       []string{"bin/bin1.meta_lic"},
345			expectedOut: []projectShare{},
346		},
347		{
348			condition:   "proprietary",
349			name:        "library",
350			roots:       []string{"lib/libd.so.meta_lic"},
351			expectedOut: []projectShare{},
352		},
353		{
354			condition: "regressgpl1",
355			name:      "container",
356			roots:     []string{"container.zip.meta_lic"},
357			expectedOut: []projectShare{
358				{
359					project:    "bin/threelibraries",
360					conditions: []string{"restricted"},
361				},
362			},
363		},
364		{
365			condition: "regressgpl1",
366			name:      "containerplus",
367			roots:     []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"},
368			expectedOut: []projectShare{
369				{
370					project:    "bin/threelibraries",
371					conditions: []string{"restricted"},
372				},
373				{
374					project:    "lib/apache",
375					conditions: []string{"restricted"},
376				},
377				{
378					project:    "lib/c++",
379					conditions: []string{"restricted"},
380				},
381			},
382		},
383		{
384			condition: "regressgpl2",
385			name:      "container",
386			roots:     []string{"container.zip.meta_lic"},
387			expectedOut: []projectShare{
388				{
389					project:    "bin/threelibraries",
390					conditions: []string{"restricted"},
391				},
392				{
393					project:    "lib/apache",
394					conditions: []string{"restricted"},
395				},
396				{
397					project:    "lib/c++",
398					conditions: []string{"restricted"},
399				},
400				{
401					project:    "lib/gpl",
402					conditions: []string{"restricted"},
403				},
404			},
405		},
406		{
407			condition: "regressgpl2",
408			name:      "containerplus",
409			roots:     []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"},
410			expectedOut: []projectShare{
411				{
412					project:    "bin/threelibraries",
413					conditions: []string{"restricted"},
414				},
415				{
416					project:    "lib/apache",
417					conditions: []string{"restricted"},
418				},
419				{
420					project:    "lib/c++",
421					conditions: []string{"restricted"},
422				},
423				{
424					project:    "lib/gpl",
425					conditions: []string{"restricted"},
426				},
427			},
428		},
429	}
430	for _, tt := range tests {
431		t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
432			expectedOut := &bytes.Buffer{}
433			for _, p := range tt.expectedOut {
434				expectedOut.WriteString(p.project)
435				for _, lc := range p.conditions {
436					expectedOut.WriteString(",")
437					expectedOut.WriteString(lc)
438				}
439				expectedOut.WriteString("\n")
440			}
441
442			stdout := &bytes.Buffer{}
443			stderr := &bytes.Buffer{}
444
445			rootFiles := make([]string, 0, len(tt.roots))
446			for _, r := range tt.roots {
447				rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
448			}
449			err := listShare(stdout, stderr, compliance.GetFS(tt.outDir), rootFiles...)
450			if err != nil {
451				t.Fatalf("listshare: error = %v, stderr = %v", err, stderr)
452				return
453			}
454			if stderr.Len() > 0 {
455				t.Errorf("listshare: gotStderr = %v, want none", stderr)
456			}
457			out := stdout.String()
458			expected := expectedOut.String()
459			if out != expected {
460				outList := strings.Split(out, "\n")
461				expectedList := strings.Split(expected, "\n")
462				startLine := 0
463				for len(outList) > startLine && len(expectedList) > startLine && outList[startLine] == expectedList[startLine] {
464					startLine++
465				}
466				t.Errorf("listshare: gotStdout = %v, want %v, somewhere near line %d Stdout = %v, want %v",
467					out, expected, startLine+1, outList[startLine], expectedList[startLine])
468			}
469		})
470	}
471}
472