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