• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_allows_dynamic_linking"},
191				},
192				{
193					project:    "dynamic/binary",
194					conditions: []string{"restricted"},
195				},
196				{
197					project: "highest/apex",
198					conditions: []string{
199						"restricted",
200						"restricted_allows_dynamic_linking",
201					},
202				},
203				{
204					project: "static/binary",
205					conditions: []string{
206						"restricted_allows_dynamic_linking",
207					},
208				},
209				{
210					project: "static/library",
211					conditions: []string{
212						"reciprocal",
213						"restricted_allows_dynamic_linking",
214					},
215				},
216			},
217		},
218		{
219			condition: "restricted",
220			name:      "container",
221			roots:     []string{"container.zip.meta_lic"},
222			expectedOut: []projectShare{
223				{
224					project:    "base/library",
225					conditions: []string{"restricted"},
226				},
227				{
228					project: "container/zip",
229					conditions: []string{
230						"restricted",
231						"restricted_allows_dynamic_linking",
232					},
233				},
234				{
235					project:    "device/library",
236					conditions: []string{"restricted_allows_dynamic_linking"},
237				},
238				{
239					project:    "dynamic/binary",
240					conditions: []string{"restricted"},
241				},
242				{
243					project: "static/binary",
244					conditions: []string{
245						"restricted_allows_dynamic_linking",
246					},
247				},
248				{
249					project: "static/library",
250					conditions: []string{
251						"reciprocal",
252						"restricted_allows_dynamic_linking",
253					},
254				},
255			},
256		},
257		{
258			condition: "restricted",
259			name:      "application",
260			roots:     []string{"application.meta_lic"},
261			expectedOut: []projectShare{
262				{
263					project: "device/library",
264					conditions: []string{
265						"restricted",
266						"restricted_allows_dynamic_linking",
267					},
268				},
269				{
270					project: "distributable/application",
271					conditions: []string{
272						"restricted",
273						"restricted_allows_dynamic_linking",
274					},
275				},
276			},
277		},
278		{
279			condition: "restricted",
280			name:      "binary",
281			roots:     []string{"bin/bin1.meta_lic"},
282			expectedOut: []projectShare{
283				{
284					project: "device/library",
285					conditions: []string{
286						"restricted_allows_dynamic_linking",
287					},
288				},
289				{
290					project: "static/binary",
291					conditions: []string{
292						"restricted_allows_dynamic_linking",
293					},
294				},
295				{
296					project: "static/library",
297					conditions: []string{
298						"reciprocal",
299						"restricted_allows_dynamic_linking",
300					},
301				},
302			},
303		},
304		{
305			condition:   "restricted",
306			name:        "library",
307			roots:       []string{"lib/libd.so.meta_lic"},
308			expectedOut: []projectShare{},
309		},
310		{
311			condition: "proprietary",
312			name:      "apex",
313			roots:     []string{"highest.apex.meta_lic"},
314			expectedOut: []projectShare{
315				{
316					project:    "base/library",
317					conditions: []string{"restricted"},
318				},
319				{
320					project:    "dynamic/binary",
321					conditions: []string{"restricted"},
322				},
323				{
324					project:    "highest/apex",
325					conditions: []string{"restricted"},
326				},
327			},
328		},
329		{
330			condition: "proprietary",
331			name:      "container",
332			roots:     []string{"container.zip.meta_lic"},
333			expectedOut: []projectShare{
334				{
335					project:    "base/library",
336					conditions: []string{"restricted"},
337				},
338				{
339					project:    "container/zip",
340					conditions: []string{"restricted"},
341				},
342				{
343					project:    "dynamic/binary",
344					conditions: []string{"restricted"},
345				},
346			},
347		},
348		{
349			condition: "proprietary",
350			name:      "application",
351			roots:     []string{"application.meta_lic"},
352			expectedOut: []projectShare{
353				{
354					project:    "device/library",
355					conditions: []string{"restricted"},
356				},
357				{
358					project:    "distributable/application",
359					conditions: []string{"restricted"},
360				},
361			},
362		},
363		{
364			condition:   "proprietary",
365			name:        "binary",
366			roots:       []string{"bin/bin1.meta_lic"},
367			expectedOut: []projectShare{},
368		},
369		{
370			condition:   "proprietary",
371			name:        "library",
372			roots:       []string{"lib/libd.so.meta_lic"},
373			expectedOut: []projectShare{},
374		},
375		{
376			condition: "regressgpl1",
377			name:      "container",
378			roots:     []string{"container.zip.meta_lic"},
379			expectedOut: []projectShare{
380				{
381					project:    "bin/threelibraries",
382					conditions: []string{"restricted"},
383				},
384				{
385					project:    "container/zip",
386					conditions: []string{"restricted"},
387				},
388			},
389		},
390		{
391			condition: "regressgpl1",
392			name:      "containerplus",
393			roots:     []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"},
394			expectedOut: []projectShare{
395				{
396					project:    "bin/threelibraries",
397					conditions: []string{"restricted"},
398				},
399				{
400					project:    "container/zip",
401					conditions: []string{"restricted"},
402				},
403				{
404					project:    "lib/apache",
405					conditions: []string{"restricted"},
406				},
407				{
408					project:    "lib/c++",
409					conditions: []string{"restricted"},
410				},
411			},
412		},
413		{
414			condition: "regressgpl2",
415			name:      "container",
416			roots:     []string{"container.zip.meta_lic"},
417			expectedOut: []projectShare{
418				{
419					project:    "bin/threelibraries",
420					conditions: []string{"restricted"},
421				},
422				{
423					project:    "container/zip",
424					conditions: []string{"restricted"},
425				},
426				{
427					project:    "lib/apache",
428					conditions: []string{"restricted"},
429				},
430				{
431					project:    "lib/c++",
432					conditions: []string{"restricted"},
433				},
434				{
435					project:    "lib/gpl",
436					conditions: []string{"restricted"},
437				},
438			},
439		},
440		{
441			condition: "regressgpl2",
442			name:      "containerplus",
443			roots:     []string{"container.zip.meta_lic", "lib/libapache.so.meta_lic", "lib/libc++.so.meta_lic"},
444			expectedOut: []projectShare{
445				{
446					project:    "bin/threelibraries",
447					conditions: []string{"restricted"},
448				},
449				{
450					project:    "container/zip",
451					conditions: []string{"restricted"},
452				},
453				{
454					project:    "lib/apache",
455					conditions: []string{"restricted"},
456				},
457				{
458					project:    "lib/c++",
459					conditions: []string{"restricted"},
460				},
461				{
462					project:    "lib/gpl",
463					conditions: []string{"restricted"},
464				},
465			},
466		},
467	}
468	for _, tt := range tests {
469		t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
470			expectedOut := &bytes.Buffer{}
471			for _, p := range tt.expectedOut {
472				expectedOut.WriteString(p.project)
473				for _, lc := range p.conditions {
474					expectedOut.WriteString(",")
475					expectedOut.WriteString(lc)
476				}
477				expectedOut.WriteString("\n")
478			}
479
480			stdout := &bytes.Buffer{}
481			stderr := &bytes.Buffer{}
482
483			rootFiles := make([]string, 0, len(tt.roots))
484			for _, r := range tt.roots {
485				rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
486			}
487			err := listShare(stdout, stderr, compliance.GetFS(tt.outDir), rootFiles...)
488			if err != nil {
489				t.Fatalf("listshare: error = %v, stderr = %v", err, stderr)
490				return
491			}
492			if stderr.Len() > 0 {
493				t.Errorf("listshare: gotStderr = %v, want none", stderr)
494			}
495			out := stdout.String()
496			expected := expectedOut.String()
497			if out != expected {
498				outList := strings.Split(out, "\n")
499				expectedList := strings.Split(expected, "\n")
500				startLine := 0
501				for len(outList) > startLine && len(expectedList) > startLine && outList[startLine] == expectedList[startLine] {
502					startLine++
503				}
504				t.Errorf("listshare: gotStdout = %v, want %v, somewhere near line %d Stdout = %v, want %v",
505					out, expected, startLine+1, outList[startLine], expectedList[startLine])
506			}
507		})
508	}
509}
510