• 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
37type outcome struct {
38	target           string
39	privacyCondition string
40	shareCondition   string
41}
42
43func (o *outcome) String() string {
44	return fmt.Sprintf("%s %s and must share from %s", o.target, o.privacyCondition, o.shareCondition)
45}
46
47type outcomeList []*outcome
48
49func (ol outcomeList) String() string {
50	result := ""
51	for _, o := range ol {
52		result = result + o.String() + "\n"
53	}
54	return result
55}
56
57func Test(t *testing.T) {
58	tests := []struct {
59		condition        string
60		name             string
61		outDir           string
62		roots            []string
63		expectedStdout   string
64		expectedOutcomes outcomeList
65	}{
66		{
67			condition:      "firstparty",
68			name:           "apex",
69			roots:          []string{"highest.apex.meta_lic"},
70			expectedStdout: "PASS",
71		},
72		{
73			condition:      "firstparty",
74			name:           "container",
75			roots:          []string{"container.zip.meta_lic"},
76			expectedStdout: "PASS",
77		},
78		{
79			condition:      "firstparty",
80			name:           "application",
81			roots:          []string{"application.meta_lic"},
82			expectedStdout: "PASS",
83		},
84		{
85			condition:      "firstparty",
86			name:           "binary",
87			roots:          []string{"bin/bin2.meta_lic"},
88			expectedStdout: "PASS",
89		},
90		{
91			condition:      "firstparty",
92			name:           "library",
93			roots:          []string{"lib/libd.so.meta_lic"},
94			expectedStdout: "PASS",
95		},
96		{
97			condition:      "notice",
98			name:           "apex",
99			roots:          []string{"highest.apex.meta_lic"},
100			expectedStdout: "PASS",
101		},
102		{
103			condition:      "notice",
104			name:           "container",
105			roots:          []string{"container.zip.meta_lic"},
106			expectedStdout: "PASS",
107		},
108		{
109			condition:      "notice",
110			name:           "application",
111			roots:          []string{"application.meta_lic"},
112			expectedStdout: "PASS",
113		},
114		{
115			condition:      "notice",
116			name:           "binary",
117			roots:          []string{"bin/bin2.meta_lic"},
118			expectedStdout: "PASS",
119		},
120		{
121			condition:      "notice",
122			name:           "library",
123			roots:          []string{"lib/libd.so.meta_lic"},
124			expectedStdout: "PASS",
125		},
126		{
127			condition:      "reciprocal",
128			name:           "apex",
129			roots:          []string{"highest.apex.meta_lic"},
130			expectedStdout: "PASS",
131		},
132		{
133			condition:      "reciprocal",
134			name:           "container",
135			roots:          []string{"container.zip.meta_lic"},
136			expectedStdout: "PASS",
137		},
138		{
139			condition:      "reciprocal",
140			name:           "application",
141			roots:          []string{"application.meta_lic"},
142			expectedStdout: "PASS",
143		},
144		{
145			condition:      "reciprocal",
146			name:           "binary",
147			roots:          []string{"bin/bin2.meta_lic"},
148			expectedStdout: "PASS",
149		},
150		{
151			condition:      "reciprocal",
152			name:           "library",
153			roots:          []string{"lib/libd.so.meta_lic"},
154			expectedStdout: "PASS",
155		},
156		{
157			condition:      "restricted",
158			name:           "apex",
159			roots:          []string{"highest.apex.meta_lic"},
160			expectedStdout: "PASS",
161		},
162		{
163			condition:      "restricted",
164			name:           "container",
165			roots:          []string{"container.zip.meta_lic"},
166			expectedStdout: "PASS",
167		},
168		{
169			condition:      "restricted",
170			name:           "application",
171			roots:          []string{"application.meta_lic"},
172			expectedStdout: "PASS",
173		},
174		{
175			condition:      "restricted",
176			name:           "binary",
177			roots:          []string{"bin/bin2.meta_lic"},
178			expectedStdout: "PASS",
179		},
180		{
181			condition:      "restricted",
182			name:           "library",
183			roots:          []string{"lib/libd.so.meta_lic"},
184			expectedStdout: "PASS",
185		},
186		{
187			condition:      "proprietary",
188			name:           "apex",
189			roots:          []string{"highest.apex.meta_lic"},
190			expectedStdout: "FAIL",
191			expectedOutcomes: outcomeList{
192				&outcome{
193					target:           "testdata/proprietary/bin/bin2.meta_lic",
194					privacyCondition: "proprietary",
195					shareCondition:   "restricted",
196				},
197			},
198		},
199		{
200			condition:      "proprietary",
201			name:           "container",
202			roots:          []string{"container.zip.meta_lic"},
203			expectedStdout: "FAIL",
204			expectedOutcomes: outcomeList{
205				&outcome{
206					target:           "testdata/proprietary/bin/bin2.meta_lic",
207					privacyCondition: "proprietary",
208					shareCondition:   "restricted",
209				},
210			},
211		},
212		{
213			condition:      "proprietary",
214			name:           "application",
215			roots:          []string{"application.meta_lic"},
216			expectedStdout: "FAIL",
217			expectedOutcomes: outcomeList{
218				&outcome{
219					target:           "testdata/proprietary/lib/liba.so.meta_lic",
220					privacyCondition: "proprietary",
221					shareCondition:   "restricted",
222				},
223			},
224		},
225		{
226			condition:      "proprietary",
227			name:           "binary",
228			roots:          []string{"bin/bin2.meta_lic", "lib/libb.so.meta_lic"},
229			expectedStdout: "FAIL",
230			expectedOutcomes: outcomeList{
231				&outcome{
232					target:           "testdata/proprietary/bin/bin2.meta_lic",
233					privacyCondition: "proprietary",
234					shareCondition:   "restricted",
235				},
236			},
237		},
238		{
239			condition:      "proprietary",
240			name:           "library",
241			roots:          []string{"lib/libd.so.meta_lic"},
242			expectedStdout: "PASS",
243		},
244	}
245	for _, tt := range tests {
246		t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
247			stdout := &bytes.Buffer{}
248			stderr := &bytes.Buffer{}
249
250			rootFiles := make([]string, 0, len(tt.roots))
251			for _, r := range tt.roots {
252				rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
253			}
254			err := checkShare(stdout, stderr, compliance.GetFS(tt.outDir), rootFiles...)
255			if err != nil && err != failConflicts {
256				t.Fatalf("checkshare: error = %v, stderr = %v", err, stderr)
257				return
258			}
259			var actualStdout string
260			for _, s := range strings.Split(stdout.String(), "\n") {
261				ts := strings.TrimLeft(s, " \t")
262				if len(ts) < 1 {
263					continue
264				}
265				if len(actualStdout) > 0 {
266					t.Errorf("checkshare: unexpected multiple output lines %q, want %q", actualStdout+"\n"+ts, tt.expectedStdout)
267				}
268				actualStdout = ts
269			}
270			if actualStdout != tt.expectedStdout {
271				t.Errorf("checkshare: unexpected stdout %q, want %q", actualStdout, tt.expectedStdout)
272			}
273			errList := strings.Split(stderr.String(), "\n")
274			actualOutcomes := make(outcomeList, 0, len(errList))
275			for _, cstring := range errList {
276				ts := strings.TrimLeft(cstring, " \t")
277				if len(ts) < 1 {
278					continue
279				}
280				cFields := strings.Split(ts, " ")
281				actualOutcomes = append(actualOutcomes, &outcome{
282					target:           cFields[0],
283					privacyCondition: cFields[1],
284					shareCondition:   cFields[6],
285				})
286			}
287			if len(actualOutcomes) != len(tt.expectedOutcomes) {
288				t.Errorf("checkshare: unexpected got %d outcomes %s, want %d outcomes %s",
289					len(actualOutcomes), actualOutcomes, len(tt.expectedOutcomes), tt.expectedOutcomes)
290				return
291			}
292			for i := range actualOutcomes {
293				if actualOutcomes[i].String() != tt.expectedOutcomes[i].String() {
294					t.Errorf("checkshare: unexpected outcome #%d, got %q, want %q",
295						i+1, actualOutcomes[i], tt.expectedOutcomes[i])
296				}
297			}
298		})
299	}
300}
301