View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.rat.anttasks;
18  
19  import static org.assertj.core.api.Assertions.assertThat;
20  import static org.assertj.core.api.Fail.fail;
21  import static org.junit.jupiter.api.Assumptions.assumeTrue;
22  
23  import java.io.BufferedReader;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.IOException;
27  import java.io.InputStreamReader;
28  import java.nio.charset.Charset;
29  import java.nio.charset.StandardCharsets;
30  import java.util.Arrays;
31  import java.util.Optional;
32  
33  import javax.xml.parsers.DocumentBuilder;
34  import javax.xml.parsers.DocumentBuilderFactory;
35  
36  import org.apache.commons.io.IOUtils;
37  import org.apache.rat.ReportConfiguration;
38  import org.apache.rat.ReportConfigurationTest;
39  import org.apache.rat.document.DocumentName;
40  import org.apache.tools.ant.BuildException;
41  import org.apache.tools.ant.MagicNames;
42  import org.apache.tools.ant.Target;
43  import org.apache.tools.ant.Task;
44  import org.apache.tools.ant.UnknownElement;
45  
46  import org.assertj.core.api.Assertions;
47  import org.junit.jupiter.api.BeforeEach;
48  import org.junit.jupiter.api.Disabled;
49  import org.junit.jupiter.api.Test;
50  import org.w3c.dom.Document;
51  
52  public class ReportTest extends AbstractRatAntTaskTest {
53      private final String baseNameStr = String.join(File.separator, new String[]{"src","test","resources","antunit"});
54      private final File antFile = new File(new File(baseNameStr), "report-junit.xml").getAbsoluteFile();
55      private DocumentName documentName;
56  
57      @BeforeEach
58      public void setUp() {
59          File baseFile = antFile.getParentFile();
60          for (int i = 0; i < 4; i++) {
61              baseFile = baseFile.getParentFile();
62          }
63          documentName = DocumentName.builder(antFile).setBaseName(baseFile).build();
64  
65          File f = new File(documentName.getBaseName());
66  
67          StringBuilder sb = new StringBuilder(documentName.getBaseName());
68                      sb.append("antfile: ").append(antFile).append("\n")
69                              .append("baseFile: ").append(baseFile).append("\n");
70          if (!f.exists()) {
71              sb.append(" does not exist (RAT CHECK)\n");
72              System.err.println(sb);
73              Assertions.fail(sb.toString());
74          }
75  
76          sb.append(" DOES exist (RAT CHECK)\n");
77          System.err.println(sb);
78          System.setProperty(MagicNames.PROJECT_BASEDIR, documentName.getBaseName());
79          super.setUp();
80      }
81      @Override
82      protected File getAntFile() {
83          return antFile;
84      }
85  
86      private String logLine(String id) {
87          return logLine(true, documentName.localized("/"), id);
88      }
89      
90      private String logLine(String fileText, String id) {
91          return logLine(true, fileText, id);
92      }
93      
94      private String logLine(boolean approved, String fileText, String id) {
95          return String.format( "%s \\Q%s\\E\\s+S .*\\s+\\Q%s\\E ", approved?" ":"!", fileText, id);
96      }
97      
98      @Test
99      public void testWithReportSentToAnt() {
100         buildRule.executeTarget("testWithReportSentToAnt");
101         assertLogMatches(logLine("AL"));
102     }
103 
104     @Test
105     public void testWithReportSentToFile() throws Exception {
106         final File reportFile = new File(getTempDir(), "selftest.report");
107         final String alLine = String.format("\\Q%s\\E\\s+S ", documentName.localized("/"));
108 
109         if (!getTempDir().mkdirs() && !getTempDir().isDirectory()) {
110             throw new IOException("Could not create temporary directory " + getTempDir());
111         }
112         if (reportFile.isFile() && !reportFile.delete()) {
113             throw new IOException("Unable to remove report file " + reportFile);
114         }
115         buildRule.executeTarget("testWithReportSentToFile");
116         assertLogDoesNotMatch(alLine);
117         assertThat(reportFile).describedAs("Expected report file " + reportFile).isFile();
118         assertFileMatches(reportFile, alLine);
119     }
120 
121     @Test
122     public void testWithALUnknown() {
123         buildRule.executeTarget("testWithALUnknown");
124         assertLogDoesNotMatch(logLine("AL"));
125         assertLogMatches(logLine(false, documentName.localized("/"), "?????"));
126     }
127 
128     @Test
129     public void testCustomLicense() {
130         buildRule.executeTarget("testCustomLicense");
131         assertLogDoesNotMatch(logLine("AL"));
132         assertLogMatches(logLine("newFa"));
133     }
134 
135     @Test
136     public void testCustomMatcher() {
137         buildRule.executeTarget("testCustomMatcher");
138         assertLogDoesNotMatch(logLine("AL"));
139         assertLogMatches(logLine("YASL1"));
140     }
141 
142     @Test
143     public void testInlineCustomMatcher() {
144         buildRule.executeTarget("testInlineCustomMatcher");
145         assertLogDoesNotMatch(logLine("AL"));
146         assertLogMatches(logLine("YASL1"));
147     }
148 
149     @Test
150     public void testCustomMatcherBuilder() {
151         buildRule.executeTarget("testCustomMatcherBuilder");
152         assertLogDoesNotMatch(logLine("AL"));
153         assertLogMatches(logLine("YASL1"));
154     }
155 
156     @Test
157     public void testNoResources() {
158         try {
159             buildRule.executeTarget("testNoResources");
160             fail("Expected Exception");
161         } catch (BuildException e) {
162             final String expect = "You must specify at least one file";
163             assertThat(e.getMessage()).describedAs("Expected " + expect).contains(expect);
164         }
165     }
166 
167     @Test
168     public void testCopyrightBuild() {
169         try {
170             buildRule.executeTarget("testCopyrightBuild");
171             assertLogMatches(logLine("/src/test/resources/antunit/index.apt","YASL1"));
172             assertLogDoesNotMatch(logLine("/index.apt","AL"));
173         } catch (BuildException e) {
174             final String expect = "You must specify at least one file";
175             assertThat(e.getMessage()).describedAs("Expected " + expect).contains(expect);
176         }
177     }
178 
179     private Report getReport(String target) {
180         Target testDefault = buildRule.getProject().getTargets().get(target);
181         Optional<Task> optT = Arrays.stream(testDefault.getTasks()).filter(t -> t.getTaskName().equals("rat:report"))
182                 .findFirst();
183         assertThat(optT).isPresent();
184         optT.get().maybeConfigure();
185         return (Report) ((UnknownElement) optT.get()).getRealThing();
186     }
187 
188     @Test
189     public void testDefault() {
190         Report report = getReport("testDefault");
191         ReportConfiguration config = report.getConfiguration();
192         ReportConfigurationTest.validateDefault(config);
193     }
194 
195     @Test
196     public void testNoLicenseMatchers() {
197         try {
198             buildRule.executeTarget("testNoLicenseMatchers");
199             fail("Expected Exception");
200         } catch (BuildException e) {
201             final String expect = "at least one license";
202             assertThat(e.getMessage()).describedAs("Expected " + expect).contains(expect);
203         }
204     }
205 
206     private String getFirstLine(File pFile) throws IOException {
207         FileInputStream fis = null;
208         InputStreamReader reader = null;
209         BufferedReader breader = null;
210         try {
211             fis = new FileInputStream(pFile);
212             reader = new InputStreamReader(fis, StandardCharsets.UTF_8);
213             breader = new BufferedReader(reader);
214             final String result = breader.readLine();
215             breader.close();
216             return result;
217         } finally {
218             IOUtils.closeQuietly(fis);
219             IOUtils.closeQuietly(reader);
220             IOUtils.closeQuietly(breader);
221         }
222     }
223 
224     @Test
225     public void testAddLicenseHeaders() throws Exception {
226         buildRule.executeTarget("testAddLicenseHeaders");
227 
228         final File origFile = new File("target/anttasks/it-sources/index.apt");
229         final String origFirstLine = getFirstLine(origFile);
230         assertThat(origFirstLine).contains("--");
231         assertThat(origFirstLine).doesNotContain("~~");
232         final File modifiedFile = new File("target/anttasks/it-sources/index.apt.new");
233         final String modifiedFirstLine = getFirstLine(modifiedFile);
234         assertThat(modifiedFirstLine).doesNotContain("--");
235         assertThat(modifiedFirstLine).contains("~~");
236     }
237 
238     /**
239      * Test correct generation of string result if non-UTF8 {@code file.encoding} is set.
240      */
241     @Test
242     @Disabled
243     public void testISO88591() {
244         // In previous versions of the JDK, it used to be possible to
245         // change the value of file.encoding at runtime. As of Java 16,
246         // this is no longer possible. Instead, at this point, we check,
247         // that file.encoding is actually ISO-8859-1. (Within Maven, this
248         // is enforced by the configuration of the surefire plugin.) If not,
249         // we skip this test.
250         assumeTrue("ISO-8859-1".equals(System.getProperty("file.encoding")), "Expected file.encoding=ISO-8859-1");
251         buildRule.executeTarget("testISO88591");
252         assertThat(buildRule.getLog()).describedAs("Log should contain the test umlauts").contains("\u00E4\u00F6\u00FC\u00C4\u00D6\u00DC\u00DF");
253     }
254 
255     /**
256      * Test correct generation of XML file if non-UTF8 {@code file.encoding} is set.
257      */
258     @Test
259     @Disabled
260     public void testISO88591WithFile() throws Exception {
261         // In previous versions of the JDK, it used to be possible to
262         // change the value of file.encoding at runtime. As of Java 16,
263         // this is no longer possible. Instead, at this point, we check,
264         // that file.encoding is actually ISO-8859-1. (Within Maven, this
265         // is enforced by the configuration of the surefire plugin.) If not,
266         // we skip this test.
267         assumeTrue("ISO-8859-1".equals(System.getProperty("file.encoding")), "Expected file.encoding=ISO-8859-1");
268         Charset.defaultCharset();
269         String outputDir = System.getProperty("output.dir", "target/anttasks");
270         String selftestOutput = System.getProperty("report.file", outputDir + "/selftest.report");
271         buildRule.executeTarget("testISO88591WithReportFile");
272         DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
273         boolean documentParsed;
274         try (FileInputStream fis = new FileInputStream(selftestOutput)) {
275             Document doc = db.parse(fis);
276             assertThat(doc.getElementsByTagName("header-sample").item(0).getTextContent())
277                     .describedAs("Report should contain test umlauts")
278                     .contains("\u00E4\u00F6\u00FC\u00C4\u00D6\u00DC\u00DF");
279             documentParsed = true;
280         } catch (Exception ex) {
281             documentParsed = false;
282         }
283         assertThat(documentParsed).describedAs("Report file could not be parsed as XML").isTrue();
284     }
285 
286 }