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'.\n </violation>" ) );
534         // but it appears as suppressed
535         assertTrue( str.contains( "suppressiontype=\"nopmd\" msg=\"Avoid unused private fields such as 'unusedVar2'.\"" ));
536 
537         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
538         renderer( mojo, generatedFile );
539         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
540 
541         // check if there's a link to the JXR files
542         str = readFile( generatedFile );
543 
544         assertTrue( str.contains( "/xref/def/configuration/AppSample.html#L27" ) );
545         // suppressed violation
546         assertTrue( str.contains( "Avoid unused private fields such as 'unusedVar2'." ) );
547     }
548 
549     public void testSuppressMarkerConfigurationWithoutRendering()
550         throws Exception
551     {
552         File testPom =
553             new File( getBasedir(),
554                       "src/test/resources/unit/default-configuration/pmd-with-suppressMarker-no-render-plugin-config.xml" );
555         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
556         mojo.execute();
557 
558         // check if the PMD files were generated
559         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
560         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
561 
562         String str = readFile( generatedFile );
563 
564         // check that there is no violation reported for "unusedVar2" - as it is suppressed
565         assertFalse( str.contains( "Avoid unused private fields such as 'unusedVar2'.\n </violation>" ) );
566         // but it appears as suppressed
567         assertTrue( str.contains( "suppressiontype=\"nopmd\" msg=\"Avoid unused private fields such as 'unusedVar2'.\"" ));
568 
569         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
570         renderer( mojo, generatedFile );
571         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
572 
573         // check if there's a link to the JXR files
574         str = readFile( generatedFile );
575 
576         assertTrue( str.contains( "/xref/def/configuration/AppSample.html#L27" ) );
577         // suppressed violations are not rendered
578         assertFalse( str.contains( "Avoid unused private fields such as 'unusedVar2'." ) );
579     }
580 
581     public void testJspConfiguration()
582             throws Exception
583     {
584         File testPom = new File( getBasedir(),
585                 "src/test/resources/unit/default-configuration/jsp-configuration-plugin-config.xml" );
586         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
587         mojo.execute();
588 
589         // check if the PMD files were generated
590         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
591         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
592 
593         // these are the rulesets, that have been applied...
594         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml" );
595         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
596 
597         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/codestyle.xml" );
598         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
599 
600         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/design.xml" );
601         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
602 
603         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/errorprone.xml" );
604         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
605 
606         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/security.xml" );
607         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
608 
609         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
610         renderer( mojo, generatedFile );
611         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
612 
613         String str = readFile( generatedFile );
614         assertTrue(str.contains("JSP file should use UTF-8 encoding"));
615         assertTrue(str.contains("Using unsanitized JSP expression can lead to Cross Site Scripting (XSS) attacks"));
616         assertTrue(str.contains("Avoid having style information in JSP files."));
617     }
618 
619     public void testPMDProcessingError()
620             throws Exception
621     {
622         File testPom = new File( getBasedir(),
623                 "src/test/resources/unit/processing-error/pmd-processing-error-plugin-config.xml" );
624         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
625         try {
626             mojo.execute();
627             fail("Expected exception");
628         } catch (RuntimeException e) {
629             assertTrue( e.getMessage().endsWith( "Found 1 PMD processing errors" ) );
630         }
631     }
632 
633     public void testPMDProcessingErrorWithDetailsSkipped()
634             throws Exception
635     {
636         File testPom = new File( getBasedir(),
637                 "src/test/resources/unit/processing-error/pmd-processing-error-skip-plugin-config.xml" );
638         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
639 
640         mojo.execute();
641         String output = CapturingPrintStream.getOutput();
642         assertTrue ( output.contains( "There are 1 PMD processing errors:" ) );
643 
644         File generatedFile = new File( getBasedir(), "target/test/unit/parse-error/target/pmd.xml" );
645         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
646         String str = readFile( generatedFile );
647         assertTrue( str.contains( "Error while parsing" ) );
648         // The parse exception must be in the XML report
649         assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
650 
651         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
652         renderer( mojo, generatedFile );
653         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
654         str = readFile( generatedFile );
655         // The parse exception must also be in the HTML report
656         assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
657     }
658 
659     public void testPMDProcessingErrorWithDetailsNoReport()
660             throws Exception
661     {
662         File testPom = new File( getBasedir(),
663                 "src/test/resources/unit/processing-error/pmd-processing-error-no-report-plugin-config.xml" );
664         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
665 
666         mojo.execute();
667         String output = CapturingPrintStream.getOutput();
668         assertTrue ( output.contains( "There are 1 PMD processing errors:" ) );
669 
670         File generatedFile = new File( getBasedir(), "target/test/unit/parse-error/target/pmd.xml" );
671         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
672         String str = readFile( generatedFile );
673         assertTrue( str.contains( "Error while parsing" ) );
674         // The parse exception must be in the XML report
675         assertTrue( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
676 
677         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
678         renderer( mojo, generatedFile );
679         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
680         str = readFile( generatedFile );
681         // The parse exception must NOT be in the HTML report, since reportProcessingErrors is false
682         assertFalse( str.contains( "ParseException: Encountered \"\" at line 23, column 5." ) );
683     }
684 
685     public void testPMDExcludeRootsShouldExcludeSubdirectories() throws Exception {
686         File testPom = new File(getBasedir(), "src/test/resources/unit/exclude-roots/pmd-exclude-roots-plugin-config.xml");
687         PmdReport mojo = (PmdReport) lookupMojo ("pmd", testPom);
688         mojo.execute();
689 
690         File generatedFile = new File( getBasedir(), "target/test/unit/exclude-roots/target/pmd.xml" );
691         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
692         String str = readFile( generatedFile );
693 
694         assertTrue( "Seems like all directories are excluded now", str.contains("ForLoopShouldBeWhileLoop") );
695         assertFalse( "Exclusion of an exact source directory not working", str.contains( "OverrideBothEqualsAndHashcode" ) );
696         assertFalse( "Exclusion of basedirectory with subdirectories not working (MPMD-178)", str.contains( "JumbledIncrementer") );
697     }
698 
699     public void testViolationExclusion()
700             throws Exception
701         {
702             File testPom =
703                 new File( getBasedir(),
704                           "src/test/resources/unit/default-configuration/pmd-report-pmd-exclusions-configuration-plugin-config.xml" );
705             final PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
706             mojo.execute();
707 
708             File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd.xml" );
709             assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
710             String str = readFile( generatedFile );
711 
712             assertEquals(0, StringUtils.countMatches(str, "<violation"));
713         }
714 
715     public void testCustomRenderer() throws MavenReportException
716     {
717         final Renderer renderer = PmdExecutor.createRenderer( "net.sourceforge.pmd.renderers.TextRenderer", "UTF-8" );
718         assertNotNull(renderer);
719     }
720 
721     public void testCodeClimateRenderer() throws MavenReportException
722     {
723         final Renderer renderer = PmdExecutor.createRenderer( "net.sourceforge.pmd.renderers.CodeClimateRenderer", "UTF-8" );
724         assertNotNull(renderer);
725     }
726 
727     public void testPmdReportCustomRulesNoExternalInfoUrl()
728             throws Exception
729     {
730         FileUtils.copyDirectoryStructure( new File( getBasedir(),
731                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
732                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
733 
734         File testPom =
735             new File( getBasedir(),
736                       "src/test/resources/unit/default-configuration/pmd-report-custom-rules.xml" );
737         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
738         mojo.execute();
739 
740         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
741         renderer( mojo, generatedFile );
742         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
743 
744         String str = readFile( generatedFile );
745 
746         // custom rule without link
747         assertEquals( 2, StringUtils.countMatches( str, "<td>CustomRule</td>" ) );
748         // standard rule with link
749         assertEquals( 4, StringUtils.countMatches( str, "\">UnusedPrivateField</a></td>" ) );
750     }
751 
752     public void testPmdReportResolveRulesets()
753             throws Exception
754     {
755         int port = determineFreePort();
756         WireMockServer mockServer = new WireMockServer( port );
757         mockServer.start();
758 
759         String sonarRuleset =
760             IOUtils.toString( getClass().getClassLoader().getResourceAsStream( "unit/default-configuration/rulesets/sonar-way-ruleset.xml" ),
761                     StandardCharsets.UTF_8 );
762 
763         final String sonarProfileUrl = "/profiles/export?format=pmd&language=java&name=Sonar%2520way";
764         final String sonarExportRulesetUrl = "http://localhost:" + mockServer.port() + sonarProfileUrl;
765         final String myRulesetBaseUrl = "/config/my-ruleset.xml";
766         final String myRulesetUrl = "http://localhost:" + mockServer.port() + myRulesetBaseUrl;
767         final String notAInternalRulesetBaseUrl = "/projects/OURPROJECT/repos/ourproject-pmd/raw/InProgressRuleset.xml?at=refs%2Fheads%2Fmaster";
768         final String notAInternalRulesetUrl = "http://localhost:" + mockServer.port() + notAInternalRulesetBaseUrl;
769 
770         WireMock.configureFor( "localhost", port );
771         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( sonarProfileUrl ) )
772                 .willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
773                                                                                 "text/xml" ).withBody( sonarRuleset ) ) );
774         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( myRulesetBaseUrl ) )
775                 .willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
776                                                                                 "text/xml" ).withBody( sonarRuleset ) ) );
777         WireMock.stubFor( WireMock.get( WireMock.urlEqualTo( notAInternalRulesetBaseUrl ) )
778                 .willReturn( WireMock.aResponse().withStatus( 200 ).withHeader( "Content-Type",
779                                                                                 "text/xml" ).withBody( sonarRuleset ) ) );
780 
781         FileUtils.copyDirectoryStructure( new File( getBasedir(),
782                                                     "src/test/resources/unit/default-configuration/jxr-files" ),
783                                           new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
784 
785         File testPom =
786             new File( getBasedir(),
787                       "src/test/resources/unit/default-configuration/pmd-report-resolve-rulesets.xml" );
788         PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
789         mojo.rulesets[3] = sonarExportRulesetUrl;
790         mojo.rulesets[4] = myRulesetUrl;
791         mojo.rulesets[5] = notAInternalRulesetUrl;
792         mojo.execute();
793 
794         // these are the rulesets, that have been copied to target/pmd/rulesets
795         File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/custom-rules.xml" );
796         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
797 
798         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/bestpractices.xml" );
799         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
800 
801         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/java-design.xml" );
802         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
803 
804         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/export_format_pmd_language_java_name_Sonar_2520way.xml" );
805         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
806 
807         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/my-ruleset.xml" );
808         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
809 
810         generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/pmd/rulesets/InProgressRuleset.xml_at_refs_2Fheads_2Fmaster.xml" );
811         assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
812 
813         mockServer.stop();
814     }
815 
816 }