View Javadoc
1   package org.apache.maven.plugins.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.ServerSocket;
27  import java.net.URL;
28  import java.nio.charset.StandardCharsets;
29  import java.util.Locale;
30  
31  import org.apache.commons.io.IOUtils;
32  import org.apache.commons.lang3.StringUtils;
33  import org.apache.maven.plugins.pmd.exec.PmdExecutor;
34  import org.apache.maven.reporting.MavenReportException;
35  import org.codehaus.plexus.util.FileUtils;
36  
37  import net.sourceforge.pmd.renderers.Renderer;
38  
39  import com.github.tomakehurst.wiremock.WireMockServer;
40  import com.github.tomakehurst.wiremock.client.WireMock;
41  
42  /**
43   * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
44   * @version $Id$
45   */
46  public class PmdReportTest
47      extends AbstractPmdReportTest
48  {
49  
50      /**
51       * {@inheritDoc}
52       */
53      @Override
54      protected void setUp()
55          throws Exception
56      {
57          super.setUp();
58          Locale.setDefault( Locale.ENGLISH );
59          FileUtils.deleteDirectory( new File( getBasedir(), "target/test/unit" ) );
60      }
61  
62      public void testDefaultConfiguration()
63          throws Exception
64      {
65          FileUtils.copyDirectoryStructure( new File( getBasedir(),
66                                                      "src/test/resources/unit/default-configuration/jxr-files" ),
67                                            new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
68  
69          File testPom =
70              new File( getBasedir(),
71                        "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml" );
72          PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
73          mojo.execute();
74  
75          // check if the PMD files were generated
76          File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
77          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
78  
79          // check if the rulesets, that have been applied, have been copied
80          generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/maven-pmd-plugin-default.xml" );
81          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
82  
83          generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
84          renderer( mojo, generatedFile );
85          assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
86  
87          // check if there's a link to the JXR files
88          String str = readFile( generatedFile );
89  
90          assertTrue( str.contains( "/xref/def/configuration/App.html#L31" ) );
91  
92          assertTrue( str.contains( "/xref/def/configuration/AppSample.html#L45" ) );
93  
94          // check if there's a priority column
95          assertTrue( str.contains( "<th>Priority</th>" ) );
96  
97          // there should be a rule column
98          assertTrue( str.contains( "<th>Rule</th>" ) );
99          // along with a link to the rule
100         assertTrue( str.contains( "pmd_rules_java_bestpractices.html#unusedprivatefield\">UnusedPrivateField</a>" ) );
101 
102         // there should be the section Violations By Priority
103         assertTrue( str.contains( "Violations By Priority</h2>" ) );
104         assertTrue( str.contains( "Priority 3</h3>" ) );
105         assertTrue( str.contains( "Priority 4</h3>" ) );
106         // the file App.java is mentioned 3 times: in prio 3, in prio 4 and in the files section
107         assertEquals( 3, StringUtils.countMatches( str, "def/configuration/App.java" ) );
108 
109         // there must be no warnings (like deprecated rules) in the log output
110         String output = CapturingPrintStream.getOutput();
111         assertFalse( output.contains( "deprecated Rule name" ) );
112         assertFalse( output.contains( "Discontinue using Rule name" ) );
113         assertFalse( output.contains( "is referenced multiple times" ) );
114 
115         // the version should be logged
116         assertTrue ( output.contains( "PMD version: " + AbstractPmdReport.getPmdVersion() ) );
117     }
118 
119     public void testDefaultConfigurationNotRenderRuleViolationPriority()
120             throws Exception
121     {
122         FileUtils.copyDirectoryStructure( new File( getBasedir(),
123                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
124                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
125 
126         File testPom =
127             new File( getBasedir(),
128                       "src/test/resources/unit/default-configuration/pmd-report-not-render-rule-priority-plugin-config.xml" );
129         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
130         mojo.execute();
131 
132         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
133         renderer( mojo, generatedFile );
134         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
135 
136         String str = readFile( generatedFile );
137 
138         // check that there's no priority column
139         assertFalse( str.contains( "<th>Priority</th>" ) );
140     }
141 
142     public void testDefaultConfigurationNoRenderViolationsByPriority()
143             throws Exception
144         {
145             FileUtils.copyDirectoryStructure( new File( getBasedir(),
146                                                         "src/test/resources/unit/default-configuration/jxr-files" ),
147                                               new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
148 
149             File testPom =
150                 new File( getBasedir(),
151                           "src/test/resources/unit/default-configuration/pmd-report-no-render-violations-by-priority.xml" );
152             PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
153             mojo.execute();
154 
155             File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
156             renderer( mojo, generatedFile );
157             assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
158 
159             String str = readFile( generatedFile );
160 
161             // there should be no section Violations By Priority
162             assertFalse( str.contains( "Violations By Priority</h2>" ) );
163             assertFalse( str.contains( "Priority 3</h3>" ) );
164             assertFalse( str.contains( "Priority 4</h3>" ) );
165             // the file App.java is mentioned once: in the files section
166             assertEquals( 1, StringUtils.countMatches( str, "def/configuration/App.java" ) );
167         }
168 
169 
170     public void testDefaultConfigurationWithAnalysisCache()
171             throws Exception
172     {
173         FileUtils.copyDirectoryStructure( new File( getBasedir(),
174                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
175                                           new File( getBasedir(), "target/test/unit/pmd-with-analysis-cache-plugin-config/target/site" ) );
176 
177         File testPom =
178             new File( getBasedir(),
179                       "src/test/resources/unit/default-configuration/pmd-with-analysis-cache-plugin-config.xml" );
180         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
181         mojo.execute();
182 
183         // check if the PMD analysis cache file has been generated
184         File cacheFile = new File( getBasedir(), "target/test/unit/pmd-with-analysis-cache-plugin-config/target/pmd/pmd.cache" );
185         assertTrue( FileUtils.fileExists( cacheFile.getAbsolutePath() ) );
186     }
187 
188     public void testJavascriptConfiguration()
189         throws Exception
190     {
191         File testPom =
192             new File( getBasedir(),
193                       "src/test/resources/unit/default-configuration/javascript-configuration-plugin-config.xml" );
194         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
195         mojo.execute();
196 
197         // check if the PMD files were generated
198         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
199         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
200 
201         // these are the rulesets, that have been applied...
202         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml" );
203         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
204 
205         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/codestyle.xml" );
206         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
207 
208         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/errorprone.xml" );
209         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
210 
211         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
212         renderer( mojo, generatedFile );
213         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
214 
215         String str = readFile( generatedFile );
216         assertTrue( str.contains( "Avoid using global variables" ) );
217     }
218 
219     public void testFileURL()
220         throws Exception
221     {
222         FileUtils.copyDirectoryStructure( new File( getBasedir(),
223                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
224                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
225 
226         File testPom =
227             new File( getBasedir(),
228                       "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml" );
229         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
230 
231         // Additional test case for MPMD-174 (https://issues.apache.org/jira/browse/MPMD-174).
232         int port = determineFreePort();
233         WireMockServer mockServer = new WireMockServer( port );
234         mockServer.start();
235 
236         String sonarRuleset =
237             IOUtils.toString( getClass().getClassLoader().getResourceAsStream( "unit/default-configuration/rulesets/sonar-way-ruleset.xml" ),
238                     StandardCharsets.UTF_8 );
239 
240         String sonarMainPageHtml =
241             IOUtils.toString( getClass().getClassLoader().getResourceAsStream( "unit/default-configuration/rulesets/sonar-main-page.html" ),
242                     StandardCharsets.UTF_8 );
243 
244         final String sonarBaseUrl = "/profiles";
245         final String sonarProfileUrl = sonarBaseUrl + "/export?format=pmd&language=java&name=Sonar%2520way";
246         final String sonarExportRulesetUrl = "http://localhost:" + mockServer.port() + sonarProfileUrl;
247 
248         WireMock.configureFor( "localhost", port );
249         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( sonarBaseUrl ) ).willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
250                                                                                                                                                "text/html" ).withBody( sonarMainPageHtml ) ) );
251 
252         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( sonarProfileUrl ) ).willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
253                                                                                                                                                   "text/xml" ).withBody( sonarRuleset ) ) );
254 
255         URL url = getClass().getClassLoader().getResource( "rulesets/java/basic.xml" );
256         URL url2 = getClass().getClassLoader().getResource( "rulesets/java/unusedcode.xml" );
257         URL url3 = getClass().getClassLoader().getResource( "rulesets/java/imports.xml" );
258         mojo.setRulesets( new String[] { url.toString(), url2.toString(), url3.toString(), sonarExportRulesetUrl } );
259 
260         mojo.execute();
261 
262         // check if the PMD files were generated
263         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
264         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
265 
266         // the resolved and extracted rulesets
267         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/basic.xml" );
268         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
269 
270         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/imports.xml" );
271         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
272 
273         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/unusedcode.xml" );
274         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
275 
276         generatedFile =
277             new File( getBasedir(),
278                       "target/test/unit/default-configuration/target/pmd/rulesets/export_format_pmd_language_java_name_Sonar_2520way.xml" );
279         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
280 
281         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
282         renderer( mojo, generatedFile );
283         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
284 
285         // check if there's a link to the JXR files
286         String str = readFile( generatedFile );
287 
288         assertTrue( str.contains( "/xref/def/configuration/App.html#L31" ) );
289 
290         assertTrue( str.contains( "/xref/def/configuration/AppSample.html#L45" ) );
291 
292         mockServer.stop();
293     }
294 
295     private int determineFreePort()
296     {
297         try (ServerSocket socket = new ServerSocket(0)) {
298             return socket.getLocalPort();
299         } catch (IOException e) {
300             throw new RuntimeException( "Couldn't find a free port.", e );
301         }
302     }
303 
304     /**
305      * With custom rulesets
306      *
307      * @throws Exception
308      */
309     public void testCustomConfiguration()
310         throws Exception
311     {
312         File testPom =
313             new File( getBasedir(),
314                       "src/test/resources/unit/custom-configuration/custom-configuration-plugin-config.xml" );
315 
316         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
317         mojo.execute();
318 
319         // check the generated files
320         File generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/pmd.csv" );
321         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
322 
323         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/pmd/rulesets/custom.xml" );
324         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
325 
326         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" );
327         renderer( mojo, generatedFile );
328         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
329 
330         // check if custom ruleset was applied
331         String str = readFile( generatedFile );
332 
333         // codestyle.xml/ControlStatementBraces:
334         assertTrue( lowerCaseContains( str, "This statement should have braces" ) );
335 
336         // Must be false as codestyle.xml/ControlStatementBraces with checkIfElseStmt=false is used
337         assertFalse( lowerCaseContains( str, "Avoid using if...else statements without curly braces" ) );
338 
339         assertFalse( "unnecessary constructor should not be triggered because of low priority",
340                     lowerCaseContains( str, "Avoid unnecessary constructors - the compiler will generate these for you" ) );
341 
342         // veryLongVariableNameWithViolation is really too long
343         assertTrue( lowerCaseContains( str, "veryLongVariableNameWithViolation" ) );
344         // notSoLongVariableName should not be reported
345         assertFalse( lowerCaseContains( str, "notSoLongVariableName" ) );
346     }
347 
348     /**
349      * Verify skip parameter
350      *
351      * @throws Exception
352      */
353     public void testSkipConfiguration()
354         throws Exception
355     {
356         File testPom = new File( getBasedir(), "src/test/resources/unit/custom-configuration/skip-plugin-config.xml" );
357         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
358         mojo.execute();
359 
360         // verify the generated files do not exist because PMD was skipped
361         File generatedFile = new File( getBasedir(), "target/test/unit/skip-configuration/target/pmd.csv" );
362         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
363 
364         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/custom.xml" );
365         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
366 
367         generatedFile = new File( getBasedir(), "target/test/unit/custom-configuration/target/site/pmd.html" );
368         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
369 
370         // the fact, the PMD execution has been skipped, should be logged
371         String output = CapturingPrintStream.getOutput();
372         assertTrue ( output.contains( "Skipping PMD execution" ) );
373     }
374 
375     public void testSkipEmptyReportConfiguration()
376         throws Exception
377     {
378         File testPom =
379             new File( getBasedir(), "src/test/resources/unit/empty-report/skip-empty-report-plugin-config.xml" );
380         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
381         mojo.execute();
382 
383         // verify the generated files do not exist because PMD was skipped
384         File generatedFile = new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" );
385         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
386     }
387 
388     public void testEmptyReportConfiguration()
389         throws Exception
390     {
391         File testPom = new File( getBasedir(), "src/test/resources/unit/empty-report/empty-report-plugin-config.xml" );
392         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
393         mojo.execute();
394 
395         // verify the generated files do exist, even if there are no violations
396         File generatedFile = new File( getBasedir(), "target/test/unit/empty-report/target/site/pmd.html" );
397         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
398         String str = readFile( generatedFile );
399         assertFalse( lowerCaseContains( str, "Hello.java" ) );
400         assertEquals( 1, StringUtils.countMatches( str, "PMD found no problems in your source code." ) );
401         // no sections files or violations by priority
402         assertFalse( str.contains( "Files</h2>" ) );
403         assertFalse( str.contains( "Violations By Priority</h2>" ) );
404     }
405 
406     public void testInvalidFormat()
407         throws Exception
408     {
409         try
410         {
411             File testPom =
412                 new File( getBasedir(), "src/test/resources/unit/invalid-format/invalid-format-plugin-config.xml" );
413             PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
414             setVariableValueToObject( mojo, "compileSourceRoots", mojo.project.getCompileSourceRoots() );
415             mojo.executeReport( Locale.ENGLISH );
416 
417             fail( "Must throw MavenReportException." );
418         }
419         catch ( Exception e )
420         {
421             assertTrue( true );
422         }
423     }
424 
425     public void testInvalidTargetJdk()
426         throws Exception
427     {
428         try
429         {
430             File testPom =
431                 new File( getBasedir(), "src/test/resources/unit/invalid-format/invalid-target-jdk-plugin-config.xml" );
432             PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
433             mojo.execute();
434 
435             fail( "Must throw MavenReportException." );
436         }
437         catch ( Exception e )
438         {
439             assertTrue( true );
440         }
441     }
442 
443     /**
444      * verify the pmd.xml file is included in the site when requested.
445      * @throws Exception
446      */
447     public void testIncludeXmlInSite()
448             throws Exception
449     {
450         File testPom = new File( getBasedir(), "src/test/resources/unit/default-configuration/pmd-report-include-xml-in-site-plugin-config.xml" );
451         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
452         mojo.execute();
453 
454         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
455         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
456         // verify the pmd file is included in site
457         File generatedXmlFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.xml" );
458         assertTrue( FileUtils.fileExists( generatedXmlFile.getAbsolutePath() ) );
459 
460         String pmdXmlTarget = readFile( new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" ) );
461         assertTrue( pmdXmlTarget.contains( "</pmd>" ) );
462 
463         // check that pmd.xml file has the closing element
464         String pmdXml = readFile( generatedXmlFile );
465         assertTrue( pmdXml.contains( "</pmd>" ) );
466     }
467 
468     /**
469      * Read the contents of the specified file object into a string
470      *
471      * @param file the file to be read
472      * @return a String object that contains the contents of the file
473      * @throws java.io.IOException
474      */
475     private String readFile( File file )
476         throws IOException
477     {
478         try ( BufferedReader reader = new BufferedReader( new FileReader( file ) ) )
479         {
480             final StringBuilder str = new StringBuilder( (int) file.length() );
481 
482             for ( String line = reader.readLine(); line != null; line = reader.readLine() )
483             {
484                 str.append( ' ' );
485                 str.append( line );
486                 str.append( '\n' );
487             }
488             return str.toString();
489         }
490     }
491 
492     /**
493      * Verify the correct working of the locationTemp method
494      *
495      * @throws Exception
496      */
497     public void testLocationTemp()
498         throws Exception
499     {
500 
501         File testPom =
502             new File( getBasedir(),
503                       "src/test/resources/unit/default-configuration/default-configuration-plugin-config.xml" );
504         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
505 
506         assertEquals( "locationTemp is not correctly encoding filename",
507                       "export_format_pmd_language_java_name_some_2520name.xml",
508                       mojo.getLocationTemp( "http://nemo.sonarsource.org/sonar/profiles/export?format=pmd&language=java&name=some%2520name" ) );
509 
510     }
511 
512     /**
513      * Verify that suppressMarker works
514      *
515      * @throws Exception
516      */
517     public void testSuppressMarkerConfiguration()
518         throws Exception
519     {
520         File testPom =
521             new File( getBasedir(),
522                       "src/test/resources/unit/default-configuration/pmd-with-suppressMarker-plugin-config.xml" );
523         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
524         mojo.execute();
525 
526         // check if the PMD files were generated
527         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
528         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
529 
530         String str = readFile( generatedFile );
531 
532         // check that there is no violation reported for "unusedVar2" - as it is suppressed
533         assertFalse( str.contains( "Avoid unused private fields such as 'unusedVar2'." ) );
534     }
535 
536     public void testJspConfiguration()
537             throws Exception
538     {
539         File testPom = new File( getBasedir(),
540                 "src/test/resources/unit/default-configuration/jsp-configuration-plugin-config.xml" );
541         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
542         mojo.execute();
543 
544         // check if the PMD files were generated
545         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
546         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
547 
548         // these are the rulesets, that have been applied...
549         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml" );
550         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
551 
552         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/codestyle.xml" );
553         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
554 
555         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/design.xml" );
556         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
557 
558         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/errorprone.xml" );
559         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
560 
561         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/security.xml" );
562         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
563 
564         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
565         renderer( mojo, generatedFile );
566         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
567 
568         String str = readFile( generatedFile );
569         assertTrue(str.contains("JSP file should use UTF-8 encoding"));
570         assertTrue(str.contains("Using unsanitized JSP expression can lead to Cross Site Scripting (XSS) attacks"));
571         assertTrue(str.contains("Avoid having style information in JSP files."));
572     }
573 
574     public void testPMDProcessingError()
575             throws Exception
576     {
577         File testPom = new File( getBasedir(),
578                 "src/test/resources/unit/processing-error/pmd-processing-error-plugin-config.xml" );
579         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
580         try {
581             mojo.execute();
582             fail("Expected exception");
583         } catch (RuntimeException e) {
584             assertTrue( e.getMessage().endsWith( "Found 1 PMD processing errors" ) );
585         }
586     }
587 
588     public void testPMDProcessingErrorWithDetailsSkipped()
589             throws Exception
590     {
591         File testPom = new File( getBasedir(),
592                 "src/test/resources/unit/processing-error/pmd-processing-error-skip-plugin-config.xml" );
593         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
594 
595         mojo.execute();
596         String output = CapturingPrintStream.getOutput();
597         assertTrue ( output.contains( "There are 1 PMD processing errors:" ) );
598 
599         File generatedFile = new File( getBasedir(), "target/test/unit/parse-error/target/pmd.xml" );
600         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
601         String str = readFile( generatedFile );
602         assertTrue( str.contains( "Error while parsing" ) );
603         // The parse exception must be in the XML report
604         assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
605 
606         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
607         renderer( mojo, generatedFile );
608         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
609         str = readFile( generatedFile );
610         // The parse exception must also be in the HTML report
611         assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
612     }
613 
614     public void testPMDProcessingErrorWithDetailsNoReport()
615             throws Exception
616     {
617         File testPom = new File( getBasedir(),
618                 "src/test/resources/unit/processing-error/pmd-processing-error-no-report-plugin-config.xml" );
619         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
620 
621         mojo.execute();
622         String output = CapturingPrintStream.getOutput();
623         assertTrue ( output.contains( "There are 1 PMD processing errors:" ) );
624 
625         File generatedFile = new File( getBasedir(), "target/test/unit/parse-error/target/pmd.xml" );
626         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
627         String str = readFile( generatedFile );
628         assertTrue( str.contains( "Error while parsing" ) );
629         // The parse exception must be in the XML report
630         assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
631 
632         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
633         renderer( mojo, generatedFile );
634         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
635         str = readFile( generatedFile );
636         // The parse exception must NOT be in the HTML report, since reportProcessingErrors is false
637         assertFalse( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
638     }
639 
640     public void testPMDExcludeRootsShouldExcludeSubdirectories() throws Exception {
641         File testPom = new File(getBasedir(), "src/test/resources/unit/exclude-roots/pmd-exclude-roots-plugin-config.xml");
642         PmdReport mojo = (PmdReport) lookupMojo ("pmd", testPom);
643         mojo.execute();
644 
645         File generatedFile = new File( getBasedir(), "target/test/unit/exclude-roots/target/pmd.xml" );
646         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
647         String str = readFile( generatedFile );
648 
649         assertTrue( "Seems like all directories are excluded now", str.contains("ForLoopShouldBeWhileLoop") );
650         assertFalse( "Exclusion of an exact source directory not working", str.contains( "OverrideBothEqualsAndHashcode" ) );
651         assertFalse( "Exclusion of basedirectory with subdirectories not working (MPMD-178)", str.contains( "JumbledIncrementer") );
652     }
653 
654     public void testViolationExclusion()
655             throws Exception
656         {
657             File testPom =
658                 new File( getBasedir(),
659                           "src/test/resources/unit/default-configuration/pmd-report-pmd-exclusions-configuration-plugin-config.xml" );
660             final PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
661             mojo.execute();
662 
663             File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
664             assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
665             String str = readFile( generatedFile );
666 
667             assertEquals(0, StringUtils.countMatches(str, "<violation"));
668         }
669 
670     public void testCustomRenderer() throws MavenReportException
671     {
672         final Renderer renderer = PmdExecutor.createRenderer( "net.sourceforge.pmd.renderers.TextRenderer", "UTF-8" );
673         assertNotNull(renderer);
674     }
675 
676     public void testCodeClimateRenderer() throws MavenReportException
677     {
678         final Renderer renderer = PmdExecutor.createRenderer( "net.sourceforge.pmd.renderers.CodeClimateRenderer", "UTF-8" );
679         assertNotNull(renderer);
680     }
681 
682     public void testPmdReportCustomRulesNoExternalInfoUrl()
683             throws Exception
684     {
685         FileUtils.copyDirectoryStructure( new File( getBasedir(),
686                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
687                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
688 
689         File testPom =
690             new File( getBasedir(),
691                       "src/test/resources/unit/default-configuration/pmd-report-custom-rules.xml" );
692         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
693         mojo.execute();
694 
695         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
696         renderer( mojo, generatedFile );
697         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
698 
699         String str = readFile( generatedFile );
700 
701         // custom rule without link
702         assertEquals( 2, StringUtils.countMatches( str, "<td>CustomRule</td>" ) );
703         // standard rule with link
704         assertEquals( 4, StringUtils.countMatches( str, "\">UnusedPrivateField</a></td>" ) );
705     }
706 
707     public void testPmdReportResolveRulesets()
708             throws Exception
709     {
710         int port = determineFreePort();
711         WireMockServer mockServer = new WireMockServer( port );
712         mockServer.start();
713 
714         String sonarRuleset =
715             IOUtils.toString( getClass().getClassLoader().getResourceAsStream( "unit/default-configuration/rulesets/sonar-way-ruleset.xml" ),
716                     StandardCharsets.UTF_8 );
717 
718         final String sonarProfileUrl = "/profiles/export?format=pmd&language=java&name=Sonar%2520way";
719         final String sonarExportRulesetUrl = "http://localhost:" + mockServer.port() + sonarProfileUrl;
720         final String myRulesetBaseUrl = "/config/my-ruleset.xml";
721         final String myRulesetUrl = "http://localhost:" + mockServer.port() + myRulesetBaseUrl;
722 
723         WireMock.configureFor( "localhost", port );
724         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( sonarProfileUrl ) )
725                 .willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
726                                                                                 "text/xml" ).withBody( sonarRuleset ) ) );
727         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( myRulesetBaseUrl ) )
728                 .willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
729                                                                                 "text/xml" ).withBody( sonarRuleset ) ) );
730 
731         FileUtils.copyDirectoryStructure( new File( getBasedir(),
732                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
733                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
734 
735         File testPom =
736             new File( getBasedir(),
737                       "src/test/resources/unit/default-configuration/pmd-report-resolve-rulesets.xml" );
738         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
739         mojo.rulesets[3] = sonarExportRulesetUrl;
740         mojo.rulesets[4] = myRulesetUrl;
741         mojo.execute();
742 
743         // these are the rulesets, that have been copied to target/pmd/rulesets
744         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/custom-rules.xml" );
745         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
746 
747         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml" );
748         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
749 
750         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/java-design.xml" );
751         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
752 
753         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/export_format_pmd_language_java_name_Sonar_2520way.xml" );
754         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
755 
756         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/my-ruleset.xml" );
757         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
758 
759         mockServer.stop();
760     }
761 
762 }