View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.maven.archetype.mojos;
21  
22  import org.apache.commons.collections.CollectionUtils;
23  import org.apache.maven.archetype.common.Constants;
24  import org.apache.maven.archetype.exception.ArchetypeGenerationFailure;
25  import org.apache.maven.archetype.exception.ArchetypeNotConfigured;
26  import org.apache.maven.archetype.exception.OutputFileExists;
27  import org.apache.maven.archetype.exception.PomFileExists;
28  import org.apache.maven.archetype.exception.ProjectDirectoryExists;
29  import org.apache.maven.archetype.exception.UnknownArchetype;
30  import org.apache.maven.archetype.generator.FilesetArchetypeGenerator;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugin.MojoFailureException;
34  import org.apache.maven.project.MavenProject;
35  import org.codehaus.plexus.util.FileUtils;
36  import org.codehaus.plexus.util.StringUtils;
37  
38  import java.io.File;
39  import java.io.FileInputStream;
40  import java.io.FileNotFoundException;
41  import java.io.IOException;
42  import java.io.StringWriter;
43  import java.util.Iterator;
44  import java.util.List;
45  import java.util.Properties;
46  
47  /**
48   * Execute the archetype integration tests.
49   *
50   * @author rafale
51   * @requiresProject true
52   * @goal integration-test
53   */
54  public class IntegrationTestMojo
55      extends AbstractMojo
56  {
57      /** @component */
58      FilesetArchetypeGenerator filesetGenerator;
59  
60      /**
61       * The archetype project to execute the integration tests on.
62       *
63       * @parameter expression="${project}"
64       * @required
65       * @readonly
66       */
67      private MavenProject project;
68  
69      /**
70       * Skip the integration test.
71       *
72       * @parameter expression="${archetype.test.skip}"
73       * @readonly
74       */
75      private boolean skip = false;
76  
77      public void execute()
78          throws
79          MojoExecutionException,
80          MojoFailureException
81      {
82          if ( !skip )
83          {
84              try
85              {
86                  File projectsDirectory =
87                      new File( project.getBasedir(), "target/test-classes/projects" );
88  
89                  if ( projectsDirectory.exists() )
90                  {
91                      File archetypeFile = project.getArtifact().getFile();
92  
93                      List projectsGoalFiles =
94                          FileUtils.getFiles( projectsDirectory, "*/goal.txt", "" );
95  
96                      Iterator goalFiles = projectsGoalFiles.iterator();
97  
98                      StringWriter errorWriter = new StringWriter();
99                      while ( goalFiles.hasNext() )
100                     {
101                         File goalFile = (File) goalFiles.next();
102 
103                         try
104                         {
105                             processIntegrationTest( goalFile, archetypeFile );
106                         }
107                         catch ( IntegrationTestFailure ex )
108                         {
109                             errorWriter.write(
110                                 "Test " + goalFile.getParentFile().getName() + " failed\n"
111                             );
112 
113                             errorWriter.write( ex.getStackTrace() + "\n" );
114                             errorWriter.write( ex.getMessage() + "\n" );
115                             errorWriter.write( "\n" );
116                         }
117                     }
118 
119                     String errors = errorWriter.toString();
120                     if ( !StringUtils.isEmpty( errors ) )
121                     {
122                         throw new MojoExecutionException( errors );
123                     }
124                 }
125             }
126             catch ( IOException ex )
127             {
128                 throw new MojoFailureException( ex, ex.getMessage(), ex.getMessage() );
129             }
130         }
131     }
132 
133     private void assertTest( File reference,
134                              File basedir )
135         throws
136         IntegrationTestFailure,
137         IOException
138     {
139         List referenceFiles = FileUtils.getFileNames( reference, "**", null, false );
140         List projectFiles = FileUtils.getFileNames( basedir, "**", null, false );
141 
142         boolean fileNamesEquals =
143             CollectionUtils.isEqualCollection( referenceFiles, projectFiles );
144 
145         {
146             Iterator refs = referenceFiles.iterator();
147             while ( refs.hasNext() )
148             {
149                 String ref = (String) refs.next();
150 
151                 if ( projectFiles.contains( ref ) )
152                 {
153                     projectFiles.remove( ref );
154                     getLog().debug( "Contained " + ref );
155                 }
156                 else
157                 {
158                     getLog().debug( "Not contained " + ref );
159                 }
160             }
161             getLog().debug( "Remains " + projectFiles );
162         }
163 
164         if ( !fileNamesEquals )
165         {
166             throw new IntegrationTestFailure( "Reference and generated project differs" );
167         }
168 
169         boolean contentEquals = true;
170         Iterator files = referenceFiles.iterator();
171         while ( files.hasNext() )
172         {
173             String file = (String) files.next();
174 
175             if ( file.endsWith( "pom.xml" ) )
176             {
177                 if ( !modelEquals( new File( reference, file ), new File( basedir, file ) ) )
178                 {
179                     getLog().warn( "Contents of file " + file + " are not equal" );
180                     contentEquals = false;
181                 }
182             }
183             else
184             {
185                 if ( !FileUtils.contentEquals(
186                     new File( reference, file ),
187                     new File( basedir, file )
188                 )
189                     )
190                 {
191                     getLog().warn( "Contents of file " + file + " are not equal" );
192                     contentEquals = false;
193                 }
194             }
195         }
196         if ( !contentEquals )
197         {
198             throw new IntegrationTestFailure( "Some content are not equals" );
199         }
200     }
201 
202     private Properties loadProperties( final File propertiesFile )
203         throws
204         IOException,
205         FileNotFoundException
206     {
207         Properties properties = new Properties();
208 
209         properties.load( new FileInputStream( propertiesFile ) );
210 
211         return properties;
212     }
213 
214     private boolean modelEquals( File referencePom,
215                                  File generatedPom )
216         throws
217         IOException
218     {
219         return FileUtils.contentEquals( referencePom, generatedPom );
220     }
221 
222     private void processIntegrationTest( File goalFile,
223                                          File archetypeFile )
224         throws
225         IntegrationTestFailure
226     {
227         try
228         {
229             Properties testProperties = getTestProperties( goalFile );
230 
231             Properties properties = getProperties( goalFile );
232 
233             String basedir = goalFile.getParentFile().getPath() + "/project";
234 
235             FileUtils.mkdir( basedir );
236 //TODO: fix this to use request
237             filesetGenerator.generateArchetype( null, archetypeFile, basedir );
238 
239             File reference = new File( goalFile.getParentFile(), "reference" );
240 
241             assertTest(
242                 reference,
243                 new File( basedir, properties.getProperty( Constants.ARTIFACT_ID ) )
244             );
245         }
246         catch ( ArchetypeNotConfigured ex )
247         {
248             throw new IntegrationTestFailure( ex );
249         }
250         catch ( UnknownArchetype ex )
251         {
252             throw new IntegrationTestFailure( ex );
253         }
254         catch ( PomFileExists ex )
255         {
256             throw new IntegrationTestFailure( ex );
257         }
258         catch ( ProjectDirectoryExists ex )
259         {
260             throw new IntegrationTestFailure( ex );
261         }
262         catch ( ArchetypeGenerationFailure ex )
263         {
264             throw new IntegrationTestFailure( ex );
265         }
266         catch ( IOException ex )
267         {
268             throw new IntegrationTestFailure( ex );
269         }
270         catch ( OutputFileExists ex )
271         {
272             throw new IntegrationTestFailure( ex );
273         }
274     }
275 
276     private Properties getProperties( File goalFile )
277         throws
278         IOException
279     {
280         File propertiesFile = new File( goalFile.getParentFile(), "archetype.properties" );
281 
282         return loadProperties( propertiesFile );
283     }
284 
285     private Properties getTestProperties( File goalFile )
286         throws
287         IOException
288     {
289         return loadProperties( goalFile );
290     }
291 
292     class IntegrationTestFailure
293         extends Exception
294     {
295         IntegrationTestFailure()
296         {
297             super();
298         }
299 
300         IntegrationTestFailure( String message )
301         {
302             super( message );
303         }
304 
305         IntegrationTestFailure( Throwable cause )
306         {
307             super( cause );
308         }
309 
310         IntegrationTestFailure( String message,
311                                 Throwable cause )
312         {
313             super( message, cause );
314         }
315     }
316 }