View Javadoc
1   package org.apache.maven.plugin.pmd;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedReader;
23  import java.io.File;
24  import java.io.FileReader;
25  import java.io.IOException;
26  import java.net.URL;
27  import java.nio.charset.StandardCharsets;
28  import java.util.Locale;
29  
30  import org.apache.commons.io.IOUtils;
31  import org.apache.commons.lang3.StringUtils;
32  import org.codehaus.plexus.util.FileUtils;
33  
34  import com.github.tomakehurst.wiremock.WireMockServer;
35  import com.github.tomakehurst.wiremock.client.WireMock;
36  
37  /**
38   * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
39   * @version $Id: PmdReportTest.html 999063 2016-10-08 16:53:12Z adangel $
40   */
41  public class PmdReportTest
42      extends AbstractPmdReportTest
43  {
44      /**
45       * {@inheritDoc}
46       */
47      @Override
48      protected void setUp()
49          throws Exception
50      {
51          super.setUp();
52          FileUtils.deleteDirectory( new File( getBasedir(), "target/test/unit" ) );
53      }
54  
55      public void testDefaultConfiguration()
56          throws Exception
57      {
58          FileUtils.copyDirectoryStructure( new File( getBasedir(),
59                                                      "src/test/resources/unit/default-configuration/jxr-files" ),
60                                            new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
61  
62          File testPom =
63              new File( getBasedir(),
64                        "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml" );
65          PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
66          mojo.execute();
67  
68          // check if the PMD files were generated
69          File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
70          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
71  
72          // check if the rulesets, that have been applied, have been copied
73          generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/java-basic.xml" );
74          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
75  
76          generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/java-imports.xml" );
77          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
78  
79          generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/java-unusedcode.xml" );
80          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
81  
82          generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
83          renderer( mojo, generatedFile );
84          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
85  
86          // check if there's a link to the JXR files
87          String str = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" ) );
88  
89          assertTrue( str.contains( "/xref/def/configuration/App.html#L31" ) );
90  
91          assertTrue( str.contains( "/xref/def/configuration/AppSample.html#L45" ) );
92      }
93  
94      public void testJavascriptConfiguration()
95          throws Exception
96      {
97          File testPom =
98              new File( getBasedir(),
99                        "src/test/resources/unit/default-configuration/javascript-configuration-plugin-config.xml" );
100         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
101         mojo.execute();
102 
103         // check if the PMD files were generated
104         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
105         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
106 
107         // these are the rulesets, that have been applied...
108         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/ecmascript-basic.xml" );
109         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
110 
111         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/ecmascript-braces.xml" );
112         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
113 
114         generatedFile =
115             new File( getBasedir(), "target/test/unit/default-configuration/target/ecmascript-unnecessary.xml" );
116         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
117 
118         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
119         renderer( mojo, generatedFile );
120         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
121 
122         String str = readFile( generatedFile );
123         assertTrue( str.contains( "Avoid using global variables" ) );
124     }
125 
126     public void testFileURL()
127         throws Exception
128     {
129         FileUtils.copyDirectoryStructure( new File( getBasedir(),
130                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
131                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
132 
133         File testPom =
134             new File( getBasedir(),
135                       "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml" );
136         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
137 
138         // Additional test case for MPMD-174 (http://jira.codehaus.org/browse/MPMD-174).
139         WireMockServer mockServer = new WireMockServer( 3456 );
140         mockServer.start();
141 
142         String sonarRuleset =
143             IOUtils.toString( getClass().getClassLoader().getResourceAsStream( "unit/default-configuration/rulesets/sonar-way-ruleset.xml" ),
144                     StandardCharsets.UTF_8 );
145 
146         String sonarMainPageHtml =
147             IOUtils.toString( getClass().getClassLoader().getResourceAsStream( "unit/default-configuration/rulesets/sonar-main-page.html" ),
148                     StandardCharsets.UTF_8 );
149 
150         final String sonarBaseUrl = "/profiles";
151         final String sonarProfileUrl = sonarBaseUrl + "/export?format=pmd&language=java&name=Sonar%2520way";
152         final String sonarExportRulesetUrl = "http://localhost:" + mockServer.port() + sonarProfileUrl;
153 
154         mockServer.stubFor( WireMock.get( WireMock.urlEqualTo( sonarBaseUrl ) ).willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
155                                                                                                                                                "text/html" ).withBody( sonarMainPageHtml ) ) );
156 
157         mockServer.stubFor( WireMock.get( WireMock.urlEqualTo( sonarProfileUrl ) ).willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
158                                                                                                                                                   "text/xml" ).withBody( sonarRuleset ) ) );
159 
160         URL url = getClass().getClassLoader().getResource( "rulesets/java/basic.xml" );
161         URL url2 = getClass().getClassLoader().getResource( "rulesets/java/unusedcode.xml" );
162         URL url3 = getClass().getClassLoader().getResource( "rulesets/java/imports.xml" );
163         mojo.setRulesets( new String[] { url.toString(), url2.toString(), url3.toString(), sonarExportRulesetUrl } );
164 
165         mojo.execute();
166 
167         // check if the PMD files were generated
168         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
169         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
170 
171         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/basic.xml" );
172         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
173 
174         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/imports.xml" );
175         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
176 
177         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/unusedcode.xml" );
178         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
179 
180         generatedFile =
181             new File( getBasedir(),
182                       "target/test/unit/default-configuration/target/export_format_pmd_language_java_name_Sonar_2520way.xml" );
183         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
184 
185         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
186         renderer( mojo, generatedFile );
187         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
188 
189         // check if there's a link to the JXR files
190         String str = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" ) );
191 
192         assertTrue( str.contains( "/xref/def/configuration/App.html#L31" ) );
193 
194         assertTrue( str.contains( "/xref/def/configuration/AppSample.html#L45" ) );
195 
196         mockServer.stop();
197     }
198 
199     /**
200      * With custom rulesets
201      *
202      * @throws Exception
203      */
204     public void testCustomConfiguration()
205         throws Exception
206     {
207         File testPom =
208             new File( getBasedir(),
209                       "src/test/resources/unit/custom-configuration/custom-configuration-plugin-config.xml" );
210 
211         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
212         mojo.execute();
213 
214         // check the generated files
215         File generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/pmd.csv" );
216         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
217 
218         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/custom.xml" );
219         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
220 
221         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" );
222         renderer( mojo, generatedFile );
223         renderer( mojo, generatedFile );
224         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
225 
226         // check if custom ruleset was applied
227         String str = readFile( new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" ) );
228         assertTrue( lowerCaseContains( str, "Avoid using if statements without curly braces" ) );
229 
230         // Must be false as IfElseStmtsMustUseBraces is excluded!
231         assertFalse( lowerCaseContains( str, "Avoid using if...else statements without curly braces" ) );
232 
233         assertFalse( "unnecessary constructor should not be triggered because of low priority",
234                     lowerCaseContains( str, "Avoid unnecessary constructors - the compiler will generate these for you" ) );
235 
236         // veryLongVariableNameWithViolation is really too long
237         assertTrue( lowerCaseContains( str, "veryLongVariableNameWithViolation" ) );
238         // notSoLongVariableName should not be reported
239         assertFalse( lowerCaseContains( str, "notSoLongVariableName" ) );
240     }
241 
242     /**
243      * Verify skip parameter
244      *
245      * @throws Exception
246      */
247     public void testSkipConfiguration()
248         throws Exception
249     {
250         File testPom = new File( getBasedir(), "src/test/resources/unit/custom-configuration/skip-plugin-config.xml" );
251         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
252         mojo.execute();
253 
254         // verify the generated files do not exist because PMD was skipped
255         File generatedFile = new File( getBasedir(), "target/test/unit/skip-configuration/target/pmd.csv" );
256         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
257 
258         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/custom.xml" );
259         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
260 
261         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" );
262         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
263     }
264 
265     public void testSkipEmptyReportConfiguration()
266         throws Exception
267     {
268         File testPom =
269             new File( getBasedir(), "src/test/resources/unit/empty-report/skip-empty-report-plugin-config.xml" );
270         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
271         mojo.execute();
272 
273         // verify the generated files do not exist because PMD was skipped
274         File generatedFile = new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" );
275         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
276     }
277 
278     public void testEmptyReportConfiguration()
279         throws Exception
280     {
281         File testPom = new File( getBasedir(), "src/test/resources/unit/empty-report/empty-report-plugin-config.xml" );
282         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
283         mojo.execute();
284 
285         // verify the generated files do exist, even if there are no violations
286         File generatedFile = new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" );
287         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
288         String str = readFile( new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" ) );
289         assertFalse( lowerCaseContains( str, "Hello.java" ) );
290     }
291 
292     public void testInvalidFormat()
293         throws Exception
294     {
295         try
296         {
297             File testPom =
298                 new File( getBasedir(), "src/test/resources/unit/invalid-format/invalid-format-plugin-config.xml" );
299             PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
300             setVariableValueToObject( mojo, "compileSourceRoots", mojo.project.getCompileSourceRoots() );
301             mojo.executeReport( Locale.ENGLISH );
302 
303             fail( "Must throw MavenReportException." );
304         }
305         catch ( Exception e )
306         {
307             assertTrue( true );
308         }
309     }
310 
311     public void testInvalidTargetJdk()
312         throws Exception
313     {
314         try
315         {
316             File testPom =
317                 new File( getBasedir(), "src/test/resources/unit/invalid-format/invalid-target-jdk-plugin-config.xml" );
318             PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
319             mojo.execute();
320 
321             fail( "Must throw MavenReportException." );
322         }
323         catch ( Exception e )
324         {
325             assertTrue( true );
326         }
327     }
328 
329     /**
330      * Read the contents of the specified file object into a string
331      *
332      * @param file the file to be read
333      * @return a String object that contains the contents of the file
334      * @throws java.io.IOException
335      */
336     private String readFile( File file )
337         throws IOException
338     {
339         try ( BufferedReader reader = new BufferedReader( new FileReader( file ) ) )
340         {
341             final StringBuilder str = new StringBuilder( (int) file.length() );
342 
343             for ( String line = reader.readLine(); line != null; line = reader.readLine() )
344             {
345                 str.append( ' ' );
346                 str.append( line );
347             }
348             return str.toString();
349         }
350     }
351 
352     /**
353      * Verify the correct working of the localtionTemp method
354      *
355      * @throws Exception
356      */
357     public void testLocationTemp()
358         throws Exception
359     {
360 
361         File testPom =
362             new File( getBasedir(),
363                       "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml" );
364         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
365 
366         assertEquals( "locationTemp is not correctly encoding filename",
367                       "export_format_pmd_language_java_name_some_2520name.xml",
368                       mojo.getLocationTemp( "http://nemo.sonarsource.org/sonar/profiles/export?format=pmd&language=java&name=some%2520name" ) );
369 
370     }
371 
372     /**
373      * Verify that suppressMarker works
374      *
375      * @throws Exception
376      */
377     public void testSuppressMarkerConfiguration()
378         throws Exception
379     {
380         File testPom =
381             new File( getBasedir(),
382                       "src/test/resources/unit/default-configuration/pmd-with-suppressMarker-plugin-config.xml" );
383         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
384         mojo.execute();
385 
386         // check if the PMD files were generated
387         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
388         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
389 
390         String str = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" ) );
391 
392         // check that there is no violation reported for "unusedVar2" - as it is suppressed
393         assertFalse( str.contains( "Avoid unused private fields such as 'unusedVar2'." ) );
394     }
395 
396     public void testJspConfiguration()
397             throws Exception
398     {
399         File testPom = new File( getBasedir(),
400                 "src/test/resources/unit/default-configuration/jsp-configuration-plugin-config.xml" );
401         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
402         mojo.execute();
403 
404         // check if the PMD files were generated
405         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
406         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
407 
408         // these are the rulesets, that have been applied...
409         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/jsp-basic.xml" );
410         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
411 
412         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
413         renderer( mojo, generatedFile );
414         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
415 
416         String str = readFile( generatedFile );
417         assertTrue(str.contains("JSP file should use UTF-8 encoding"));
418         assertTrue(str.contains("Using unsanitized JSP expression can lead to Cross Site Scripting (XSS) attacks"));
419         assertTrue(str.contains("Avoid having style information in JSP files."));
420     }
421 
422     public void testPMDProcessingError()
423             throws Exception
424     {
425         File testPom = new File( getBasedir(),
426                 "src/test/resources/unit/processing-error/pmd-processing-error-plugin-config.xml" );
427         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
428         try {
429             mojo.execute();
430             fail("Expected exception");
431         } catch (RuntimeException e) {
432             assertTrue( e.getMessage().endsWith( "Found 1 PMD processing errors" ) );
433         }
434     }
435 
436     public void testPMDExcludeRootsShouldExcludeSubdirectories() throws Exception {
437         File testPom = new File(getBasedir(), "src/test/resources/unit/exclude-roots/pmd-exclude-roots-plugin-config.xml");
438         PmdReport mojo = (PmdReport) lookupMojo ("pmd", testPom);
439         mojo.execute();
440 
441         File generatedFile = new File( getBasedir(), "target/test/unit/exclude-roots/target/pmd.xml" );
442         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
443         String str = readFile( generatedFile );
444 
445         assertTrue( "Seems like all directories are excluded now", str.contains("ForLoopShouldBeWhileLoop") );
446         assertFalse( "Exclusion of an exact source directory not working", str.contains( "OverrideBothEqualsAndHashcode" ) );
447         assertFalse( "Exclusion of basedirectory with subdirectories not working (MPMD-178)", str.contains( "JumbledIncrementer") );
448     }
449 
450     public void testViolationExclusion()
451             throws Exception
452         {
453             File testPom =
454                 new File( getBasedir(),
455                           "src/test/resources/unit/default-configuration/pmd-report-pmd-exclusions-configuration-plugin-config.xml" );
456             final PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
457             mojo.execute();
458 
459             File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
460             assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
461             String str = readFile( generatedFile );
462 
463             assertEquals(0, StringUtils.countMatches(str, "<violation"));
464         }
465 }