View Javadoc

1   package org.apache.maven.plugin.ear.it;
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 junit.framework.TestCase;
23  import org.apache.maven.it.VerificationException;
24  import org.apache.maven.it.Verifier;
25  import org.apache.maven.it.util.ResourceExtractor;
26  import org.apache.maven.plugin.ear.util.ResourceEntityResolver;
27  import org.custommonkey.xmlunit.Diff;
28  import org.custommonkey.xmlunit.XMLAssert;
29  import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
30  import org.xml.sax.helpers.DefaultHandler;
31  
32  import javax.xml.parsers.DocumentBuilder;
33  import javax.xml.parsers.DocumentBuilderFactory;
34  import java.io.File;
35  import java.io.FilenameFilter;
36  import java.io.IOException;
37  import java.util.ArrayList;
38  import java.util.Arrays;
39  import java.util.HashMap;
40  import java.util.List;
41  import java.util.Map;
42  import java.util.Properties;
43  
44  /**
45   * Base class for ear test cases.
46   *
47   * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
48   * @version $Id: AbstractEarPluginIT.java 1360989 2012-07-12 22:37:40Z olamy $
49   */
50  public abstract class AbstractEarPluginIT
51      extends TestCase
52  {
53  
54      protected final String FINAL_NAME_PREFIX = "maven-ear-plugin-test-";
55  
56      protected final String FINAL_NAME_SUFFIX = "-99.0";
57  
58      /**
59       * The base directory.
60       */
61      private File basedir;
62  
63      /**
64       * Test repository directory.
65       */
66      protected File localRepositoryDir = new File( getBasedir().getAbsolutePath(), "target/test-classes/m2repo" );
67  
68      protected File settingsFile = new File( getBasedir().getAbsolutePath(), "target/test-classes/settings.xml" );
69  
70  
71      /**
72       * Execute the EAR plugin for the specified project.
73       *
74       * @param projectName the name of the project
75       * @param properties  extra properties to be used by the embedder
76       * @return the base directory of the project
77       * @throws Exception if an error occurred
78       */
79      @SuppressWarnings( "unchecked" )
80      protected File executeMojo( final String projectName, final Properties properties, boolean expectNoError )
81          throws Exception
82      {
83          System.out.println( "  Building: " + projectName );
84  
85          File testDir = getTestDir( projectName );
86          Verifier verifier = new Verifier( testDir.getAbsolutePath() );
87          // Let's add alternate settings.xml setting so that the latest dependencies are used
88          String localRepo = System.getProperty( "localRepositoryPath" );
89          verifier.setLocalRepo( localRepo );
90  
91          verifier.getCliOptions().add( "-s \"" + settingsFile.getAbsolutePath() + "\"" );//
92          verifier.getCliOptions().add( "-X" );
93          verifier.localRepo = localRepo;
94  
95          // On linux and macOSX, an exception is thrown if a build failure occurs underneath
96          try
97          {
98              verifier.executeGoal( "package" );
99          }
100         catch ( VerificationException e )
101         {
102             //@TODO needs to be handled nicely in the verifier
103             if ( expectNoError || e.getMessage().indexOf( "Exit code was non-zero" ) == -1 )
104             {
105                 throw e;
106             }
107         }
108 
109         // If no error is expected make sure that error logs are free
110         if ( expectNoError )
111         {
112             verifier.verifyErrorFreeLog();
113         }
114         verifier.resetStreams();
115         return testDir;
116     }
117 
118     /**
119      * Execute the EAR plugin for the specified project.
120      *
121      * @param projectName the name of the project
122      * @param properties  extra properties to be used by the embedder
123      * @return the base directory of the project
124      * @throws Exception if an error occurred
125      */
126     protected File executeMojo( final String projectName, final Properties properties )
127         throws Exception
128     {
129         return executeMojo( projectName, properties, true );
130     }
131 
132 
133     /**
134      * Executes the specified projects and asserts the given artifacts.
135      *
136      * @param projectName               the project to test
137      * @param expectedArtifacts         the list of artifacts to be found in the EAR archive
138      * @param artifactsDirectory        whether the artifact is an exploded artifactsDirectory or not
139      * @param testDeploymentDescriptors whether we should test deployment descriptors
140      * @return the base directory of the project
141      * @throws Exception
142      */
143     protected File doTestProject( final String projectName, final String[] expectedArtifacts,
144                                   final boolean[] artifactsDirectory, boolean testDeploymentDescriptors )
145         throws Exception
146     {
147         final File baseDir = executeMojo( projectName, new Properties() );
148         assertEarArchive( baseDir, projectName );
149         assertEarDirectory( baseDir, projectName );
150 
151         assertArchiveContent( baseDir, projectName, expectedArtifacts, artifactsDirectory );
152 
153         if ( testDeploymentDescriptors )
154         {
155             assertDeploymentDescriptors( baseDir, projectName );
156         }
157 
158         return baseDir;
159 
160     }
161 
162     /**
163      * Executes the specified projects and asserts the given artifacts. Assert the
164      * deployment descriptors are valid
165      *
166      * @param projectName        the project to test
167      * @param expectedArtifacts  the list of artifacts to be found in the EAR archive
168      * @param artifactsDirectory whether the artifact is an exploded artifactsDirectory or not
169      * @return the base directory of the project
170      * @throws Exception
171      */
172     protected File doTestProject( final String projectName, final String[] expectedArtifacts,
173                                   final boolean[] artifactsDirectory )
174         throws Exception
175     {
176         return doTestProject( projectName, expectedArtifacts, artifactsDirectory, true );
177 
178     }
179 
180     /**
181      * Executes the specified projects and asserts the given artifacts as
182      * artifacts (non directory)
183      *
184      * @param projectName               the project to test
185      * @param expectedArtifacts         the list of artifacts to be found in the EAR archive
186      * @param testDeploymentDescriptors whether we should test deployment descriptors
187      * @return the base directory of the project
188      * @throws Exception
189      */
190     protected File doTestProject( final String projectName, final String[] expectedArtifacts,
191                                   boolean testDeploymentDescriptors )
192         throws Exception
193     {
194         return doTestProject( projectName, expectedArtifacts, new boolean[expectedArtifacts.length] );
195     }
196 
197     /**
198      * Executes the specified projects and asserts the given artifacts as
199      * artifacts (non directory). Assert the deployment descriptors are valid
200      *
201      * @param projectName       the project to test
202      * @param expectedArtifacts the list of artifacts to be found in the EAR archive
203      * @return the base directory of the project
204      * @throws Exception
205      */
206     protected File doTestProject( final String projectName, final String[] expectedArtifacts )
207         throws Exception
208     {
209         return doTestProject( projectName, expectedArtifacts, true );
210     }
211 
212     protected void assertEarArchive( final File baseDir, final String projectName )
213     {
214         assertTrue( "EAR archive does not exist", getEarArchive( baseDir, projectName ).exists() );
215     }
216 
217     protected void assertEarDirectory( final File baseDir, final String projectName )
218     {
219         assertTrue( "EAR archive directory does not exist", getEarDirectory( baseDir, projectName ).exists() );
220     }
221 
222     protected File getTargetDirectory( final File basedir )
223     {
224         return new File( basedir, "target" );
225     }
226 
227     protected File getEarArchive( final File baseDir, final String projectName )
228     {
229         return new File( getTargetDirectory( baseDir ), buildFinalName( projectName ) + ".ear" );
230     }
231 
232     protected File getEarDirectory( final File baseDir, final String projectName )
233     {
234         return new File( getTargetDirectory( baseDir ), buildFinalName( projectName ) );
235     }
236 
237     protected String buildFinalName( final String projectName )
238     {
239         return FINAL_NAME_PREFIX + projectName + FINAL_NAME_SUFFIX;
240     }
241 
242     protected void assertArchiveContent( final File baseDir, final String projectName, final String[] artifactNames,
243                                          final boolean[] artifactsDirectory )
244     {
245         // sanity check
246         assertEquals( "Wrong parameter, artifacts mismatch directory flags", artifactNames.length,
247                       artifactsDirectory.length );
248 
249         File dir = getEarDirectory( baseDir, projectName );
250 
251         // Let's build the expected directories sort list
252         final List<File> expectedDirectories = new ArrayList<File>();
253         for ( int i = 0; i < artifactsDirectory.length; i++ )
254         {
255             if ( artifactsDirectory[i] )
256             {
257                 expectedDirectories.add( new File( dir, artifactNames[i] ) );
258             }
259         }
260 
261         final List<File> actualFiles = buildArchiveContentFiles( dir, expectedDirectories );
262         assertEquals( "Artifacts mismatch " + actualFiles, artifactNames.length, actualFiles.size() );
263         for ( int i = 0; i < artifactNames.length; i++ )
264         {
265             String artifactName = artifactNames[i];
266             final boolean isDirectory = artifactsDirectory[i];
267             File expectedFile = new File( dir, artifactName );
268 
269             assertEquals( "Artifact[" + artifactName + "] not in the right form (exploded/archive", isDirectory,
270                           expectedFile.isDirectory() );
271             assertTrue( "Artifact[" + artifactName + "] not found in ear archive",
272                         actualFiles.contains( expectedFile ) );
273 
274         }
275     }
276 
277     protected List<File> buildArchiveContentFiles( final File baseDir, final List<File> expectedDirectories )
278     {
279         final List<File> result = new ArrayList<File>();
280         addFiles( baseDir, result, expectedDirectories );
281 
282         return result;
283     }
284 
285     private void addFiles( final File directory, final List<File> files, final List<File> expectedDirectories )
286     {
287         File[] result = directory.listFiles( new FilenameFilter()
288         {
289             public boolean accept( File dir, String name )
290             {
291                 return !name.equals( "META-INF" );
292             }
293 
294         } );
295 
296         /*
297            Kinda complex. If we found a file, we always add it to the list
298            of files. If a directory is within the expectedDirectories short
299            list we add it but we don't add it's content. Otherwise, we don't
300            add the directory *BUT* we browse it's content
301          */
302         for ( int i = 0; i < result.length; i++ )
303         {
304             File file = result[i];
305             if ( file.isFile() )
306             {
307                 files.add( file );
308             }
309             else if ( expectedDirectories.contains( file ) )
310             {
311                 files.add( file );
312             }
313             else
314             {
315                 addFiles( file, files, expectedDirectories );
316             }
317         }
318     }
319 
320     protected File getBasedir()
321     {
322         if ( basedir != null )
323         {
324             return basedir;
325         }
326 
327         final String basedirString = System.getProperty( "basedir" );
328         if ( basedirString == null )
329         {
330             basedir = new File( "" );
331         }
332         else
333         {
334             basedir = new File( basedirString );
335         }
336         return basedir;
337     }
338 
339     protected File getTestDir( String projectName )
340         throws IOException
341     {
342         return ResourceExtractor.simpleExtractResources( getClass(), "/projects/" + projectName );
343     }
344 
345     // Generated application.xml stuff
346 
347     /**
348      * Asserts that the deployment descriptors have been generated successfully.
349      * <p/>
350      * This test assumes that deployment descriptors are located in the
351      * <tt>expected-META-INF</tt> directory of the project. Note that the
352      * <tt>MANIFEST.mf</tt> file is ignored and is not tested.
353      *
354      * @param baseDir     the directory of the tested project
355      * @param projectName the name of the project
356      */
357     protected void assertDeploymentDescriptors( final File baseDir, final String projectName )
358         throws IOException
359     {
360         final File earDirectory = getEarDirectory( baseDir, projectName );
361         final File[] actualDeploymentDescriptors = getDeploymentDescriptors( new File( earDirectory, "META-INF" ) );
362         final File[] expectedDeploymentDescriptors =
363             getDeploymentDescriptors( new File( baseDir, "expected-META-INF" ) );
364 
365         if ( expectedDeploymentDescriptors == null )
366         {
367             assertNull( "No deployment descriptor was expected", actualDeploymentDescriptors );
368         }
369         else
370         {
371             assertNotNull( "Missing deployment descriptor", actualDeploymentDescriptors );
372 
373             // Make sure we have the same number of files
374             assertEquals( "Number of Deployment descriptor(s) mismatch", expectedDeploymentDescriptors.length,
375                           actualDeploymentDescriptors.length );
376 
377             // Sort the files so that we have the same behavior here
378             Arrays.sort( expectedDeploymentDescriptors );
379             Arrays.sort( actualDeploymentDescriptors );
380 
381             for ( int i = 0; i < expectedDeploymentDescriptors.length; i++ )
382             {
383                 File expectedDeploymentDescriptor = expectedDeploymentDescriptors[i];
384                 File actualDeploymentDescriptor = actualDeploymentDescriptors[i];
385 
386                 assertEquals( "File name mismatch", expectedDeploymentDescriptor.getName(),
387                               actualDeploymentDescriptor.getName() );
388 
389                 try
390                 {
391                     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
392                     dbf.setValidating( true );
393                     DocumentBuilder docBuilder = dbf.newDocumentBuilder();
394                     docBuilder.setEntityResolver( new ResourceEntityResolver() );
395                     docBuilder.setErrorHandler( new DefaultHandler() );
396 
397                     // Make sure that it matches even if the elements are not in
398                     // the exact same order
399                     final Diff myDiff = new Diff( docBuilder.parse( expectedDeploymentDescriptor ),
400                                                   docBuilder.parse( actualDeploymentDescriptor ) );
401                     myDiff.overrideElementQualifier( new RecursiveElementNameAndTextQualifier() );
402                     XMLAssert.assertXMLEqual(
403                         "Wrong deployment descriptor generated for[" + expectedDeploymentDescriptor.getName() + "]",
404                         myDiff, true );
405                 }
406                 catch ( Exception e )
407                 {
408                     e.printStackTrace();
409                     fail( "Could not assert deployment descriptor " + e.getMessage() );
410                 }
411             }
412         }
413     }
414 
415     private File[] getDeploymentDescriptors( final File ddDirectory )
416     {
417         return ddDirectory.listFiles( new FilenameFilter()
418         {
419             public boolean accept( File dir, String name )
420             {
421                 return !name.equalsIgnoreCase( "manifest.mf" );
422             }
423         } );
424     }
425 }