1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileReader;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.PrintStream;
29 import java.nio.charset.StandardCharsets;
30 import java.nio.file.Files;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.concurrent.atomic.AtomicBoolean;
35 import java.util.regex.Pattern;
36 import javax.xml.parsers.ParserConfigurationException;
37 import javax.xml.xpath.XPath;
38 import javax.xml.xpath.XPathExpressionException;
39 import javax.xml.xpath.XPathFactory;
40 import org.apache.commons.cli.Option;
41 import org.apache.commons.cli.Options;
42 import org.apache.commons.io.IOUtils;
43 import org.apache.commons.lang3.tuple.ImmutablePair;
44 import org.apache.commons.lang3.tuple.Pair;
45 import org.apache.rat.api.RatException;
46 import org.apache.rat.commandline.Arg;
47 import org.apache.rat.commandline.StyleSheets;
48 import org.apache.rat.config.exclusion.StandardCollection;
49 import org.apache.rat.config.results.ClaimValidator;
50 import org.apache.rat.configuration.builders.SpdxBuilder;
51 import org.apache.rat.help.Help;
52 import org.apache.rat.license.ILicense;
53 import org.apache.rat.license.ILicenseFamily;
54 import org.apache.rat.license.LicenseSetFactory;
55 import org.apache.rat.report.claim.ClaimStatistic;
56 import org.apache.rat.test.AbstractOptionsProvider;
57 import org.apache.rat.test.utils.OptionFormatter;
58 import org.apache.rat.test.utils.Resources;
59 import org.apache.rat.testhelpers.FileUtils;
60 import org.apache.rat.testhelpers.TestingLog;
61 import org.apache.rat.testhelpers.TextUtils;
62 import org.apache.rat.testhelpers.XmlUtils;
63 import org.apache.rat.utils.DefaultLog;
64 import org.apache.rat.utils.Log;
65 import org.junit.jupiter.params.provider.ArgumentsProvider;
66 import org.w3c.dom.Document;
67 import org.xml.sax.SAXException;
68
69 import static org.apache.rat.commandline.Arg.HELP_LICENSES;
70 import static org.assertj.core.api.Assertions.assertThat;
71 import static org.assertj.core.api.Fail.fail;
72
73
74
75
76 class ReporterOptionsProvider extends AbstractOptionsProvider implements ArgumentsProvider {
77 static File sourceDir;
78
79
80
81
82 final AtomicBoolean helpCalled = new AtomicBoolean(false);
83
84 public ReporterOptionsProvider() {
85 super(ReporterOptionsTest.testPath.toFile());
86 processTestFunctionAnnotations();
87 testMap.put("addLicense", this::addLicenseTest);
88 testMap.remove("add-license");
89 testMap.put("dir", () -> DefaultLog.getInstance().info("--dir has no valid test"));
90 super.validate(Collections.emptyList());
91 }
92
93
94
95
96
97
98
99
100
101 @Override
102 protected final ReportConfiguration generateConfig(List<Pair<Option, String[]>> args) throws IOException {
103 return generateConfig(args, false);
104 }
105
106 protected final ReportConfiguration generateConfig(List<Pair<Option, String[]>> args, boolean helpExpected) throws IOException {
107 if (sourceDir == null) {
108 throw new IOException("sourceDir not set");
109 }
110 helpCalled.set(false);
111 ReportConfiguration config = OptionCollection.parseCommands(sourceDir, extractArgs(args), o -> helpCalled.set(true), true);
112 assertThat(helpCalled.get()).as("Help was called").isEqualTo(helpExpected);
113 if (config != null && !config.hasSource()) {
114 config.addSource(OptionCollection.getReportable(sourceDir, config));
115 }
116 return config;
117 }
118
119 private void configureSourceDir(Option option) {
120 sourceDir = new File(baseDir, OptionFormatter.getName(option));
121 FileUtils.mkDir(sourceDir);
122 }
123
124 private void validateNoArgSetup() throws IOException, RatException {
125
126 TestingLog log = new TestingLog();
127 DefaultLog.setInstance(log);
128 try {
129 ReportConfiguration config = generateConfig(Collections.emptyList());
130 Reporter reporter = new Reporter(config);
131 ClaimStatistic claimStatistic = reporter.execute();
132 ClaimValidator validator = config.getClaimValidator();
133 assertThat(validator.listIssues(claimStatistic)).isEmpty();
134 } finally {
135 DefaultLog.setInstance(null);
136 }
137
138 }
139
140 @OptionCollectionTest.TestFunction
141 protected void addLicenseTest() {
142 editLicenseTest(Arg.EDIT_ADD.find("addLicense"));
143 }
144
145 @OptionCollectionTest.TestFunction
146 protected void editLicenseTest() {
147 editLicenseTest(Arg.EDIT_ADD.find("edit-license"));
148 }
149
150 private void editLicenseTest(final Option option) {
151 try {
152 configureSourceDir(option);
153 ReportConfiguration config = generateConfig(ImmutablePair.of(option, null));
154 File testFile = writeFile("NoLicense.java", "class NoLicense {}");
155 File resultFile = new File(sourceDir, "NoLicense.java.new");
156 FileUtils.delete(resultFile);
157
158 Reporter reporter = new Reporter(config);
159 ClaimStatistic claimStatistic = reporter.execute();
160 assertThat(claimStatistic).isNotNull();
161 String contents = String.join("\n", IOUtils.readLines(new FileReader(testFile)));
162 assertThat(contents).isEqualTo("class NoLicense {}");
163 assertThat(resultFile).exists();
164 contents = String.join("\n", IOUtils.readLines(new FileReader(resultFile)));
165 assertThat(contents).isEqualTo("/*\n" +
166 " * Licensed to the Apache Software Foundation (ASF) under one\n" +
167 " * or more contributor license agreements. See the NOTICE file\n" +
168 " * distributed with this work for additional information\n" +
169 " * regarding copyright ownership. The ASF licenses this file\n" +
170 " * to you under the Apache License, Version 2.0 (the\n" +
171 " * \"License\"); you may not use this file except in compliance\n" +
172 " * with the License. You may obtain a copy of the License at\n" +
173 " * \n" +
174 " * http://www.apache.org/licenses/LICENSE-2.0\n" +
175 " * \n" +
176 " * Unless required by applicable law or agreed to in writing,\n" +
177 " * software distributed under the License is distributed on an\n" +
178 " * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n" +
179 " * KIND, either express or implied. See the License for the\n" +
180 " * specific language governing permissions and limitations\n" +
181 " * under the License.\n" +
182 " */\n\n" +
183 "class NoLicense {}");
184 } catch (IOException | RatException e) {
185 fail(e.getMessage(), e);
186 }
187 }
188
189 protected File writeFile(String name) {
190 return FileUtils.writeFile(sourceDir, name, Collections.singletonList(name));
191 }
192
193 protected File writeFile(String name, String content) {
194 return FileUtils.writeFile(sourceDir, name, Collections.singletonList(content));
195 }
196
197 protected File writeFile(String name, Iterable<String> content) {
198 return FileUtils.writeFile(sourceDir, name, content);
199 }
200
201 @OptionCollectionTest.TestFunction
202 private void execLicensesDeniedTest(final Option option, final String[] args) {
203 try {
204 configureSourceDir(option);
205 File illumosFile = writeFile("illumousFile.java", "The contents of this file are " +
206 "subject to the terms of the Common Development and Distribution License (the \"License\") You " +
207 "may not use this file except in compliance with the License.");
208
209 validateNoArgSetup();
210
211 ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
212 Reporter reporter = new Reporter(config);
213 ClaimStatistic claimStatistic = reporter.execute();
214 ClaimValidator validator = config.getClaimValidator();
215 assertThat(validator.listIssues(claimStatistic)).containsExactly("UNAPPROVED");
216 } catch (IOException | RatException e) {
217 fail(e.getMessage(), e);
218 }
219 }
220
221 @OptionCollectionTest.TestFunction
222 protected void licensesDeniedTest() {
223 execLicensesDeniedTest(Arg.LICENSES_DENIED.find("licenses-denied"), new String[]{"ILLUMOS"});
224 }
225
226 @OptionCollectionTest.TestFunction
227 protected void licensesDeniedFileTest() {
228 File outputFile = FileUtils.writeFile(baseDir, "licensesDenied.txt", Collections.singletonList("ILLUMOS"));
229 execLicensesDeniedTest(Arg.LICENSES_DENIED_FILE.find("licenses-denied-file"),
230 new String[]{outputFile.getAbsolutePath()});
231 }
232
233 private void noDefaultsTest(final Option option) {
234 try {
235 configureSourceDir(option);
236 File testFile = writeFile("Test.java", Arrays.asList("/*\n", "SPDX-License-Identifier: Apache-2.0\n",
237 "*/\n\n", "class Test {}\n"));
238
239 validateNoArgSetup();
240
241 ReportConfiguration config = generateConfig(ImmutablePair.of(option, null));
242 Reporter reporter = new Reporter(config);
243 try {
244 reporter.execute();
245 fail("Should have thrown exception");
246 } catch (RatException e) {
247 ClaimStatistic claimStatistic = reporter.getClaimsStatistic();
248 ClaimValidator validator = config.getClaimValidator();
249 assertThat(validator.listIssues(claimStatistic)).containsExactlyInAnyOrder("DOCUMENT_TYPES", "LICENSE_CATEGORIES", "LICENSE_NAMES", "STANDARDS");
250 }
251 } catch (IOException | RatException e) {
252 fail(e.getMessage(), e);
253 }
254 }
255
256 @OptionCollectionTest.TestFunction
257 protected void noDefaultLicensesTest() {
258 noDefaultsTest(Arg.CONFIGURATION_NO_DEFAULTS.find("no-default-licenses"));
259 }
260
261 @OptionCollectionTest.TestFunction
262 protected void configurationNoDefaultsTest() {
263 noDefaultsTest(Arg.CONFIGURATION_NO_DEFAULTS.find("configuration-no-defaults"));
264 }
265
266 @OptionCollectionTest.TestFunction
267 protected void counterMaxTest() {
268 Option option = Arg.COUNTER_MAX.option();
269 String[] arg = {null};
270 try {
271 configureSourceDir(option);
272 File testFile = writeFile("Test.java", Arrays.asList("/*\n", "SPDX-License-Identifier: Unapproved\n",
273 "*/\n\n", "class Test {}\n"));
274
275 ReportConfiguration config = generateConfig(Collections.emptyList());
276 Reporter reporter = new Reporter(config);
277 ClaimStatistic claimStatistic = reporter.execute();
278 ClaimValidator validator = config.getClaimValidator();
279 assertThat(validator.listIssues(claimStatistic)).containsExactly("UNAPPROVED");
280
281 arg[0] = "Unapproved:1";
282 config = generateConfig(ImmutablePair.of(option, arg));
283 reporter = new Reporter(config);
284 claimStatistic = reporter.execute();
285 validator = config.getClaimValidator();
286 assertThat(validator.listIssues(claimStatistic)).isEmpty();
287 } catch (IOException | RatException e) {
288 fail(e.getMessage(), e);
289 }
290 }
291
292 @OptionCollectionTest.TestFunction
293 protected void counterMinTest() {
294 Option option = Arg.COUNTER_MIN.option();
295 String[] arg = {null};
296
297 try {
298 configureSourceDir(option);
299 File testFile = writeFile("Test.java", Arrays.asList("/*\n", "SPDX-License-Identifier: Unapproved\n",
300 "*/\n\n", "class Test {}\n"));
301
302 ReportConfiguration config = generateConfig(Collections.emptyList());
303 Reporter reporter = new Reporter(config);
304 ClaimStatistic claimStatistic = reporter.execute();
305 ClaimValidator validator = config.getClaimValidator();
306 assertThat(validator.listIssues(claimStatistic)).containsExactly("UNAPPROVED");
307
308 arg[0] = "Unapproved:1";
309 config = generateConfig(ImmutablePair.of(option, arg));
310 reporter = new Reporter(config);
311 claimStatistic = reporter.execute();
312 validator = config.getClaimValidator();
313 assertThat(validator.listIssues(claimStatistic)).isEmpty();
314 } catch (IOException | RatException e) {
315 fail(e.getMessage(), e);
316 }
317 }
318
319
320 private void execExcludeTest(final Option option, final String[] args) {
321 String[] notExcluded = {"notbaz", "well._afile"};
322 String[] excluded = {"some.foo", "B.bar", "justbaz"};
323 try {
324 configureSourceDir(option);
325 writeFile("notbaz");
326 writeFile("well._afile");
327 writeFile("some.foo");
328 writeFile("B.bar");
329 writeFile("justbaz");
330
331 ReportConfiguration config = generateConfig(Collections.emptyList());
332 Reporter reporter = new Reporter(config);
333 ClaimStatistic claimStatistic = reporter.execute();
334 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(5);
335 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(0);
336
337
338 config = generateConfig(ImmutablePair.of(option, args));
339 reporter = new Reporter(config);
340 claimStatistic = reporter.execute();
341 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
342 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(3);
343 } catch (IOException | RatException e) {
344 fail(e.getMessage(), e);
345 }
346 }
347
348 private void excludeFileTest(final Option option) {
349 configureSourceDir(option);
350 File outputFile = FileUtils.writeFile(baseDir, "exclude.txt", Arrays.asList(EXCLUDE_ARGS));
351 execExcludeTest(option, new String[]{outputFile.getAbsolutePath()});
352 }
353
354 @OptionCollectionTest.TestFunction
355 protected void excludeFileTest() {
356 excludeFileTest(Arg.EXCLUDE_FILE.find("exclude-file"));
357 }
358
359 @OptionCollectionTest.TestFunction
360 protected void inputExcludeFileTest() {
361 excludeFileTest(Arg.EXCLUDE_FILE.find("input-exclude-file"));
362 }
363
364 @OptionCollectionTest.TestFunction
365 protected void excludeTest() {
366 execExcludeTest(Arg.EXCLUDE.find("exclude"), EXCLUDE_ARGS);
367 }
368
369 @OptionCollectionTest.TestFunction
370 protected void inputExcludeTest() {
371 execExcludeTest(Arg.EXCLUDE.find("input-exclude"), EXCLUDE_ARGS);
372 }
373
374 @OptionCollectionTest.TestFunction
375 protected void inputExcludeSizeTest() {
376 Option option = Arg.EXCLUDE_SIZE.option();
377 String[] args = {"5"};
378
379 try {
380 configureSourceDir(option);
381 writeFile("Hi.txt", "Hi");
382 writeFile("Hello.txt", "Hello");
383 writeFile("HelloWorld.txt", "HelloWorld");
384
385 ReportConfiguration config = generateConfig(Collections.emptyList());
386 Reporter reporter = new Reporter(config);
387 ClaimStatistic claimStatistic = reporter.execute();
388 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(3);
389 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(0);
390
391
392 config = generateConfig(ImmutablePair.of(option, args));
393 reporter = new Reporter(config);
394 claimStatistic = reporter.execute();
395 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
396 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(1);
397 } catch (IOException | RatException e) {
398 fail(e.getMessage(), e);
399 }
400 }
401
402 @OptionCollectionTest.TestFunction
403 protected void inputExcludeStdTest() {
404 Option option = Arg.EXCLUDE_STD.find("input-exclude-std");
405 String[] args = {StandardCollection.MAVEN.name()};
406
407
408
409 try {
410 configureSourceDir(option);
411 writeFile("afile~");
412 writeFile(".#afile");
413 writeFile("%afile%");
414 writeFile("._afile");
415 writeFile("afile~more");
416 writeFile("what.#afile");
417 writeFile("%afile%withMore");
418 writeFile("well._afile");
419 writeFile("build.log");
420
421 ReportConfiguration config = generateConfig(Collections.emptyList());
422 Reporter reporter = new Reporter(config);
423 ClaimStatistic claimStatistic = reporter.execute();
424 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(5);
425 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(4);
426
427 config = generateConfig(ImmutablePair.of(option, args));
428 reporter = new Reporter(config);
429 claimStatistic = reporter.execute();
430 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(4);
431 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(5);
432 } catch (IOException | RatException e) {
433 fail(e.getMessage(), e);
434 }
435 }
436
437 @OptionCollectionTest.TestFunction
438 protected void inputExcludeParsedScmTest() {
439 Option option = Arg.EXCLUDE_PARSE_SCM.find("input-exclude-parsed-scm");
440 String[] args = {"GIT"};
441 String[] lines = {
442 "# somethings",
443 "!thingone", "thing*", System.lineSeparator(),
444 "# some fish",
445 "**/fish", "*_fish",
446 "# some colorful directories",
447 "red/", "blue/*/"};
448
449 try {
450 configureSourceDir(option);
451
452 writeFile(".gitignore", Arrays.asList(lines));
453 writeFile("thingone");
454 writeFile("thingtwo");
455
456 File dir = new File(sourceDir, "dir");
457 FileUtils.mkDir(dir);
458 FileUtils.writeFile(dir, "fish_two");
459 FileUtils.writeFile(dir, "fish");
460
461 dir = new File(sourceDir, "red");
462 FileUtils.mkDir(dir);
463 FileUtils.writeFile(dir, "fish");
464
465 dir = new File(sourceDir, "blue/fish");
466 FileUtils.mkDir(dir);
467 FileUtils.writeFile(dir, "dory");
468
469 dir = new File(sourceDir, "some");
470 FileUtils.mkDir(dir);
471 FileUtils.writeFile(dir, "fish");
472 FileUtils.writeFile(dir, "things");
473 FileUtils.writeFile(dir, "thingone");
474
475 dir = new File(sourceDir, "another");
476 FileUtils.mkDir(dir);
477 FileUtils.writeFile(dir, "red_fish");
478
479 ReportConfiguration config = generateConfig(Collections.emptyList());
480 Reporter reporter = new Reporter(config);
481 ClaimStatistic claimStatistic = reporter.execute();
482 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(11);
483
484 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(0);
485
486 config = generateConfig(ImmutablePair.of(option, args));
487 reporter = new Reporter(config);
488 claimStatistic = reporter.execute();
489 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(3);
490 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(8);
491 } catch (IOException | RatException e) {
492 fail(e.getMessage(), e);
493 }
494 }
495
496
497 private void execIncludeTest(final Option option, final String[] args) {
498 Option excludeOption = Arg.EXCLUDE.option();
499 String[] notExcluded = {"B.bar", "justbaz", "notbaz"};
500 String[] excluded = {"some.foo"};
501 try {
502 configureSourceDir(option);
503 writeFile("notbaz");
504 writeFile("some.foo");
505 writeFile("B.bar");
506 writeFile("justbaz");
507
508 ReportConfiguration config = generateConfig(Collections.emptyList());
509 Reporter reporter = new Reporter(config);
510 ClaimStatistic claimStatistic = reporter.execute();
511 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(4);
512 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(0);
513
514
515 config = generateConfig(ImmutablePair.of(excludeOption, EXCLUDE_ARGS));
516 reporter = new Reporter(config);
517 claimStatistic = reporter.execute();
518 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
519
520 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(3);
521
522
523 config = generateConfig(ImmutablePair.of(option, args), ImmutablePair.of(excludeOption, EXCLUDE_ARGS));
524 reporter = new Reporter(config);
525 claimStatistic = reporter.execute();
526 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(3);
527
528 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(1);
529 } catch (IOException | RatException e) {
530 fail(e.getMessage(), e);
531 }
532 }
533
534 private void includeFileTest(final Option option) {
535 File outputFile = FileUtils.writeFile(baseDir, "include.txt", Arrays.asList(INCLUDE_ARGS));
536 execIncludeTest(option, new String[]{outputFile.getAbsolutePath()});
537 }
538
539 @OptionCollectionTest.TestFunction
540 protected void inputIncludeFileTest() {
541 includeFileTest(Arg.INCLUDE_FILE.find("input-include-file"));
542 }
543
544 @OptionCollectionTest.TestFunction
545 protected void includesFileTest() {
546 includeFileTest(Arg.INCLUDE_FILE.find("includes-file"));
547 }
548
549 @OptionCollectionTest.TestFunction
550 protected void includeTest() {
551 execIncludeTest(Arg.INCLUDE.find("include"), INCLUDE_ARGS);
552 }
553
554 @OptionCollectionTest.TestFunction
555 protected void inputIncludeTest() {
556 execIncludeTest(Arg.INCLUDE.find("input-include"), INCLUDE_ARGS);
557 }
558
559 @OptionCollectionTest.TestFunction
560 protected void inputIncludeStdTest() {
561 Option option = Arg.INCLUDE_STD.find("input-include-std");
562 String[] args = {StandardCollection.MISC.name()};
563 try {
564 configureSourceDir(option);
565
566 writeFile("afile~more");
567 writeFile("afile~");
568 writeFile(".#afile");
569 writeFile("%afile%");
570 writeFile("._afile");
571 writeFile("what.#afile");
572 writeFile("%afile%withMore");
573 writeFile("well._afile");
574
575 ImmutablePair<Option, String[]> excludes = ImmutablePair.of(Arg.EXCLUDE.find("input-exclude"),
576 new String[]{"*~more", "*~"});
577
578 ReportConfiguration config = generateConfig(Collections.singletonList(excludes));
579 Reporter reporter = new Reporter(config);
580 ClaimStatistic claimStatistic = reporter.execute();
581 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(3);
582 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(5);
583
584 config = generateConfig(excludes, ImmutablePair.of(option, args));
585 reporter = new Reporter(config);
586 claimStatistic = reporter.execute();
587 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(7);
588 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(1);
589 } catch (IOException | RatException e) {
590 fail(e.getMessage(), e);
591 }
592 }
593
594 @OptionCollectionTest.TestFunction
595 protected void inputSourceTest() {
596 Option option = Arg.SOURCE.find("input-source");
597 try {
598 configureSourceDir(option);
599
600 writeFile("codefile");
601 File inputFile = writeFile("intput.txt", "codefile");
602 writeFile("notcodFile");
603
604 ReportConfiguration config = generateConfig();
605 Reporter reporter = new Reporter(config);
606 ClaimStatistic claimStatistic = reporter.execute();
607 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(3);
608 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(0);
609
610 config = generateConfig(ImmutablePair.of(option, new String[]{inputFile.getAbsolutePath()}));
611 reporter = new Reporter(config);
612 claimStatistic = reporter.execute();
613 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
614 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.IGNORED)).isEqualTo(0);
615 } catch (IOException | RatException e) {
616 fail(e.getMessage(), e);
617 }
618 }
619
620 private ReportConfiguration addCatzLicense(ReportConfiguration config) {
621 String catz = ILicenseFamily.makeCategory("catz");
622 config.addFamily(ILicenseFamily.builder().setLicenseFamilyCategory(catz).setLicenseFamilyName("catz").build());
623 config.addLicense(ILicense.builder().setFamily(catz)
624 .setMatcher(new SpdxBuilder().setName("catz")));
625 return config;
626 }
627
628 private void execLicenseFamiliesApprovedTest(final Option option, final String[] args) {
629 Pair<Option, String[]> arg1 = ImmutablePair.of(option, args);
630 try {
631 configureSourceDir(option);
632
633 writeFile("catz.txt", "SPDX-License-Identifier: catz");
634
635 ReportConfiguration config = addCatzLicense(generateConfig());
636 Reporter reporter = new Reporter(config);
637 ClaimStatistic claimStatistic = reporter.execute();
638
639 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
640 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(0);
641 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
642
643 config = addCatzLicense(generateConfig(arg1));
644 reporter = new Reporter(config);
645 claimStatistic = reporter.execute();
646 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
647 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
648 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(0);
649 } catch (IOException | RatException e) {
650 fail(e.getMessage(), e);
651 }
652 }
653
654 @OptionCollectionTest.TestFunction
655 protected void licenseFamiliesApprovedFileTest() {
656 Option option = Arg.FAMILIES_APPROVED_FILE.find("license-families-approved-file");
657 File outputFile = FileUtils.writeFile(baseDir, "familiesApproved.txt", Collections.singletonList("catz"));
658 execLicenseFamiliesApprovedTest(option, new String[]{outputFile.getAbsolutePath()});
659 }
660
661 @OptionCollectionTest.TestFunction
662 protected void licenseFamiliesApprovedTest() {
663 execLicenseFamiliesApprovedTest(Arg.FAMILIES_APPROVED.find("license-families-approved"),
664 new String[]{"catz"});
665 }
666
667 private void execLicenseFamiliesDeniedTest(final Option option, final String[] args) {
668 Pair<Option, String[]> arg1 = ImmutablePair.of(option, args);
669 String bsd = ILicenseFamily.makeCategory("BSD-3");
670 try {
671 configureSourceDir(option);
672
673
674 writeFile("bsd.txt", "SPDX-License-Identifier: BSD-3-Clause");
675
676 ReportConfiguration config = generateConfig();
677 Reporter reporter = new Reporter(config);
678 ClaimStatistic claimStatistic = reporter.execute();
679 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
680 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
681 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(0);
682
683 config = generateConfig(arg1);
684 reporter = new Reporter(config);
685 claimStatistic = reporter.execute();
686 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
687 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(0);
688 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
689 } catch (IOException | RatException e) {
690 fail(e.getMessage(), e);
691 }
692 }
693
694 @OptionCollectionTest.TestFunction
695 protected void licenseFamiliesDeniedFileTest() {
696 File outputFile = FileUtils.writeFile(baseDir, "familiesDenied.txt", Collections.singletonList("BSD-3"));
697 execLicenseFamiliesDeniedTest(Arg.FAMILIES_DENIED_FILE.find("license-families-denied-file"),
698 new String[]{outputFile.getAbsolutePath()});
699 }
700
701 @OptionCollectionTest.TestFunction
702 protected void licenseFamiliesDeniedTest() {
703 execLicenseFamiliesDeniedTest(Arg.FAMILIES_DENIED.find("license-families-denied"),
704 new String[]{"BSD-3"});
705 }
706
707
708 private void configTest(final Option option) {
709 try {
710 configureSourceDir(option);
711 String[] args = {
712 Resources.getResourceFile("OptionTools/One.xml").getAbsolutePath(),
713 Resources.getResourceFile("OptionTools/Two.xml").getAbsolutePath()};
714
715 Pair<Option, String[]> arg1 = ImmutablePair.of(option, args);
716
717 writeFile("bsd.txt", "SPDX-License-Identifier: BSD-3-Clause");
718 writeFile("one.txt", "one is the lonelest number");
719
720 ReportConfiguration config = generateConfig();
721 Reporter reporter = new Reporter(config);
722 ClaimStatistic claimStatistic = reporter.execute();
723 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
724 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
725 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
726
727 config = generateConfig(arg1);
728 reporter = new Reporter(config);
729 claimStatistic = reporter.execute();
730 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
731 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(2);
732 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(0);
733
734 Pair<Option, String[]> arg2 = ImmutablePair.of(Arg.CONFIGURATION_NO_DEFAULTS.find("configuration-no-defaults"), null);
735
736 config = generateConfig(arg1, arg2);
737 reporter = new Reporter(config);
738 claimStatistic = reporter.execute();
739 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
740 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
741 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
742
743 } catch (IOException | RatException e) {
744 fail(e.getMessage(), e);
745 }
746 }
747
748 @OptionCollectionTest.TestFunction
749 protected void licensesTest() {
750 configTest(Arg.CONFIGURATION.find("licenses"));
751 }
752
753 @OptionCollectionTest.TestFunction
754 protected void configTest() {
755 configTest(Arg.CONFIGURATION.find("config"));
756 }
757
758 @OptionCollectionTest.TestFunction
759 protected void execLicensesApprovedTest(final Option option, String[] args) {
760 Pair<Option, String[]> arg1 = ImmutablePair.of(option, args);
761
762 try {
763 configureSourceDir(option);
764
765 writeFile("gpl.txt", "SPDX-License-Identifier: GPL-1.0-only");
766 writeFile("apl.txt", "SPDX-License-Identifier: Apache-2.0");
767
768 ReportConfiguration config = generateConfig();
769 Reporter reporter = new Reporter(config);
770 ClaimStatistic claimStatistic = reporter.execute();
771 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
772 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
773 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
774
775 config = generateConfig(arg1);
776 reporter = new Reporter(config);
777 claimStatistic = reporter.execute();
778 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
779 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(2);
780 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(0);
781
782
783 } catch (IOException | RatException e) {
784 fail(e.getMessage(), e);
785 }
786 }
787
788 @OptionCollectionTest.TestFunction
789 protected void licensesApprovedFileTest() {
790 File outputFile = FileUtils.writeFile(baseDir, "licensesApproved.txt", Collections.singletonList("GPL1"));
791 execLicensesApprovedTest(Arg.LICENSES_APPROVED_FILE.find("licenses-approved-file"),
792 new String[]{outputFile.getAbsolutePath()});
793 }
794
795 @OptionCollectionTest.TestFunction
796 protected void licensesApprovedTest() {
797 execLicensesApprovedTest(Arg.LICENSES_APPROVED.find("licenses-approved"),
798 new String[]{"GPL1"});
799 }
800
801 @OptionCollectionTest.TestFunction
802 protected void scanHiddenDirectoriesTest() {
803 Option option = Arg.INCLUDE_STD.find("scan-hidden-directories");
804 Pair<Option, String[]> arg1 = ImmutablePair.of(option, null);
805
806 try {
807 configureSourceDir(option);
808
809 writeFile("apl.txt", "SPDX-License-Identifier: Apache-2.0");
810
811 File hiddenDir = new File(sourceDir, ".hiddendir");
812 FileUtils.mkDir(hiddenDir);
813 FileUtils.writeFile(hiddenDir, "gpl.txt", Collections.singletonList("SPDX-License-Identifier: GPL-1.0-only"));
814
815 ReportConfiguration config = generateConfig();
816 Reporter reporter = new Reporter(config);
817 ClaimStatistic claimStatistic = reporter.execute();
818 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
819 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
820 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(0);
821
822 config = generateConfig(arg1);
823 reporter = new Reporter(config);
824 claimStatistic = reporter.execute();
825 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(2);
826 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
827 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
828 } catch (IOException | RatException e) {
829 fail(e.getMessage(), e);
830 }
831 }
832
833 private void outTest(final Option option) {
834 try {
835 configureSourceDir(option);
836 writeFile("apl.txt", "SPDX-License-Identifier: Apache-2.0");
837 File outFile = new File(sourceDir, "outexample");
838 FileUtils.delete(outFile);
839 String[] args = new String[]{outFile.getAbsolutePath()};
840
841 ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
842 Reporter reporter = new Reporter(config);
843 ClaimStatistic claimStatistic = reporter.output();
844 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
845 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(1);
846 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(0);
847
848 String actualText = TextUtils.readFile(outFile);
849 TextUtils.assertContainsExactly(1, "Apache License 2.0: 1 ", actualText);
850 TextUtils.assertContainsExactly(1, "STANDARD: 1 ", actualText);
851
852 } catch (IOException | RatException e) {
853 fail(e.getMessage(), e);
854 }
855 }
856
857 @OptionCollectionTest.TestFunction
858 protected void outTest() {
859 outTest(Arg.OUTPUT_FILE.find("out"));
860 }
861
862 @OptionCollectionTest.TestFunction
863 protected void outputFileTest() {
864 outTest(Arg.OUTPUT_FILE.find("output-file"));
865 }
866
867 private void styleSheetTest(final Option option) {
868 PrintStream origin = System.out;
869 ByteArrayOutputStream baos = new ByteArrayOutputStream();
870 try (PrintStream out = new PrintStream(baos)) {
871 System.setOut(out);
872 configureSourceDir(option);
873
874 File file = writeFile("stylesheet", "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
875 " <xsl:template match=\"@*|node()\">\n" +
876 " Hello world\n" +
877 " </xsl:template>\n" +
878 "</xsl:stylesheet>");
879
880 String[] args = {null};
881 for (StyleSheets sheet : StyleSheets.values()) {
882 args[0] = sheet.arg();
883 ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
884 Reporter reporter = new Reporter(config);
885 ClaimStatistic claimStatistic = reporter.output();
886 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
887 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(0);
888 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
889
890 String actualText = baos.toString(StandardCharsets.UTF_8.name());
891 switch (sheet) {
892 case MISSING_HEADERS:
893 TextUtils.assertContainsExactly(1, "Files with missing headers:" + System.lineSeparator() +
894 " /stylesheet", actualText);
895 break;
896 case PLAIN:
897 TextUtils.assertContainsExactly(1, "Unknown license: 1 ", actualText);
898 TextUtils.assertContainsExactly(1, "?????: 1 ", actualText);
899 break;
900 case XML:
901 TextUtils.assertContainsExactly(1, "<resource encoding=\"ISO-8859-1\" mediaType=\"text/plain\" name=\"/stylesheet\" type=\"STANDARD\">", actualText);
902 break;
903 case UNAPPROVED_LICENSES:
904 TextUtils.assertContainsExactly(1, "Files with unapproved licenses:" + System.lineSeparator() + " /stylesheet", actualText);
905 break;
906 default:
907 fail("No test for stylesheet " + sheet);
908 break;
909 }
910 baos.reset();
911 }
912 args[0] = file.getAbsolutePath();
913 ReportConfiguration config = generateConfig(ImmutablePair.of(option, args));
914 Reporter reporter = new Reporter(config);
915 ClaimStatistic claimStatistic = reporter.output();
916 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
917 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(0);
918 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
919
920 String actualText = baos.toString(StandardCharsets.UTF_8.name());
921 TextUtils.assertContainsExactly(1, "Hello world", actualText);
922
923 } catch (IOException | RatException e) {
924 fail(e.getMessage(), e);
925 } finally {
926 System.setOut(origin);
927 }
928 }
929
930 @OptionCollectionTest.TestFunction
931 protected void stylesheetTest() {
932 styleSheetTest(Arg.OUTPUT_STYLE.find("stylesheet"));
933 }
934
935 @OptionCollectionTest.TestFunction
936 protected void outputStyleTest() {
937 styleSheetTest(Arg.OUTPUT_STYLE.find("output-style"));
938 }
939
940 @OptionCollectionTest.TestFunction
941 protected void xmlTest() {
942 PrintStream origin = System.out;
943 Option option = Arg.OUTPUT_STYLE.find("xml");
944 ByteArrayOutputStream baos = new ByteArrayOutputStream();
945 try (PrintStream out = new PrintStream(baos)) {
946 System.setOut(out);
947 configureSourceDir(option);
948
949 File file = writeFile("stylesheet", "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
950 " <xsl:template match=\"@*|node()\">\n" +
951 " Hello world\n" +
952 " </xsl:template>\n" +
953 "</xsl:stylesheet>");
954
955 ReportConfiguration config = generateConfig(ImmutablePair.of(option, null));
956 Reporter reporter = new Reporter(config);
957 ClaimStatistic claimStatistic = reporter.output();
958 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.STANDARDS)).isEqualTo(1);
959 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.APPROVED)).isEqualTo(0);
960 assertThat(claimStatistic.getCounter(ClaimStatistic.Counter.UNAPPROVED)).isEqualTo(1);
961
962 String actualText = baos.toString(StandardCharsets.UTF_8.name());
963 TextUtils.assertContainsExactly(1, "<resource encoding=\"ISO-8859-1\" mediaType=\"text/plain\" name=\"/stylesheet\" type=\"STANDARD\">", actualText);
964
965 try (InputStream expected = StyleSheets.getStyleSheet("xml").get();
966 InputStream actual = config.getStyleSheet().get()) {
967 assertThat(IOUtils.contentEquals(expected, actual)).as("'xml' does not match").isTrue();
968 }
969 } catch (IOException | RatException e) {
970 fail(e.getMessage(), e);
971 } finally {
972 System.setOut(origin);
973 }
974 }
975
976 @OptionCollectionTest.TestFunction
977 protected void logLevelTest() {
978 PrintStream origin = System.out;
979 Option option = Arg.LOG_LEVEL.find("log-level");
980 ByteArrayOutputStream baos = new ByteArrayOutputStream();
981 Log.Level oldLevel = DefaultLog.getInstance().getLevel();
982 try (PrintStream out = new PrintStream(baos)) {
983 System.setOut(out);
984 configureSourceDir(option);
985
986 ReportConfiguration config = generateConfig();
987 Reporter reporter = new Reporter(config);
988 reporter.output();
989 TextUtils.assertNotContains("DEBUG", baos.toString(StandardCharsets.UTF_8.name()));
990
991 config = generateConfig(ImmutablePair.of(option, new String[]{"debug"}));
992 reporter = new Reporter(config);
993 reporter.output();
994 TextUtils.assertContains("DEBUG", baos.toString(StandardCharsets.UTF_8.name()));
995 } catch (IOException | RatException e) {
996 fail(e.getMessage(), e);
997 } finally {
998 System.setOut(origin);
999 DefaultLog.getInstance().setLevel(oldLevel);
1000 }
1001 }
1002
1003 private void listLicenses(final Option option) {
1004 XPath xPath = XPathFactory.newInstance().newXPath();
1005 String[] args = {null};
1006
1007 try {
1008 configureSourceDir(option);
1009 File outFile = new File(sourceDir, "out.xml");
1010 FileUtils.delete(outFile);
1011 ImmutablePair<Option, String[]> outputFile = ImmutablePair.of(Arg.OUTPUT_FILE.option(), new String[]{outFile.getAbsolutePath()});
1012 ImmutablePair<Option, String[]> stylesheet = ImmutablePair.of(Arg.OUTPUT_STYLE.option(), new String[]{StyleSheets.XML.arg()});
1013 for (LicenseSetFactory.LicenseFilter filter : LicenseSetFactory.LicenseFilter.values()) {
1014 args[0] = filter.name();
1015 ReportConfiguration config = generateConfig(outputFile, stylesheet, ImmutablePair.of(option, args));
1016 Reporter reporter = new Reporter(config);
1017 reporter.output();
1018 Document document = XmlUtils.toDom(new FileInputStream(outFile));
1019 switch (filter) {
1020 case ALL:
1021 XmlUtils.assertIsPresent(filter.name(), document, xPath, "/rat-report/rat-config/licenses/license[@id='AL2.0']");
1022 XmlUtils.assertIsPresent(filter.name(), document, xPath, "/rat-report/rat-config/licenses/license[@id='GPL1']");
1023 break;
1024 case APPROVED:
1025 XmlUtils.assertIsPresent(filter.name(), document, xPath, "/rat-report/rat-config/licenses/license[@id='AL2.0']");
1026 XmlUtils.assertIsNotPresent(filter.name(), document, xPath, "/rat-report/rat-config/licenses/license[@id='GPL1']");
1027 break;
1028 case NONE:
1029 XmlUtils.assertIsNotPresent(filter.name(), document, xPath, "/rat-report/rat-config/licenses/license[@id='AL2.0']");
1030 XmlUtils.assertIsNotPresent(filter.name(), document, xPath, "/rat-report/rat-config/licenses/license[@id='GPL1']");
1031 break;
1032 default:
1033 throw new IllegalArgumentException("Unexpected filter: " + filter);
1034 }
1035 }
1036 } catch (IOException | RatException | SAXException | ParserConfigurationException |
1037 XPathExpressionException e) {
1038 fail(e.getMessage(), e);
1039 }
1040 }
1041
1042 @OptionCollectionTest.TestFunction
1043 protected void listLicensesTest() {
1044 listLicenses(Arg.OUTPUT_LICENSES.find("list-licenses"));
1045 }
1046
1047 @OptionCollectionTest.TestFunction
1048 protected void outputLicensesTest() {
1049 listLicenses(Arg.OUTPUT_LICENSES.find("output-licenses"));
1050 }
1051
1052 private void listFamilies(final Option option) {
1053 XPath xPath = XPathFactory.newInstance().newXPath();
1054 String[] args = {null};
1055
1056 try {
1057 configureSourceDir(option);
1058 File outFile = new File(sourceDir, "out.xml");
1059 FileUtils.delete(outFile);
1060 ImmutablePair<Option, String[]> outputFile = ImmutablePair.of(Arg.OUTPUT_FILE.option(), new String[]{outFile.getAbsolutePath()});
1061 ImmutablePair<Option, String[]> stylesheet = ImmutablePair.of(Arg.OUTPUT_STYLE.option(), new String[]{StyleSheets.XML.arg()});
1062 for (LicenseSetFactory.LicenseFilter filter : LicenseSetFactory.LicenseFilter.values()) {
1063 args[0] = filter.name();
1064 ReportConfiguration config = generateConfig(outputFile, stylesheet, ImmutablePair.of(option, args));
1065 Reporter reporter = new Reporter(config);
1066 reporter.output();
1067 Document document = XmlUtils.toDom(Files.newInputStream(outFile.toPath()));
1068 switch (filter) {
1069 case ALL:
1070 XmlUtils.assertIsPresent(filter.name(), document, xPath, "/rat-report/rat-config/families/family[@id='AL']");
1071 XmlUtils.assertIsPresent(filter.name(), document, xPath, "/rat-report/rat-config/families/family[@id='GPL']");
1072 break;
1073 case APPROVED:
1074 XmlUtils.assertIsPresent(filter.name(), document, xPath, "/rat-report/rat-config/families/family[@id='AL']");
1075 XmlUtils.assertIsNotPresent(filter.name(), document, xPath, "/rat-report/rat-config/families/family[@id='GPL']");
1076 break;
1077 case NONE:
1078 XmlUtils.assertIsNotPresent(filter.name(), document, xPath, "/rat-report/rat-config/families/family[@id='AL']");
1079 XmlUtils.assertIsNotPresent(filter.name(), document, xPath, "/rat-report/rat-config/families/family[@id='GPL']");
1080 break;
1081 default:
1082 throw new IllegalArgumentException("Unexpected filter: " + filter);
1083 }
1084 }
1085 } catch (IOException | RatException | SAXException | ParserConfigurationException |
1086 XPathExpressionException e) {
1087 fail(e.getMessage(), e);
1088 }
1089 }
1090
1091 @OptionCollectionTest.TestFunction
1092 protected void listFamiliesTest() {
1093 listFamilies(Arg.OUTPUT_FAMILIES.find("list-families"));
1094 }
1095
1096 @OptionCollectionTest.TestFunction
1097 protected void outputFamiliesTest() {
1098 listFamilies(Arg.OUTPUT_FAMILIES.find("output-families"));
1099 }
1100
1101 private void archiveTest(final Option option) {
1102 XPath xPath = XPathFactory.newInstance().newXPath();
1103 String[] args = {null};
1104
1105 try {
1106 configureSourceDir(option);
1107 File outFile = new File(sourceDir, "out.xml");
1108 FileUtils.delete(outFile);
1109 ImmutablePair<Option, String[]> outputFile = ImmutablePair.of(Arg.OUTPUT_FILE.option(), new String[]{outFile.getAbsolutePath()});
1110 ImmutablePair<Option, String[]> stylesheet = ImmutablePair.of(Arg.OUTPUT_STYLE.option(), new String[]{StyleSheets.XML.arg()});
1111 File archive = Resources.getResourceFile("tikaFiles/archive/dummy.jar");
1112 File localArchive = new File(sourceDir, "dummy.jar");
1113 try (InputStream in = Files.newInputStream(archive.toPath());
1114 OutputStream out = Files.newOutputStream(localArchive.toPath())) {
1115 IOUtils.copy(in, out);
1116 }
1117
1118 for (ReportConfiguration.Processing proc : ReportConfiguration.Processing.values()) {
1119 args[0] = proc.name();
1120 ReportConfiguration config = generateConfig(outputFile, stylesheet, ImmutablePair.of(option, args));
1121 Reporter reporter = new Reporter(config);
1122 reporter.output();
1123
1124 Document document = XmlUtils.toDom(Files.newInputStream(outFile.toPath()));
1125 XmlUtils.assertIsPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']");
1126 switch (proc) {
1127 case ABSENCE:
1128 XmlUtils.assertIsPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']/license[@family='AL ']");
1129 XmlUtils.assertIsPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']/license[@family='?????']");
1130 break;
1131 case PRESENCE:
1132 XmlUtils.assertIsPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']/license[@family='AL ']");
1133 XmlUtils.assertIsNotPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']/license[@family='?????']");
1134 break;
1135 case NOTIFICATION:
1136 XmlUtils.assertIsNotPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']/license[@family='AL ']");
1137 XmlUtils.assertIsNotPresent(proc.name(), document, xPath, "/rat-report/resource[@name='/dummy.jar']/license[@family='?????']");
1138 break;
1139 default:
1140 throw new IllegalArgumentException("Unexpected processing " + proc);
1141 }
1142 }
1143 } catch (IOException | RatException | SAXException | ParserConfigurationException |
1144 XPathExpressionException e) {
1145 fail(e.getMessage(), e);
1146 }
1147 }
1148
1149 @OptionCollectionTest.TestFunction
1150 protected void outputArchiveTest() {
1151 archiveTest(Arg.OUTPUT_ARCHIVE.find("output-archive"));
1152 }
1153
1154 private void standardTest(final Option option) {
1155 XPath xPath = XPathFactory.newInstance().newXPath();
1156 String[] args = {null};
1157
1158 try {
1159 configureSourceDir(option);
1160 File outFile = new File(sourceDir, "out.xml");
1161 ImmutablePair<Option, String[]> outputFile = ImmutablePair.of(Arg.OUTPUT_FILE.option(), new String[]{outFile.getAbsolutePath()});
1162 ImmutablePair<Option, String[]> stylesheet = ImmutablePair.of(Arg.OUTPUT_STYLE.option(), new String[]{StyleSheets.XML.arg()});
1163
1164 writeFile("Test.java", Arrays.asList("/*\n", "SPDX-License-Identifier: Apache-2.0\n",
1165 "*/\n\n", "class Test {}\n"));
1166 writeFile("Missing.java", Arrays.asList("/* no license */\n\n", "class Test {}\n"));
1167
1168 String testDoc = "/rat-report/resource[@name='/Test.java']";
1169 String missingDoc = "/rat-report/resource[@name='/Missing.java']";
1170
1171 for (ReportConfiguration.Processing proc : ReportConfiguration.Processing.values()) {
1172 args[0] = proc.name();
1173 ReportConfiguration config = generateConfig(outputFile, stylesheet, ImmutablePair.of(option, args));
1174 Reporter reporter = new Reporter(config);
1175 reporter.output();
1176
1177 Document document = XmlUtils.toDom(Files.newInputStream(outFile.toPath()));
1178 XmlUtils.assertIsPresent(proc.name(), document, xPath, testDoc);
1179 XmlUtils.assertIsPresent(proc.name(), document, xPath, missingDoc);
1180
1181 switch (proc) {
1182 case ABSENCE:
1183 XmlUtils.assertIsPresent(proc.name(), document, xPath, testDoc + "/license[@family='AL ']");
1184 XmlUtils.assertIsPresent(proc.name(), document, xPath, missingDoc + "/license[@family='?????']");
1185 break;
1186 case PRESENCE:
1187 XmlUtils.assertIsPresent(proc.name(), document, xPath, testDoc + "/license[@family='AL ']");
1188 XmlUtils.assertIsNotPresent(proc.name(), document, xPath, missingDoc + "/license[@family='?????']");
1189 break;
1190 case NOTIFICATION:
1191 XmlUtils.assertIsNotPresent(proc.name(), document, xPath, testDoc + "/license[@family='AL ']");
1192 XmlUtils.assertIsNotPresent(proc.name(), document, xPath, missingDoc + "/license[@family='?????']");
1193 break;
1194 default:
1195 throw new IllegalArgumentException("Unexpected processing " + proc);
1196 }
1197 }
1198 } catch (IOException | RatException | SAXException | ParserConfigurationException |
1199 XPathExpressionException e) {
1200 fail(e.getMessage(), e);
1201 }
1202 }
1203
1204 @OptionCollectionTest.TestFunction
1205 protected void outputStandardTest() {
1206 standardTest(Arg.OUTPUT_STANDARD.find("output-standard"));
1207 }
1208
1209 private void editCopyrightTest(final Option option, final Option extraOption) {
1210 final String myCopyright = "MyCopyright";
1211 Pair<Option, String[]> arg1 = ImmutablePair.of(option, new String[]{myCopyright});
1212 final boolean forced = Arg.EDIT_OVERWRITE.option().equals(extraOption);
1213 final boolean dryRun = Arg.DRY_RUN.option().equals(extraOption);
1214 Pair<Option, String[]> extraArg = null;
1215 if (forced || dryRun) {
1216 extraArg = ImmutablePair.of(extraOption, null);
1217 }
1218
1219 try {
1220 configureSourceDir(option);
1221 File javaFile = writeFile("Missing.java", Arrays.asList("/* no license */\n\n", "class Test {}\n"));
1222 File newJavaFile = new File(sourceDir, "Missing.java.new");
1223 FileUtils.delete(newJavaFile);
1224
1225 ReportConfiguration config = extraArg != null ? generateConfig(arg1, extraArg) : generateConfig(arg1);
1226 Reporter reporter = new Reporter(config);
1227 reporter.execute();
1228
1229 String actualText = TextUtils.readFile(javaFile);
1230 TextUtils.assertNotContains(myCopyright, actualText);
1231
1232 Pair<Option, String[]> arg2 = ImmutablePair.of(Arg.EDIT_ADD.find("edit-license"), null);
1233 config = extraArg != null ? generateConfig(arg1, arg2, extraArg) : generateConfig(arg1, arg2);
1234 reporter = new Reporter(config);
1235 reporter.execute();
1236
1237 actualText = TextUtils.readFile(javaFile);
1238 if (forced) {
1239 TextUtils.assertContains(myCopyright, actualText);
1240 assertThat(newJavaFile).doesNotExist();
1241 } else if (dryRun) {
1242 TextUtils.assertNotContains(myCopyright, actualText);
1243 assertThat(newJavaFile).doesNotExist();
1244 } else {
1245 TextUtils.assertNotContains(myCopyright, actualText);
1246 assertThat(newJavaFile).exists();
1247 }
1248 } catch (IOException | RatException e) {
1249 fail(e.getMessage(), e);
1250 }
1251 }
1252
1253 @OptionCollectionTest.TestFunction
1254 protected void copyrightTest() {
1255 editCopyrightTest(Arg.EDIT_COPYRIGHT.find("copyright"), null);
1256 }
1257
1258 @OptionCollectionTest.TestFunction
1259 protected void editCopyrightTest() {
1260 editCopyrightTest(Arg.EDIT_COPYRIGHT.find("edit-copyright"), null);
1261 }
1262
1263 @OptionCollectionTest.TestFunction
1264 protected void forceTest() {
1265 editCopyrightTest(Arg.EDIT_COPYRIGHT.find("edit-copyright"), Arg.EDIT_OVERWRITE.find("force"));
1266 }
1267
1268 @OptionCollectionTest.TestFunction
1269 protected void editOverwriteTest() {
1270 editCopyrightTest(Arg.EDIT_COPYRIGHT.find("edit-copyright"), Arg.EDIT_OVERWRITE.find("edit-overwrite"));
1271 }
1272
1273 @OptionCollectionTest.TestFunction
1274 @Override
1275 public void helpTest() {
1276 PrintStream origin = System.out;
1277 Options options = OptionCollection.buildOptions();
1278 Pair<Option, String[]> arg1 = ImmutablePair.of(OptionCollection.HELP, null);
1279 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1280 String actualText = null;
1281 try (PrintStream out = new PrintStream(baos)) {
1282 System.setOut(out);
1283 configureSourceDir(OptionCollection.HELP);
1284
1285 ReportConfiguration config = generateConfig(Arrays.asList(arg1), true);
1286 assertThat(helpCalled.get()).as("Help was not called").isTrue();
1287 new Help(System.out).printUsage(options);
1288 actualText = baos.toString(StandardCharsets.UTF_8.name());
1289 } catch (IOException e) {
1290 fail(e.getMessage(), e);
1291 } finally {
1292 System.setOut(origin);
1293 }
1294
1295
1296 assertThat(actualText).contains("====== Available Options ======");
1297 for (Option option : options.getOptions()) {
1298 StringBuilder regex = new StringBuilder();
1299 if (option.getOpt() != null) {
1300 regex.append("-").append(option.getOpt());
1301 if (option.hasLongOpt()) {
1302 regex.append(",");
1303 }
1304 }
1305 if (option.hasLongOpt()) {
1306 regex.append("--").append(option.getLongOpt());
1307 }
1308 if (option.hasArg()) {
1309 String name = option.getArgName() == null ? "arg" : option.getArgName();
1310 regex.append(".+\\<").append(name).append("\\>");
1311 }
1312 if (option.isDeprecated()) {
1313 regex.append(".+\\[Deprecated ");
1314 }
1315 assertThat(Pattern.compile(regex.toString()).matcher(actualText).find()).as("missing '" + regex + "'").isTrue();
1316 }
1317
1318 assertThat(actualText).contains("====== Argument Types ======");
1319 assertThat(actualText).contains("====== Standard Collections ======");
1320 for (StandardCollection collection : StandardCollection.values()) {
1321 assertThat(actualText).contains("<" + collection.name() + ">");
1322 }
1323 }
1324
1325 @OptionCollectionTest.TestFunction
1326 protected void helpLicensesTest() {
1327 PrintStream origin = System.out;
1328 Option option = HELP_LICENSES.option();
1329 Pair<Option, String[]> arg1 = ImmutablePair.of(option, null);
1330 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1331 String actualText = null;
1332 try (PrintStream out = new PrintStream(baos)) {
1333 System.setOut(out);
1334 configureSourceDir(option);
1335 ReportConfiguration config = generateConfig(arg1);
1336 actualText = baos.toString(StandardCharsets.UTF_8.name());
1337 } catch (IOException e) {
1338 fail(e.getMessage(), e);
1339 } finally {
1340 System.setOut(origin);
1341 }
1342
1343 assertThat(actualText).isNotNull();
1344 TextUtils.assertContains("====== Licenses ======", actualText);
1345 TextUtils.assertContains("====== Defined Matchers ======", actualText);
1346 TextUtils.assertContains("====== Defined Families ======", actualText);
1347 }
1348
1349 @OptionCollectionTest.TestFunction
1350 protected void dryRunTest() {
1351 editCopyrightTest(Arg.EDIT_COPYRIGHT.find("edit-copyright"), Arg.DRY_RUN.find("dry-run"));
1352 }
1353 }