blob: 305502239c89d6b667add35d4af0ac2a07a059c3 [file] [log] [blame]
Bob Badourfa739da2021-10-25 16:21:00 -07001// 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 "strings"
21 "testing"
22)
23
24func Test_plaintext(t *testing.T) {
25 tests := []struct {
26 condition string
27 name string
28 roots []string
29 ctx context
30 expectedOut []string
31 }{
32 {
33 condition: "firstparty",
34 name: "apex",
35 roots: []string{"highest.apex.meta_lic"},
36 expectedOut: []string{
37 "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic static",
38 "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic static",
39 "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/lib/libb.so.meta_lic dynamic",
40 "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/lib/libd.so.meta_lic dynamic",
41 "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/bin/bin1.meta_lic static",
42 "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/bin/bin2.meta_lic static",
43 "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/liba.so.meta_lic static",
44 "testdata/firstparty/highest.apex.meta_lic testdata/firstparty/lib/libb.so.meta_lic static",
45 },
46 },
47 {
48 condition: "firstparty",
49 name: "apex_trimmed",
50 roots: []string{"highest.apex.meta_lic"},
51 ctx: context{stripPrefix: "testdata/firstparty/"},
52 expectedOut: []string{
53 "bin/bin1.meta_lic lib/liba.so.meta_lic static",
54 "bin/bin1.meta_lic lib/libc.a.meta_lic static",
55 "bin/bin2.meta_lic lib/libb.so.meta_lic dynamic",
56 "bin/bin2.meta_lic lib/libd.so.meta_lic dynamic",
57 "highest.apex.meta_lic bin/bin1.meta_lic static",
58 "highest.apex.meta_lic bin/bin2.meta_lic static",
59 "highest.apex.meta_lic lib/liba.so.meta_lic static",
60 "highest.apex.meta_lic lib/libb.so.meta_lic static",
61 },
62 },
63 {
64 condition: "firstparty",
65 name: "apex_trimmed_labelled",
66 roots: []string{"highest.apex.meta_lic"},
67 ctx: context{stripPrefix: "testdata/firstparty/", labelConditions: true},
68 expectedOut: []string{
69 "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:notice static",
70 "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:notice static",
71 "bin/bin2.meta_lic:notice lib/libb.so.meta_lic:notice dynamic",
72 "bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice dynamic",
73 "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
74 "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice static",
75 "highest.apex.meta_lic:notice lib/liba.so.meta_lic:notice static",
76 "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice static",
77 },
78 },
79 {
80 condition: "firstparty",
81 name: "container",
82 roots: []string{"container.zip.meta_lic"},
83 expectedOut: []string{
84 "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic static",
85 "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic static",
86 "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/lib/libb.so.meta_lic dynamic",
87 "testdata/firstparty/bin/bin2.meta_lic testdata/firstparty/lib/libd.so.meta_lic dynamic",
88 "testdata/firstparty/container.zip.meta_lic testdata/firstparty/bin/bin1.meta_lic static",
89 "testdata/firstparty/container.zip.meta_lic testdata/firstparty/bin/bin2.meta_lic static",
90 "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/liba.so.meta_lic static",
91 "testdata/firstparty/container.zip.meta_lic testdata/firstparty/lib/libb.so.meta_lic static",
92 },
93 },
94 {
95 condition: "firstparty",
96 name: "application",
97 roots: []string{"application.meta_lic"},
98 expectedOut: []string{
99 "testdata/firstparty/application.meta_lic testdata/firstparty/bin/bin3.meta_lic toolchain",
100 "testdata/firstparty/application.meta_lic testdata/firstparty/lib/liba.so.meta_lic static",
101 "testdata/firstparty/application.meta_lic testdata/firstparty/lib/libb.so.meta_lic dynamic",
102 },
103 },
104 {
105 condition: "firstparty",
106 name: "binary",
107 roots: []string{"bin/bin1.meta_lic"},
108 expectedOut: []string{
109 "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/liba.so.meta_lic static",
110 "testdata/firstparty/bin/bin1.meta_lic testdata/firstparty/lib/libc.a.meta_lic static",
111 },
112 },
113 {
114 condition: "firstparty",
115 name: "library",
116 roots: []string{"lib/libd.so.meta_lic"},
117 expectedOut: []string{},
118 },
119 {
120 condition: "notice",
121 name: "apex",
122 roots: []string{"highest.apex.meta_lic"},
123 expectedOut: []string{
124 "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic static",
125 "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic static",
126 "testdata/notice/bin/bin2.meta_lic testdata/notice/lib/libb.so.meta_lic dynamic",
127 "testdata/notice/bin/bin2.meta_lic testdata/notice/lib/libd.so.meta_lic dynamic",
128 "testdata/notice/highest.apex.meta_lic testdata/notice/bin/bin1.meta_lic static",
129 "testdata/notice/highest.apex.meta_lic testdata/notice/bin/bin2.meta_lic static",
130 "testdata/notice/highest.apex.meta_lic testdata/notice/lib/liba.so.meta_lic static",
131 "testdata/notice/highest.apex.meta_lic testdata/notice/lib/libb.so.meta_lic static",
132 },
133 },
134 {
135 condition: "notice",
136 name: "apex_trimmed",
137 roots: []string{"highest.apex.meta_lic"},
138 ctx: context{stripPrefix: "testdata/notice/"},
139 expectedOut: []string{
140 "bin/bin1.meta_lic lib/liba.so.meta_lic static",
141 "bin/bin1.meta_lic lib/libc.a.meta_lic static",
142 "bin/bin2.meta_lic lib/libb.so.meta_lic dynamic",
143 "bin/bin2.meta_lic lib/libd.so.meta_lic dynamic",
144 "highest.apex.meta_lic bin/bin1.meta_lic static",
145 "highest.apex.meta_lic bin/bin2.meta_lic static",
146 "highest.apex.meta_lic lib/liba.so.meta_lic static",
147 "highest.apex.meta_lic lib/libb.so.meta_lic static",
148 },
149 },
150 {
151 condition: "notice",
152 name: "apex_trimmed_labelled",
153 roots: []string{"highest.apex.meta_lic"},
154 ctx: context{stripPrefix: "testdata/notice/", labelConditions: true},
155 expectedOut: []string{
156 "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:notice static",
157 "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:notice static",
158 "bin/bin2.meta_lic:notice lib/libb.so.meta_lic:notice dynamic",
159 "bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice dynamic",
160 "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
161 "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice static",
162 "highest.apex.meta_lic:notice lib/liba.so.meta_lic:notice static",
163 "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice static",
164 },
165 },
166 {
167 condition: "notice",
168 name: "container",
169 roots: []string{"container.zip.meta_lic"},
170 expectedOut: []string{
171 "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic static",
172 "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic static",
173 "testdata/notice/bin/bin2.meta_lic testdata/notice/lib/libb.so.meta_lic dynamic",
174 "testdata/notice/bin/bin2.meta_lic testdata/notice/lib/libd.so.meta_lic dynamic",
175 "testdata/notice/container.zip.meta_lic testdata/notice/bin/bin1.meta_lic static",
176 "testdata/notice/container.zip.meta_lic testdata/notice/bin/bin2.meta_lic static",
177 "testdata/notice/container.zip.meta_lic testdata/notice/lib/liba.so.meta_lic static",
178 "testdata/notice/container.zip.meta_lic testdata/notice/lib/libb.so.meta_lic static",
179 },
180 },
181 {
182 condition: "notice",
183 name: "application",
184 roots: []string{"application.meta_lic"},
185 expectedOut: []string{
186 "testdata/notice/application.meta_lic testdata/notice/bin/bin3.meta_lic toolchain",
187 "testdata/notice/application.meta_lic testdata/notice/lib/liba.so.meta_lic static",
188 "testdata/notice/application.meta_lic testdata/notice/lib/libb.so.meta_lic dynamic",
189 },
190 },
191 {
192 condition: "notice",
193 name: "binary",
194 roots: []string{"bin/bin1.meta_lic"},
195 expectedOut: []string{
196 "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/liba.so.meta_lic static",
197 "testdata/notice/bin/bin1.meta_lic testdata/notice/lib/libc.a.meta_lic static",
198 },
199 },
200 {
201 condition: "notice",
202 name: "library",
203 roots: []string{"lib/libd.so.meta_lic"},
204 expectedOut: []string{},
205 },
206 {
207 condition: "reciprocal",
208 name: "apex",
209 roots: []string{"highest.apex.meta_lic"},
210 expectedOut: []string{
211 "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic static",
212 "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic static",
213 "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/lib/libb.so.meta_lic dynamic",
214 "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/lib/libd.so.meta_lic dynamic",
215 "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/bin/bin1.meta_lic static",
216 "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/bin/bin2.meta_lic static",
217 "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/liba.so.meta_lic static",
218 "testdata/reciprocal/highest.apex.meta_lic testdata/reciprocal/lib/libb.so.meta_lic static",
219 },
220 },
221 {
222 condition: "reciprocal",
223 name: "apex_trimmed",
224 roots: []string{"highest.apex.meta_lic"},
225 ctx: context{stripPrefix: "testdata/reciprocal/"},
226 expectedOut: []string{
227 "bin/bin1.meta_lic lib/liba.so.meta_lic static",
228 "bin/bin1.meta_lic lib/libc.a.meta_lic static",
229 "bin/bin2.meta_lic lib/libb.so.meta_lic dynamic",
230 "bin/bin2.meta_lic lib/libd.so.meta_lic dynamic",
231 "highest.apex.meta_lic bin/bin1.meta_lic static",
232 "highest.apex.meta_lic bin/bin2.meta_lic static",
233 "highest.apex.meta_lic lib/liba.so.meta_lic static",
234 "highest.apex.meta_lic lib/libb.so.meta_lic static",
235 },
236 },
237 {
238 condition: "reciprocal",
239 name: "apex_trimmed_labelled",
240 roots: []string{"highest.apex.meta_lic"},
241 ctx: context{stripPrefix: "testdata/reciprocal/", labelConditions: true},
242 expectedOut: []string{
243 "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:reciprocal static",
244 "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal static",
245 "bin/bin2.meta_lic:notice lib/libb.so.meta_lic:notice dynamic",
246 "bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice dynamic",
247 "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
248 "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice static",
249 "highest.apex.meta_lic:notice lib/liba.so.meta_lic:reciprocal static",
250 "highest.apex.meta_lic:notice lib/libb.so.meta_lic:notice static",
251 },
252 },
253 {
254 condition: "reciprocal",
255 name: "container",
256 roots: []string{"container.zip.meta_lic"},
257 expectedOut: []string{
258 "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic static",
259 "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic static",
260 "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/lib/libb.so.meta_lic dynamic",
261 "testdata/reciprocal/bin/bin2.meta_lic testdata/reciprocal/lib/libd.so.meta_lic dynamic",
262 "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/bin/bin1.meta_lic static",
263 "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/bin/bin2.meta_lic static",
264 "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/liba.so.meta_lic static",
265 "testdata/reciprocal/container.zip.meta_lic testdata/reciprocal/lib/libb.so.meta_lic static",
266 },
267 },
268 {
269 condition: "reciprocal",
270 name: "application",
271 roots: []string{"application.meta_lic"},
272 expectedOut: []string{
273 "testdata/reciprocal/application.meta_lic testdata/reciprocal/bin/bin3.meta_lic toolchain",
274 "testdata/reciprocal/application.meta_lic testdata/reciprocal/lib/liba.so.meta_lic static",
275 "testdata/reciprocal/application.meta_lic testdata/reciprocal/lib/libb.so.meta_lic dynamic",
276 },
277 },
278 {
279 condition: "reciprocal",
280 name: "binary",
281 roots: []string{"bin/bin1.meta_lic"},
282 expectedOut: []string{
283 "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/liba.so.meta_lic static",
284 "testdata/reciprocal/bin/bin1.meta_lic testdata/reciprocal/lib/libc.a.meta_lic static",
285 },
286 },
287 {
288 condition: "reciprocal",
289 name: "library",
290 roots: []string{"lib/libd.so.meta_lic"},
291 expectedOut: []string{},
292 },
293 {
294 condition: "restricted",
295 name: "apex",
296 roots: []string{"highest.apex.meta_lic"},
297 expectedOut: []string{
298 "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic static",
299 "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic static",
300 "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic dynamic",
301 "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libd.so.meta_lic dynamic",
302 "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin1.meta_lic static",
303 "testdata/restricted/highest.apex.meta_lic testdata/restricted/bin/bin2.meta_lic static",
304 "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/liba.so.meta_lic static",
305 "testdata/restricted/highest.apex.meta_lic testdata/restricted/lib/libb.so.meta_lic static",
306 },
307 },
308 {
309 condition: "restricted",
310 name: "apex_trimmed",
311 roots: []string{"highest.apex.meta_lic"},
312 ctx: context{stripPrefix: "testdata/restricted/"},
313 expectedOut: []string{
314 "bin/bin1.meta_lic lib/liba.so.meta_lic static",
315 "bin/bin1.meta_lic lib/libc.a.meta_lic static",
316 "bin/bin2.meta_lic lib/libb.so.meta_lic dynamic",
317 "bin/bin2.meta_lic lib/libd.so.meta_lic dynamic",
318 "highest.apex.meta_lic bin/bin1.meta_lic static",
319 "highest.apex.meta_lic bin/bin2.meta_lic static",
320 "highest.apex.meta_lic lib/liba.so.meta_lic static",
321 "highest.apex.meta_lic lib/libb.so.meta_lic static",
322 },
323 },
324 {
325 condition: "restricted",
326 name: "apex_trimmed_labelled",
327 roots: []string{"highest.apex.meta_lic"},
328 ctx: context{stripPrefix: "testdata/restricted/", labelConditions: true},
329 expectedOut: []string{
Bob Badour103eb0f2022-01-10 13:50:57 -0800330 "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking static",
Bob Badourfa739da2021-10-25 16:21:00 -0700331 "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:reciprocal static",
332 "bin/bin2.meta_lic:notice lib/libb.so.meta_lic:restricted dynamic",
333 "bin/bin2.meta_lic:notice lib/libd.so.meta_lic:notice dynamic",
334 "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
335 "highest.apex.meta_lic:notice bin/bin2.meta_lic:notice static",
Bob Badour103eb0f2022-01-10 13:50:57 -0800336 "highest.apex.meta_lic:notice lib/liba.so.meta_lic:restricted_allows_dynamic_linking static",
Bob Badourfa739da2021-10-25 16:21:00 -0700337 "highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted static",
338 },
339 },
340 {
341 condition: "restricted",
342 name: "container",
343 roots: []string{"container.zip.meta_lic"},
344 expectedOut: []string{
345 "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic static",
346 "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic static",
347 "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libb.so.meta_lic dynamic",
348 "testdata/restricted/bin/bin2.meta_lic testdata/restricted/lib/libd.so.meta_lic dynamic",
349 "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin1.meta_lic static",
350 "testdata/restricted/container.zip.meta_lic testdata/restricted/bin/bin2.meta_lic static",
351 "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/liba.so.meta_lic static",
352 "testdata/restricted/container.zip.meta_lic testdata/restricted/lib/libb.so.meta_lic static",
353 },
354 },
355 {
356 condition: "restricted",
357 name: "application",
358 roots: []string{"application.meta_lic"},
359 expectedOut: []string{
360 "testdata/restricted/application.meta_lic testdata/restricted/bin/bin3.meta_lic toolchain",
361 "testdata/restricted/application.meta_lic testdata/restricted/lib/liba.so.meta_lic static",
362 "testdata/restricted/application.meta_lic testdata/restricted/lib/libb.so.meta_lic dynamic",
363 },
364 },
365 {
366 condition: "restricted",
367 name: "binary",
368 roots: []string{"bin/bin1.meta_lic"},
369 expectedOut: []string{
370 "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/liba.so.meta_lic static",
371 "testdata/restricted/bin/bin1.meta_lic testdata/restricted/lib/libc.a.meta_lic static",
372 },
373 },
374 {
375 condition: "restricted",
376 name: "library",
377 roots: []string{"lib/libd.so.meta_lic"},
378 expectedOut: []string{},
379 },
380 {
381 condition: "proprietary",
382 name: "apex",
383 roots: []string{"highest.apex.meta_lic"},
384 expectedOut: []string{
385 "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic static",
386 "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic static",
387 "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic dynamic",
388 "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libd.so.meta_lic dynamic",
389 "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin1.meta_lic static",
390 "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/bin/bin2.meta_lic static",
391 "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/liba.so.meta_lic static",
392 "testdata/proprietary/highest.apex.meta_lic testdata/proprietary/lib/libb.so.meta_lic static",
393 },
394 },
395 {
396 condition: "proprietary",
397 name: "apex_trimmed",
398 roots: []string{"highest.apex.meta_lic"},
399 ctx: context{stripPrefix: "testdata/proprietary/"},
400 expectedOut: []string{
401 "bin/bin1.meta_lic lib/liba.so.meta_lic static",
402 "bin/bin1.meta_lic lib/libc.a.meta_lic static",
403 "bin/bin2.meta_lic lib/libb.so.meta_lic dynamic",
404 "bin/bin2.meta_lic lib/libd.so.meta_lic dynamic",
405 "highest.apex.meta_lic bin/bin1.meta_lic static",
406 "highest.apex.meta_lic bin/bin2.meta_lic static",
407 "highest.apex.meta_lic lib/liba.so.meta_lic static",
408 "highest.apex.meta_lic lib/libb.so.meta_lic static",
409 },
410 },
411 {
412 condition: "proprietary",
413 name: "apex_trimmed_labelled",
414 roots: []string{"highest.apex.meta_lic"},
415 ctx: context{stripPrefix: "testdata/proprietary/", labelConditions: true},
416 expectedOut: []string{
417 "bin/bin1.meta_lic:notice lib/liba.so.meta_lic:by_exception_only:proprietary static",
418 "bin/bin1.meta_lic:notice lib/libc.a.meta_lic:by_exception_only:proprietary static",
419 "bin/bin2.meta_lic:by_exception_only:proprietary lib/libb.so.meta_lic:restricted dynamic",
420 "bin/bin2.meta_lic:by_exception_only:proprietary lib/libd.so.meta_lic:notice dynamic",
421 "highest.apex.meta_lic:notice bin/bin1.meta_lic:notice static",
422 "highest.apex.meta_lic:notice bin/bin2.meta_lic:by_exception_only:proprietary static",
423 "highest.apex.meta_lic:notice lib/liba.so.meta_lic:by_exception_only:proprietary static",
424 "highest.apex.meta_lic:notice lib/libb.so.meta_lic:restricted static",
425 },
426 },
427 {
428 condition: "proprietary",
429 name: "container",
430 roots: []string{"container.zip.meta_lic"},
431 expectedOut: []string{
432 "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic static",
433 "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic static",
434 "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libb.so.meta_lic dynamic",
435 "testdata/proprietary/bin/bin2.meta_lic testdata/proprietary/lib/libd.so.meta_lic dynamic",
436 "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin1.meta_lic static",
437 "testdata/proprietary/container.zip.meta_lic testdata/proprietary/bin/bin2.meta_lic static",
438 "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/liba.so.meta_lic static",
439 "testdata/proprietary/container.zip.meta_lic testdata/proprietary/lib/libb.so.meta_lic static",
440 },
441 },
442 {
443 condition: "proprietary",
444 name: "application",
445 roots: []string{"application.meta_lic"},
446 expectedOut: []string{
447 "testdata/proprietary/application.meta_lic testdata/proprietary/bin/bin3.meta_lic toolchain",
448 "testdata/proprietary/application.meta_lic testdata/proprietary/lib/liba.so.meta_lic static",
449 "testdata/proprietary/application.meta_lic testdata/proprietary/lib/libb.so.meta_lic dynamic",
450 },
451 },
452 {
453 condition: "proprietary",
454 name: "binary",
455 roots: []string{"bin/bin1.meta_lic"},
456 expectedOut: []string{
457 "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/liba.so.meta_lic static",
458 "testdata/proprietary/bin/bin1.meta_lic testdata/proprietary/lib/libc.a.meta_lic static",
459 },
460 },
461 {
462 condition: "proprietary",
463 name: "library",
464 roots: []string{"lib/libd.so.meta_lic"},
465 expectedOut: []string{},
466 },
467 }
468 for _, tt := range tests {
469 t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
470 expectedOut := &bytes.Buffer{}
471 for _, eo := range tt.expectedOut {
472 expectedOut.WriteString(eo)
473 expectedOut.WriteString("\n")
474 }
475
476 stdout := &bytes.Buffer{}
477 stderr := &bytes.Buffer{}
478
479 rootFiles := make([]string, 0, len(tt.roots))
480 for _, r := range tt.roots {
481 rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
482 }
483 err := dumpGraph(&tt.ctx, stdout, stderr, rootFiles...)
484 if err != nil {
485 t.Fatalf("dumpgraph: error = %v, stderr = %v", err, stderr)
486 return
487 }
488 if stderr.Len() > 0 {
489 t.Errorf("dumpgraph: gotStderr = %v, want none", stderr)
490 }
491 out := stdout.String()
492 expected := expectedOut.String()
493 if out != expected {
494 outList := strings.Split(out, "\n")
495 expectedList := strings.Split(expected, "\n")
496 startLine := 0
497 for len(outList) > startLine && len(expectedList) > startLine && outList[startLine] == expectedList[startLine] {
498 startLine++
499 }
500 t.Errorf("listshare: gotStdout = %v, want %v, somewhere near line %d Stdout = %v, want %v",
501 out, expected, startLine+1, outList[startLine], expectedList[startLine])
502 }
503 })
504 }
505}
506
507type testContext struct {
508 nextNode int
509 nodes map[string]string
510}
511
512type matcher interface {
513 matchString(*testContext) string
514 typeString() string
515}
516
517type targetMatcher struct {
518 target string
519 conditions []string
520}
521
522func (tm *targetMatcher) matchString(ctx *testContext) string {
523 m := tm.target
524 if len(tm.conditions) > 0 {
525 m += "\\n" + strings.Join(tm.conditions, "\\n")
526 }
527 m = ctx.nodes[tm.target] + " [label=\"" + m + "\"];"
528 return m
529}
530
531func (tm *targetMatcher) typeString() string {
532 return "target"
533}
534
535type edgeMatcher struct {
536 target string
537 dep string
538 annotations []string
539}
540
541func (em *edgeMatcher) matchString(ctx *testContext) string {
542 return ctx.nodes[em.dep] + " -> " + ctx.nodes[em.target] + " [label=\"" + strings.Join(em.annotations, "\\n") + "\"];"
543}
544
545func (tm *edgeMatcher) typeString() string {
546 return "edge"
547}
548
549type getMatcher func(*testContext) matcher
550
551func matchTarget(target string, conditions ...string) getMatcher {
552 return func(ctx *testContext) matcher {
553 ctx.nodes[target] = fmt.Sprintf("n%d", ctx.nextNode)
554 ctx.nextNode++
555 return &targetMatcher{target, append([]string{}, conditions...)}
556 }
557}
558
559func matchEdge(target, dep string, annotations ...string) getMatcher {
560 return func(ctx *testContext) matcher {
561 if _, ok := ctx.nodes[target]; !ok {
562 panic(fmt.Errorf("no node for target %v in %v -> %v [label=\"%s\"];", target, dep, target, strings.Join(annotations, "\\n")))
563 }
564 if _, ok := ctx.nodes[dep]; !ok {
565 panic(fmt.Errorf("no node for dep %v in %v -> %v [label=\"%s\"];", target, dep, target, strings.Join(annotations, "\\n")))
566 }
567 return &edgeMatcher{target, dep, append([]string{}, annotations...)}
568 }
569}
570
571func Test_graphviz(t *testing.T) {
572 tests := []struct {
573 condition string
574 name string
575 roots []string
576 ctx context
577 expectedOut []getMatcher
578 }{
579 {
580 condition: "firstparty",
581 name: "apex",
582 roots: []string{"highest.apex.meta_lic"},
583 expectedOut: []getMatcher{
584 matchTarget("testdata/firstparty/bin/bin1.meta_lic"),
585 matchTarget("testdata/firstparty/bin/bin2.meta_lic"),
586 matchTarget("testdata/firstparty/highest.apex.meta_lic"),
587 matchTarget("testdata/firstparty/lib/liba.so.meta_lic"),
588 matchTarget("testdata/firstparty/lib/libb.so.meta_lic"),
589 matchTarget("testdata/firstparty/lib/libc.a.meta_lic"),
590 matchTarget("testdata/firstparty/lib/libd.so.meta_lic"),
591 matchEdge("testdata/firstparty/bin/bin1.meta_lic", "testdata/firstparty/lib/liba.so.meta_lic", "static"),
592 matchEdge("testdata/firstparty/bin/bin1.meta_lic", "testdata/firstparty/lib/libc.a.meta_lic", "static"),
593 matchEdge("testdata/firstparty/bin/bin2.meta_lic", "testdata/firstparty/lib/libb.so.meta_lic", "dynamic"),
594 matchEdge("testdata/firstparty/bin/bin2.meta_lic", "testdata/firstparty/lib/libd.so.meta_lic", "dynamic"),
595 matchEdge("testdata/firstparty/highest.apex.meta_lic", "testdata/firstparty/bin/bin1.meta_lic", "static"),
596 matchEdge("testdata/firstparty/highest.apex.meta_lic", "testdata/firstparty/bin/bin2.meta_lic", "static"),
597 matchEdge("testdata/firstparty/highest.apex.meta_lic", "testdata/firstparty/lib/liba.so.meta_lic", "static"),
598 matchEdge("testdata/firstparty/highest.apex.meta_lic", "testdata/firstparty/lib/libb.so.meta_lic", "static"),
599 },
600 },
601 {
602 condition: "firstparty",
603 name: "apex_trimmed",
604 roots: []string{"highest.apex.meta_lic"},
605 ctx: context{stripPrefix: "testdata/firstparty/"},
606 expectedOut: []getMatcher{
607 matchTarget("bin/bin1.meta_lic"),
608 matchTarget("bin/bin2.meta_lic"),
609 matchTarget("highest.apex.meta_lic"),
610 matchTarget("lib/liba.so.meta_lic"),
611 matchTarget("lib/libb.so.meta_lic"),
612 matchTarget("lib/libc.a.meta_lic"),
613 matchTarget("lib/libd.so.meta_lic"),
614 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
615 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
616 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
617 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
618 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
619 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
620 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
621 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
622 },
623 },
624 {
625 condition: "firstparty",
626 name: "apex_trimmed_labelled",
627 roots: []string{"highest.apex.meta_lic"},
628 ctx: context{stripPrefix: "testdata/firstparty/", labelConditions: true},
629 expectedOut: []getMatcher{
630 matchTarget("bin/bin1.meta_lic", "notice"),
631 matchTarget("bin/bin2.meta_lic", "notice"),
632 matchTarget("highest.apex.meta_lic", "notice"),
633 matchTarget("lib/liba.so.meta_lic", "notice"),
634 matchTarget("lib/libb.so.meta_lic", "notice"),
635 matchTarget("lib/libc.a.meta_lic", "notice"),
636 matchTarget("lib/libd.so.meta_lic", "notice"),
637 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
638 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
639 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
640 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
641 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
642 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
643 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
644 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
645 },
646 },
647 {
648 condition: "firstparty",
649 name: "container",
650 roots: []string{"container.zip.meta_lic"},
651 expectedOut: []getMatcher{
652 matchTarget("testdata/firstparty/bin/bin1.meta_lic"),
653 matchTarget("testdata/firstparty/bin/bin2.meta_lic"),
654 matchTarget("testdata/firstparty/container.zip.meta_lic"),
655 matchTarget("testdata/firstparty/lib/liba.so.meta_lic"),
656 matchTarget("testdata/firstparty/lib/libb.so.meta_lic"),
657 matchTarget("testdata/firstparty/lib/libc.a.meta_lic"),
658 matchTarget("testdata/firstparty/lib/libd.so.meta_lic"),
659 matchEdge("testdata/firstparty/bin/bin1.meta_lic", "testdata/firstparty/lib/liba.so.meta_lic", "static"),
660 matchEdge("testdata/firstparty/bin/bin1.meta_lic", "testdata/firstparty/lib/libc.a.meta_lic", "static"),
661 matchEdge("testdata/firstparty/bin/bin2.meta_lic", "testdata/firstparty/lib/libb.so.meta_lic", "dynamic"),
662 matchEdge("testdata/firstparty/bin/bin2.meta_lic", "testdata/firstparty/lib/libd.so.meta_lic", "dynamic"),
663 matchEdge("testdata/firstparty/container.zip.meta_lic", "testdata/firstparty/bin/bin1.meta_lic", "static"),
664 matchEdge("testdata/firstparty/container.zip.meta_lic", "testdata/firstparty/bin/bin2.meta_lic", "static"),
665 matchEdge("testdata/firstparty/container.zip.meta_lic", "testdata/firstparty/lib/liba.so.meta_lic", "static"),
666 matchEdge("testdata/firstparty/container.zip.meta_lic", "testdata/firstparty/lib/libb.so.meta_lic", "static"),
667 },
668 },
669 {
670 condition: "firstparty",
671 name: "application",
672 roots: []string{"application.meta_lic"},
673 expectedOut: []getMatcher{
674 matchTarget("testdata/firstparty/application.meta_lic"),
675 matchTarget("testdata/firstparty/bin/bin3.meta_lic"),
676 matchTarget("testdata/firstparty/lib/liba.so.meta_lic"),
677 matchTarget("testdata/firstparty/lib/libb.so.meta_lic"),
678 matchEdge("testdata/firstparty/application.meta_lic", "testdata/firstparty/bin/bin3.meta_lic", "toolchain"),
679 matchEdge("testdata/firstparty/application.meta_lic", "testdata/firstparty/lib/liba.so.meta_lic", "static"),
680 matchEdge("testdata/firstparty/application.meta_lic", "testdata/firstparty/lib/libb.so.meta_lic", "dynamic"),
681 },
682 },
683 {
684 condition: "firstparty",
685 name: "binary",
686 roots: []string{"bin/bin1.meta_lic"},
687 expectedOut: []getMatcher{
688 matchTarget("testdata/firstparty/bin/bin1.meta_lic"),
689 matchTarget("testdata/firstparty/lib/liba.so.meta_lic"),
690 matchTarget("testdata/firstparty/lib/libc.a.meta_lic"),
691 matchEdge("testdata/firstparty/bin/bin1.meta_lic", "testdata/firstparty/lib/liba.so.meta_lic", "static"),
692 matchEdge("testdata/firstparty/bin/bin1.meta_lic", "testdata/firstparty/lib/libc.a.meta_lic", "static"),
693 },
694 },
695 {
696 condition: "firstparty",
697 name: "library",
698 roots: []string{"lib/libd.so.meta_lic"},
699 expectedOut: []getMatcher{matchTarget("testdata/firstparty/lib/libd.so.meta_lic")},
700 },
701 {
702 condition: "notice",
703 name: "apex",
704 roots: []string{"highest.apex.meta_lic"},
705 expectedOut: []getMatcher{
706 matchTarget("testdata/notice/bin/bin1.meta_lic"),
707 matchTarget("testdata/notice/bin/bin2.meta_lic"),
708 matchTarget("testdata/notice/highest.apex.meta_lic"),
709 matchTarget("testdata/notice/lib/liba.so.meta_lic"),
710 matchTarget("testdata/notice/lib/libb.so.meta_lic"),
711 matchTarget("testdata/notice/lib/libc.a.meta_lic"),
712 matchTarget("testdata/notice/lib/libd.so.meta_lic"),
713 matchEdge("testdata/notice/bin/bin1.meta_lic", "testdata/notice/lib/liba.so.meta_lic", "static"),
714 matchEdge("testdata/notice/bin/bin1.meta_lic", "testdata/notice/lib/libc.a.meta_lic", "static"),
715 matchEdge("testdata/notice/bin/bin2.meta_lic", "testdata/notice/lib/libb.so.meta_lic", "dynamic"),
716 matchEdge("testdata/notice/bin/bin2.meta_lic", "testdata/notice/lib/libd.so.meta_lic", "dynamic"),
717 matchEdge("testdata/notice/highest.apex.meta_lic", "testdata/notice/bin/bin1.meta_lic", "static"),
718 matchEdge("testdata/notice/highest.apex.meta_lic", "testdata/notice/bin/bin2.meta_lic", "static"),
719 matchEdge("testdata/notice/highest.apex.meta_lic", "testdata/notice/lib/liba.so.meta_lic", "static"),
720 matchEdge("testdata/notice/highest.apex.meta_lic", "testdata/notice/lib/libb.so.meta_lic", "static"),
721 },
722 },
723 {
724 condition: "notice",
725 name: "apex_trimmed",
726 roots: []string{"highest.apex.meta_lic"},
727 ctx: context{stripPrefix: "testdata/notice/"},
728 expectedOut: []getMatcher{
729 matchTarget("bin/bin1.meta_lic"),
730 matchTarget("bin/bin2.meta_lic"),
731 matchTarget("highest.apex.meta_lic"),
732 matchTarget("lib/liba.so.meta_lic"),
733 matchTarget("lib/libb.so.meta_lic"),
734 matchTarget("lib/libc.a.meta_lic"),
735 matchTarget("lib/libd.so.meta_lic"),
736 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
737 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
738 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
739 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
740 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
741 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
742 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
743 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
744 },
745 },
746 {
747 condition: "notice",
748 name: "apex_trimmed_labelled",
749 roots: []string{"highest.apex.meta_lic"},
750 ctx: context{stripPrefix: "testdata/notice/", labelConditions: true},
751 expectedOut: []getMatcher{
752 matchTarget("bin/bin1.meta_lic", "notice"),
753 matchTarget("bin/bin2.meta_lic", "notice"),
754 matchTarget("highest.apex.meta_lic", "notice"),
755 matchTarget("lib/liba.so.meta_lic", "notice"),
756 matchTarget("lib/libb.so.meta_lic", "notice"),
757 matchTarget("lib/libc.a.meta_lic", "notice"),
758 matchTarget("lib/libd.so.meta_lic", "notice"),
759 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
760 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
761 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
762 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
763 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
764 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
765 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
766 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
767 },
768 },
769 {
770 condition: "notice",
771 name: "container",
772 roots: []string{"container.zip.meta_lic"},
773 expectedOut: []getMatcher{
774 matchTarget("testdata/notice/bin/bin1.meta_lic"),
775 matchTarget("testdata/notice/bin/bin2.meta_lic"),
776 matchTarget("testdata/notice/container.zip.meta_lic"),
777 matchTarget("testdata/notice/lib/liba.so.meta_lic"),
778 matchTarget("testdata/notice/lib/libb.so.meta_lic"),
779 matchTarget("testdata/notice/lib/libc.a.meta_lic"),
780 matchTarget("testdata/notice/lib/libd.so.meta_lic"),
781 matchEdge("testdata/notice/bin/bin1.meta_lic", "testdata/notice/lib/liba.so.meta_lic", "static"),
782 matchEdge("testdata/notice/bin/bin1.meta_lic", "testdata/notice/lib/libc.a.meta_lic", "static"),
783 matchEdge("testdata/notice/bin/bin2.meta_lic", "testdata/notice/lib/libb.so.meta_lic", "dynamic"),
784 matchEdge("testdata/notice/bin/bin2.meta_lic", "testdata/notice/lib/libd.so.meta_lic", "dynamic"),
785 matchEdge("testdata/notice/container.zip.meta_lic", "testdata/notice/bin/bin1.meta_lic", "static"),
786 matchEdge("testdata/notice/container.zip.meta_lic", "testdata/notice/bin/bin2.meta_lic", "static"),
787 matchEdge("testdata/notice/container.zip.meta_lic", "testdata/notice/lib/liba.so.meta_lic", "static"),
788 matchEdge("testdata/notice/container.zip.meta_lic", "testdata/notice/lib/libb.so.meta_lic", "static"),
789 },
790 },
791 {
792 condition: "notice",
793 name: "application",
794 roots: []string{"application.meta_lic"},
795 expectedOut: []getMatcher{
796 matchTarget("testdata/notice/application.meta_lic"),
797 matchTarget("testdata/notice/bin/bin3.meta_lic"),
798 matchTarget("testdata/notice/lib/liba.so.meta_lic"),
799 matchTarget("testdata/notice/lib/libb.so.meta_lic"),
800 matchEdge("testdata/notice/application.meta_lic", "testdata/notice/bin/bin3.meta_lic", "toolchain"),
801 matchEdge("testdata/notice/application.meta_lic", "testdata/notice/lib/liba.so.meta_lic", "static"),
802 matchEdge("testdata/notice/application.meta_lic", "testdata/notice/lib/libb.so.meta_lic", "dynamic"),
803 },
804 },
805 {
806 condition: "notice",
807 name: "binary",
808 roots: []string{"bin/bin1.meta_lic"},
809 expectedOut: []getMatcher{
810 matchTarget("testdata/notice/bin/bin1.meta_lic"),
811 matchTarget("testdata/notice/lib/liba.so.meta_lic"),
812 matchTarget("testdata/notice/lib/libc.a.meta_lic"),
813 matchEdge("testdata/notice/bin/bin1.meta_lic", "testdata/notice/lib/liba.so.meta_lic", "static"),
814 matchEdge("testdata/notice/bin/bin1.meta_lic", "testdata/notice/lib/libc.a.meta_lic", "static"),
815 },
816 },
817 {
818 condition: "notice",
819 name: "library",
820 roots: []string{"lib/libd.so.meta_lic"},
821 expectedOut: []getMatcher{matchTarget("testdata/notice/lib/libd.so.meta_lic")},
822 },
823 {
824 condition: "reciprocal",
825 name: "apex",
826 roots: []string{"highest.apex.meta_lic"},
827 expectedOut: []getMatcher{
828 matchTarget("testdata/reciprocal/bin/bin1.meta_lic"),
829 matchTarget("testdata/reciprocal/bin/bin2.meta_lic"),
830 matchTarget("testdata/reciprocal/highest.apex.meta_lic"),
831 matchTarget("testdata/reciprocal/lib/liba.so.meta_lic"),
832 matchTarget("testdata/reciprocal/lib/libb.so.meta_lic"),
833 matchTarget("testdata/reciprocal/lib/libc.a.meta_lic"),
834 matchTarget("testdata/reciprocal/lib/libd.so.meta_lic"),
835 matchEdge("testdata/reciprocal/bin/bin1.meta_lic", "testdata/reciprocal/lib/liba.so.meta_lic", "static"),
836 matchEdge("testdata/reciprocal/bin/bin1.meta_lic", "testdata/reciprocal/lib/libc.a.meta_lic", "static"),
837 matchEdge("testdata/reciprocal/bin/bin2.meta_lic", "testdata/reciprocal/lib/libb.so.meta_lic", "dynamic"),
838 matchEdge("testdata/reciprocal/bin/bin2.meta_lic", "testdata/reciprocal/lib/libd.so.meta_lic", "dynamic"),
839 matchEdge("testdata/reciprocal/highest.apex.meta_lic", "testdata/reciprocal/bin/bin1.meta_lic", "static"),
840 matchEdge("testdata/reciprocal/highest.apex.meta_lic", "testdata/reciprocal/bin/bin2.meta_lic", "static"),
841 matchEdge("testdata/reciprocal/highest.apex.meta_lic", "testdata/reciprocal/lib/liba.so.meta_lic", "static"),
842 matchEdge("testdata/reciprocal/highest.apex.meta_lic", "testdata/reciprocal/lib/libb.so.meta_lic", "static"),
843 },
844 },
845 {
846 condition: "reciprocal",
847 name: "apex_trimmed",
848 roots: []string{"highest.apex.meta_lic"},
849 ctx: context{stripPrefix: "testdata/reciprocal/"},
850 expectedOut: []getMatcher{
851 matchTarget("bin/bin1.meta_lic"),
852 matchTarget("bin/bin2.meta_lic"),
853 matchTarget("highest.apex.meta_lic"),
854 matchTarget("lib/liba.so.meta_lic"),
855 matchTarget("lib/libb.so.meta_lic"),
856 matchTarget("lib/libc.a.meta_lic"),
857 matchTarget("lib/libd.so.meta_lic"),
858 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
859 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
860 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
861 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
862 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
863 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
864 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
865 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
866 },
867 },
868 {
869 condition: "reciprocal",
870 name: "apex_trimmed_labelled",
871 roots: []string{"highest.apex.meta_lic"},
872 ctx: context{stripPrefix: "testdata/reciprocal/", labelConditions: true},
873 expectedOut: []getMatcher{
874 matchTarget("bin/bin1.meta_lic", "notice"),
875 matchTarget("bin/bin2.meta_lic", "notice"),
876 matchTarget("highest.apex.meta_lic", "notice"),
877 matchTarget("lib/liba.so.meta_lic", "reciprocal"),
878 matchTarget("lib/libb.so.meta_lic", "notice"),
879 matchTarget("lib/libc.a.meta_lic", "reciprocal"),
880 matchTarget("lib/libd.so.meta_lic", "notice"),
881 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
882 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
883 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
884 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
885 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
886 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
887 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
888 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
889 },
890 },
891 {
892 condition: "reciprocal",
893 name: "container",
894 roots: []string{"container.zip.meta_lic"},
895 expectedOut: []getMatcher{
896 matchTarget("testdata/reciprocal/bin/bin1.meta_lic"),
897 matchTarget("testdata/reciprocal/bin/bin2.meta_lic"),
898 matchTarget("testdata/reciprocal/container.zip.meta_lic"),
899 matchTarget("testdata/reciprocal/lib/liba.so.meta_lic"),
900 matchTarget("testdata/reciprocal/lib/libb.so.meta_lic"),
901 matchTarget("testdata/reciprocal/lib/libc.a.meta_lic"),
902 matchTarget("testdata/reciprocal/lib/libd.so.meta_lic"),
903 matchEdge("testdata/reciprocal/bin/bin1.meta_lic", "testdata/reciprocal/lib/liba.so.meta_lic", "static"),
904 matchEdge("testdata/reciprocal/bin/bin1.meta_lic", "testdata/reciprocal/lib/libc.a.meta_lic", "static"),
905 matchEdge("testdata/reciprocal/bin/bin2.meta_lic", "testdata/reciprocal/lib/libb.so.meta_lic", "dynamic"),
906 matchEdge("testdata/reciprocal/bin/bin2.meta_lic", "testdata/reciprocal/lib/libd.so.meta_lic", "dynamic"),
907 matchEdge("testdata/reciprocal/container.zip.meta_lic", "testdata/reciprocal/bin/bin1.meta_lic", "static"),
908 matchEdge("testdata/reciprocal/container.zip.meta_lic", "testdata/reciprocal/bin/bin2.meta_lic", "static"),
909 matchEdge("testdata/reciprocal/container.zip.meta_lic", "testdata/reciprocal/lib/liba.so.meta_lic", "static"),
910 matchEdge("testdata/reciprocal/container.zip.meta_lic", "testdata/reciprocal/lib/libb.so.meta_lic", "static"),
911 },
912 },
913 {
914 condition: "reciprocal",
915 name: "application",
916 roots: []string{"application.meta_lic"},
917 expectedOut: []getMatcher{
918 matchTarget("testdata/reciprocal/application.meta_lic"),
919 matchTarget("testdata/reciprocal/bin/bin3.meta_lic"),
920 matchTarget("testdata/reciprocal/lib/liba.so.meta_lic"),
921 matchTarget("testdata/reciprocal/lib/libb.so.meta_lic"),
922 matchEdge("testdata/reciprocal/application.meta_lic", "testdata/reciprocal/bin/bin3.meta_lic", "toolchain"),
923 matchEdge("testdata/reciprocal/application.meta_lic", "testdata/reciprocal/lib/liba.so.meta_lic", "static"),
924 matchEdge("testdata/reciprocal/application.meta_lic", "testdata/reciprocal/lib/libb.so.meta_lic", "dynamic"),
925 },
926 },
927 {
928 condition: "reciprocal",
929 name: "binary",
930 roots: []string{"bin/bin1.meta_lic"},
931 expectedOut: []getMatcher{
932 matchTarget("testdata/reciprocal/bin/bin1.meta_lic"),
933 matchTarget("testdata/reciprocal/lib/liba.so.meta_lic"),
934 matchTarget("testdata/reciprocal/lib/libc.a.meta_lic"),
935 matchEdge("testdata/reciprocal/bin/bin1.meta_lic", "testdata/reciprocal/lib/liba.so.meta_lic", "static"),
936 matchEdge("testdata/reciprocal/bin/bin1.meta_lic", "testdata/reciprocal/lib/libc.a.meta_lic", "static"),
937 },
938 },
939 {
940 condition: "reciprocal",
941 name: "library",
942 roots: []string{"lib/libd.so.meta_lic"},
943 expectedOut: []getMatcher{matchTarget("testdata/reciprocal/lib/libd.so.meta_lic")},
944 },
945 {
946 condition: "restricted",
947 name: "apex",
948 roots: []string{"highest.apex.meta_lic"},
949 expectedOut: []getMatcher{
950 matchTarget("testdata/restricted/bin/bin1.meta_lic"),
951 matchTarget("testdata/restricted/bin/bin2.meta_lic"),
952 matchTarget("testdata/restricted/highest.apex.meta_lic"),
953 matchTarget("testdata/restricted/lib/liba.so.meta_lic"),
954 matchTarget("testdata/restricted/lib/libb.so.meta_lic"),
955 matchTarget("testdata/restricted/lib/libc.a.meta_lic"),
956 matchTarget("testdata/restricted/lib/libd.so.meta_lic"),
957 matchEdge("testdata/restricted/bin/bin1.meta_lic", "testdata/restricted/lib/liba.so.meta_lic", "static"),
958 matchEdge("testdata/restricted/bin/bin1.meta_lic", "testdata/restricted/lib/libc.a.meta_lic", "static"),
959 matchEdge("testdata/restricted/bin/bin2.meta_lic", "testdata/restricted/lib/libb.so.meta_lic", "dynamic"),
960 matchEdge("testdata/restricted/bin/bin2.meta_lic", "testdata/restricted/lib/libd.so.meta_lic", "dynamic"),
961 matchEdge("testdata/restricted/highest.apex.meta_lic", "testdata/restricted/bin/bin1.meta_lic", "static"),
962 matchEdge("testdata/restricted/highest.apex.meta_lic", "testdata/restricted/bin/bin2.meta_lic", "static"),
963 matchEdge("testdata/restricted/highest.apex.meta_lic", "testdata/restricted/lib/liba.so.meta_lic", "static"),
964 matchEdge("testdata/restricted/highest.apex.meta_lic", "testdata/restricted/lib/libb.so.meta_lic", "static"),
965 },
966 },
967 {
968 condition: "restricted",
969 name: "apex_trimmed",
970 roots: []string{"highest.apex.meta_lic"},
971 ctx: context{stripPrefix: "testdata/restricted/"},
972 expectedOut: []getMatcher{
973 matchTarget("bin/bin1.meta_lic"),
974 matchTarget("bin/bin2.meta_lic"),
975 matchTarget("highest.apex.meta_lic"),
976 matchTarget("lib/liba.so.meta_lic"),
977 matchTarget("lib/libb.so.meta_lic"),
978 matchTarget("lib/libc.a.meta_lic"),
979 matchTarget("lib/libd.so.meta_lic"),
980 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
981 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
982 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
983 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
984 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
985 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
986 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
987 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
988 },
989 },
990 {
991 condition: "restricted",
992 name: "apex_trimmed_labelled",
993 roots: []string{"highest.apex.meta_lic"},
994 ctx: context{stripPrefix: "testdata/restricted/", labelConditions: true},
995 expectedOut: []getMatcher{
996 matchTarget("bin/bin1.meta_lic", "notice"),
997 matchTarget("bin/bin2.meta_lic", "notice"),
998 matchTarget("highest.apex.meta_lic", "notice"),
Bob Badour103eb0f2022-01-10 13:50:57 -0800999 matchTarget("lib/liba.so.meta_lic", "restricted_allows_dynamic_linking"),
Bob Badourfa739da2021-10-25 16:21:00 -07001000 matchTarget("lib/libb.so.meta_lic", "restricted"),
1001 matchTarget("lib/libc.a.meta_lic", "reciprocal"),
1002 matchTarget("lib/libd.so.meta_lic", "notice"),
1003 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
1004 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
1005 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
1006 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
1007 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
1008 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
1009 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
1010 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
1011 },
1012 },
1013 {
1014 condition: "restricted",
1015 name: "container",
1016 roots: []string{"container.zip.meta_lic"},
1017 expectedOut: []getMatcher{
1018 matchTarget("testdata/restricted/bin/bin1.meta_lic"),
1019 matchTarget("testdata/restricted/bin/bin2.meta_lic"),
1020 matchTarget("testdata/restricted/container.zip.meta_lic"),
1021 matchTarget("testdata/restricted/lib/liba.so.meta_lic"),
1022 matchTarget("testdata/restricted/lib/libb.so.meta_lic"),
1023 matchTarget("testdata/restricted/lib/libc.a.meta_lic"),
1024 matchTarget("testdata/restricted/lib/libd.so.meta_lic"),
1025 matchEdge("testdata/restricted/bin/bin1.meta_lic", "testdata/restricted/lib/liba.so.meta_lic", "static"),
1026 matchEdge("testdata/restricted/bin/bin1.meta_lic", "testdata/restricted/lib/libc.a.meta_lic", "static"),
1027 matchEdge("testdata/restricted/bin/bin2.meta_lic", "testdata/restricted/lib/libb.so.meta_lic", "dynamic"),
1028 matchEdge("testdata/restricted/bin/bin2.meta_lic", "testdata/restricted/lib/libd.so.meta_lic", "dynamic"),
1029 matchEdge("testdata/restricted/container.zip.meta_lic", "testdata/restricted/bin/bin1.meta_lic", "static"),
1030 matchEdge("testdata/restricted/container.zip.meta_lic", "testdata/restricted/bin/bin2.meta_lic", "static"),
1031 matchEdge("testdata/restricted/container.zip.meta_lic", "testdata/restricted/lib/liba.so.meta_lic", "static"),
1032 matchEdge("testdata/restricted/container.zip.meta_lic", "testdata/restricted/lib/libb.so.meta_lic", "static"),
1033 },
1034 },
1035 {
1036 condition: "restricted",
1037 name: "application",
1038 roots: []string{"application.meta_lic"},
1039 expectedOut: []getMatcher{
1040 matchTarget("testdata/restricted/application.meta_lic"),
1041 matchTarget("testdata/restricted/bin/bin3.meta_lic"),
1042 matchTarget("testdata/restricted/lib/liba.so.meta_lic"),
1043 matchTarget("testdata/restricted/lib/libb.so.meta_lic"),
1044 matchEdge("testdata/restricted/application.meta_lic", "testdata/restricted/bin/bin3.meta_lic", "toolchain"),
1045 matchEdge("testdata/restricted/application.meta_lic", "testdata/restricted/lib/liba.so.meta_lic", "static"),
1046 matchEdge("testdata/restricted/application.meta_lic", "testdata/restricted/lib/libb.so.meta_lic", "dynamic"),
1047 },
1048 },
1049 {
1050 condition: "restricted",
1051 name: "binary",
1052 roots: []string{"bin/bin1.meta_lic"},
1053 expectedOut: []getMatcher{
1054 matchTarget("testdata/restricted/bin/bin1.meta_lic"),
1055 matchTarget("testdata/restricted/lib/liba.so.meta_lic"),
1056 matchTarget("testdata/restricted/lib/libc.a.meta_lic"),
1057 matchEdge("testdata/restricted/bin/bin1.meta_lic", "testdata/restricted/lib/liba.so.meta_lic", "static"),
1058 matchEdge("testdata/restricted/bin/bin1.meta_lic", "testdata/restricted/lib/libc.a.meta_lic", "static"),
1059 },
1060 },
1061 {
1062 condition: "restricted",
1063 name: "library",
1064 roots: []string{"lib/libd.so.meta_lic"},
1065 expectedOut: []getMatcher{matchTarget("testdata/restricted/lib/libd.so.meta_lic")},
1066 },
1067 {
1068 condition: "proprietary",
1069 name: "apex",
1070 roots: []string{"highest.apex.meta_lic"},
1071 expectedOut: []getMatcher{
1072 matchTarget("testdata/proprietary/bin/bin1.meta_lic"),
1073 matchTarget("testdata/proprietary/bin/bin2.meta_lic"),
1074 matchTarget("testdata/proprietary/highest.apex.meta_lic"),
1075 matchTarget("testdata/proprietary/lib/liba.so.meta_lic"),
1076 matchTarget("testdata/proprietary/lib/libb.so.meta_lic"),
1077 matchTarget("testdata/proprietary/lib/libc.a.meta_lic"),
1078 matchTarget("testdata/proprietary/lib/libd.so.meta_lic"),
1079 matchEdge("testdata/proprietary/bin/bin1.meta_lic", "testdata/proprietary/lib/liba.so.meta_lic", "static"),
1080 matchEdge("testdata/proprietary/bin/bin1.meta_lic", "testdata/proprietary/lib/libc.a.meta_lic", "static"),
1081 matchEdge("testdata/proprietary/bin/bin2.meta_lic", "testdata/proprietary/lib/libb.so.meta_lic", "dynamic"),
1082 matchEdge("testdata/proprietary/bin/bin2.meta_lic", "testdata/proprietary/lib/libd.so.meta_lic", "dynamic"),
1083 matchEdge("testdata/proprietary/highest.apex.meta_lic", "testdata/proprietary/bin/bin1.meta_lic", "static"),
1084 matchEdge("testdata/proprietary/highest.apex.meta_lic", "testdata/proprietary/bin/bin2.meta_lic", "static"),
1085 matchEdge("testdata/proprietary/highest.apex.meta_lic", "testdata/proprietary/lib/liba.so.meta_lic", "static"),
1086 matchEdge("testdata/proprietary/highest.apex.meta_lic", "testdata/proprietary/lib/libb.so.meta_lic", "static"),
1087 },
1088 },
1089 {
1090 condition: "proprietary",
1091 name: "apex_trimmed",
1092 roots: []string{"highest.apex.meta_lic"},
1093 ctx: context{stripPrefix: "testdata/proprietary/"},
1094 expectedOut: []getMatcher{
1095 matchTarget("bin/bin1.meta_lic"),
1096 matchTarget("bin/bin2.meta_lic"),
1097 matchTarget("highest.apex.meta_lic"),
1098 matchTarget("lib/liba.so.meta_lic"),
1099 matchTarget("lib/libb.so.meta_lic"),
1100 matchTarget("lib/libc.a.meta_lic"),
1101 matchTarget("lib/libd.so.meta_lic"),
1102 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
1103 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
1104 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
1105 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
1106 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
1107 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
1108 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
1109 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
1110 },
1111 },
1112 {
1113 condition: "proprietary",
1114 name: "apex_trimmed_labelled",
1115 roots: []string{"highest.apex.meta_lic"},
1116 ctx: context{stripPrefix: "testdata/proprietary/", labelConditions: true},
1117 expectedOut: []getMatcher{
1118 matchTarget("bin/bin1.meta_lic", "notice"),
1119 matchTarget("bin/bin2.meta_lic", "by_exception_only", "proprietary"),
1120 matchTarget("highest.apex.meta_lic", "notice"),
1121 matchTarget("lib/liba.so.meta_lic", "by_exception_only", "proprietary"),
1122 matchTarget("lib/libb.so.meta_lic", "restricted"),
1123 matchTarget("lib/libc.a.meta_lic", "by_exception_only", "proprietary"),
1124 matchTarget("lib/libd.so.meta_lic", "notice"),
1125 matchEdge("bin/bin1.meta_lic", "lib/liba.so.meta_lic", "static"),
1126 matchEdge("bin/bin1.meta_lic", "lib/libc.a.meta_lic", "static"),
1127 matchEdge("bin/bin2.meta_lic", "lib/libb.so.meta_lic", "dynamic"),
1128 matchEdge("bin/bin2.meta_lic", "lib/libd.so.meta_lic", "dynamic"),
1129 matchEdge("highest.apex.meta_lic", "bin/bin1.meta_lic", "static"),
1130 matchEdge("highest.apex.meta_lic", "bin/bin2.meta_lic", "static"),
1131 matchEdge("highest.apex.meta_lic", "lib/liba.so.meta_lic", "static"),
1132 matchEdge("highest.apex.meta_lic", "lib/libb.so.meta_lic", "static"),
1133 },
1134 },
1135 {
1136 condition: "proprietary",
1137 name: "container",
1138 roots: []string{"container.zip.meta_lic"},
1139 expectedOut: []getMatcher{
1140 matchTarget("testdata/proprietary/bin/bin1.meta_lic"),
1141 matchTarget("testdata/proprietary/bin/bin2.meta_lic"),
1142 matchTarget("testdata/proprietary/container.zip.meta_lic"),
1143 matchTarget("testdata/proprietary/lib/liba.so.meta_lic"),
1144 matchTarget("testdata/proprietary/lib/libb.so.meta_lic"),
1145 matchTarget("testdata/proprietary/lib/libc.a.meta_lic"),
1146 matchTarget("testdata/proprietary/lib/libd.so.meta_lic"),
1147 matchEdge("testdata/proprietary/bin/bin1.meta_lic", "testdata/proprietary/lib/liba.so.meta_lic", "static"),
1148 matchEdge("testdata/proprietary/bin/bin1.meta_lic", "testdata/proprietary/lib/libc.a.meta_lic", "static"),
1149 matchEdge("testdata/proprietary/bin/bin2.meta_lic", "testdata/proprietary/lib/libb.so.meta_lic", "dynamic"),
1150 matchEdge("testdata/proprietary/bin/bin2.meta_lic", "testdata/proprietary/lib/libd.so.meta_lic", "dynamic"),
1151 matchEdge("testdata/proprietary/container.zip.meta_lic", "testdata/proprietary/bin/bin1.meta_lic", "static"),
1152 matchEdge("testdata/proprietary/container.zip.meta_lic", "testdata/proprietary/bin/bin2.meta_lic", "static"),
1153 matchEdge("testdata/proprietary/container.zip.meta_lic", "testdata/proprietary/lib/liba.so.meta_lic", "static"),
1154 matchEdge("testdata/proprietary/container.zip.meta_lic", "testdata/proprietary/lib/libb.so.meta_lic", "static"),
1155 },
1156 },
1157 {
1158 condition: "proprietary",
1159 name: "application",
1160 roots: []string{"application.meta_lic"},
1161 expectedOut: []getMatcher{
1162 matchTarget("testdata/proprietary/application.meta_lic"),
1163 matchTarget("testdata/proprietary/bin/bin3.meta_lic"),
1164 matchTarget("testdata/proprietary/lib/liba.so.meta_lic"),
1165 matchTarget("testdata/proprietary/lib/libb.so.meta_lic"),
1166 matchEdge("testdata/proprietary/application.meta_lic", "testdata/proprietary/bin/bin3.meta_lic", "toolchain"),
1167 matchEdge("testdata/proprietary/application.meta_lic", "testdata/proprietary/lib/liba.so.meta_lic", "static"),
1168 matchEdge("testdata/proprietary/application.meta_lic", "testdata/proprietary/lib/libb.so.meta_lic", "dynamic"),
1169 },
1170 },
1171 {
1172 condition: "proprietary",
1173 name: "binary",
1174 roots: []string{"bin/bin1.meta_lic"},
1175 expectedOut: []getMatcher{
1176 matchTarget("testdata/proprietary/bin/bin1.meta_lic"),
1177 matchTarget("testdata/proprietary/lib/liba.so.meta_lic"),
1178 matchTarget("testdata/proprietary/lib/libc.a.meta_lic"),
1179 matchEdge("testdata/proprietary/bin/bin1.meta_lic", "testdata/proprietary/lib/liba.so.meta_lic", "static"),
1180 matchEdge("testdata/proprietary/bin/bin1.meta_lic", "testdata/proprietary/lib/libc.a.meta_lic", "static"),
1181 },
1182 },
1183 {
1184 condition: "proprietary",
1185 name: "library",
1186 roots: []string{"lib/libd.so.meta_lic"},
1187 expectedOut: []getMatcher{matchTarget("testdata/proprietary/lib/libd.so.meta_lic")},
1188 },
1189 }
1190 for _, tt := range tests {
1191 t.Run(tt.condition+" "+tt.name, func(t *testing.T) {
1192 ctx := &testContext{0, make(map[string]string)}
1193
1194 expectedOut := &bytes.Buffer{}
1195 for _, eo := range tt.expectedOut {
1196 m := eo(ctx)
1197 expectedOut.WriteString(m.matchString(ctx))
1198 expectedOut.WriteString("\n")
1199 }
1200
1201 stdout := &bytes.Buffer{}
1202 stderr := &bytes.Buffer{}
1203
1204 rootFiles := make([]string, 0, len(tt.roots))
1205 for _, r := range tt.roots {
1206 rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
1207 }
1208 tt.ctx.graphViz = true
1209 err := dumpGraph(&tt.ctx, stdout, stderr, rootFiles...)
1210 if err != nil {
1211 t.Fatalf("dumpgraph: error = %v, stderr = %v", err, stderr)
1212 return
1213 }
1214 if stderr.Len() > 0 {
1215 t.Errorf("dumpgraph: gotStderr = %v, want none", stderr)
1216 }
1217 outList := strings.Split(stdout.String(), "\n")
1218 outLine := 0
1219 if outList[outLine] != "strict digraph {" {
1220 t.Errorf("dumpgraph: got 1st line %v, want strict digraph {")
1221 }
1222 outLine++
1223 if strings.HasPrefix(strings.TrimLeft(outList[outLine], " \t"), "rankdir") {
1224 outLine++
1225 }
1226 endOut := len(outList)
1227 for endOut > 0 && strings.TrimLeft(outList[endOut-1], " \t") == "" {
1228 endOut--
1229 }
1230 if outList[endOut-1] != "}" {
1231 t.Errorf("dumpgraph: got last line %v, want }", outList[endOut-1])
1232 }
1233 endOut--
1234 if strings.HasPrefix(strings.TrimLeft(outList[endOut-1], " \t"), "{rank=same") {
1235 endOut--
1236 }
1237 expectedList := strings.Split(expectedOut.String(), "\n")
1238 for len(expectedList) > 0 && expectedList[len(expectedList)-1] == "" {
1239 expectedList = expectedList[0 : len(expectedList)-1]
1240 }
1241 matchLine := 0
1242
1243 for outLine < endOut && matchLine < len(expectedList) && strings.TrimLeft(outList[outLine], " \t") == expectedList[matchLine] {
1244 outLine++
1245 matchLine++
1246 }
1247 if outLine < endOut || matchLine < len(expectedList) {
1248 if outLine >= endOut {
1249 t.Errorf("dumpgraph: missing lines at end of graph, want %d lines %v", len(expectedList)-matchLine, strings.Join(expectedList[matchLine:], "\n"))
1250 } else if matchLine >= len(expectedList) {
1251 t.Errorf("dumpgraph: unexpected lines at end of graph starting line %d, got %v, want nothing", outLine+1, strings.Join(outList[outLine:], "\n"))
1252 } else {
1253 t.Errorf("dumpgraph: at line %d, got %v, want %v", outLine+1, strings.Join(outList[outLine:], "\n"), strings.Join(expectedList[matchLine:], "\n"))
1254 }
1255 }
1256 })
1257 }
1258}