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