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 MojoExecutionException, MojoFailureException
79      {
80          if ( !skip )
81          {
82              try
83              {
84                  File projectsDirectory = new File( project.getBasedir(), "target/test-classes/projects" );
85  
86                  if ( projectsDirectory.exists() )
87                  {
88                      File archetypeFile = project.getArtifact().getFile();
89  
90                      List projectsGoalFiles = FileUtils.getFiles( projectsDirectory, "*/goal.txt", "" );
91  
92                      Iterator goalFiles = projectsGoalFiles.iterator();
93  
94                      StringWriter errorWriter = new StringWriter();
95                      while ( goalFiles.hasNext() )
96                      {
97                          File goalFile = (File) goalFiles.next();
98  
99                          try
100                         {
101                             processIntegrationTest( goalFile, archetypeFile );
102                         }
103                         catch ( IntegrationTestFailure ex )
104                         {
105                             errorWriter.write( "Test " + goalFile.getParentFile().getName() + " failed\n" );
106                             errorWriter.write( ex.getStackTrace() + "\n" );
107                             errorWriter.write( ex.getMessage() + "\n" );
108                             errorWriter.write( "\n" );
109                         }
110                     }
111 
112                     String errors = errorWriter.toString();
113                     if ( !StringUtils.isEmpty( errors ) )
114                     {
115                         throw new MojoExecutionException( errors );
116                     }
117                 }
118             }
119             catch ( IOException ex )
120             {
121                 throw new MojoFailureException( ex, ex.getMessage(), ex.getMessage() );
122             }
123         }
124     }
125 
126     private void assertTest( File reference, File basedir )
127         throws IntegrationTestFailure, IOException
128     {
129         List referenceFiles = FileUtils.getFileNames( reference, "**", null, false );
130         List projectFiles = FileUtils.getFileNames( basedir, "**", null, false );
131 
132         boolean fileNamesEquals = CollectionUtils.isEqualCollection( referenceFiles, projectFiles );
133 
134         {
135             for ( Iterator refs = referenceFiles.iterator(); refs.hasNext(); )
136             {
137                 String ref = (String) refs.next();
138 
139                 if ( projectFiles.contains( ref ) )
140                 {
141                     projectFiles.remove( ref );
142                     getLog().debug( "Contained " + ref );
143                 }
144                 else
145                 {
146                     getLog().debug( "Not contained " + ref );
147                 }
148             }
149             getLog().debug( "Remains " + projectFiles );
150         }
151 
152         if ( !fileNamesEquals )
153         {
154             throw new IntegrationTestFailure( "Reference and generated project differs" );
155         }
156 
157         boolean contentEquals = true;
158 
159         for ( Iterator files = referenceFiles.iterator(); files.hasNext(); )
160         {
161             String file = (String) files.next();
162 
163             if ( file.endsWith( "pom.xml" ) )
164             {
165                 if ( !modelEquals( new File( reference, file ), new File( basedir, file ) ) )
166                 {
167                     getLog().warn( "Contents of file " + file + " are not equal" );
168                     contentEquals = false;
169                 }
170             }
171             else
172             {
173                 if ( !FileUtils.contentEquals( new File( reference, file ), new File( basedir, file ) ) )
174                 {
175                     getLog().warn( "Contents of file " + file + " are not equal" );
176                     contentEquals = false;
177                 }
178             }
179         }
180         if ( !contentEquals )
181         {
182             throw new IntegrationTestFailure( "Some content are not equals" );
183         }
184     }
185 
186     private Properties loadProperties( final File propertiesFile )
187         throws IOException, FileNotFoundException
188     {
189         Properties properties = new Properties();
190 
191         properties.load( new FileInputStream( propertiesFile ) );
192 
193         return properties;
194     }
195 
196     private boolean modelEquals( File referencePom, File generatedPom )
197         throws IOException
198     {
199         return FileUtils.contentEquals( referencePom, generatedPom );
200     }
201 
202     private void processIntegrationTest( File goalFile, File archetypeFile )
203         throws IntegrationTestFailure
204     {
205         try
206         {
207             Properties testProperties = getTestProperties( goalFile );
208 
209             Properties properties = getProperties( goalFile );
210 
211             String basedir = goalFile.getParentFile().getPath() + "/project";
212 
213             FileUtils.mkdir( basedir );
214             // TODO: fix this to use request
215             filesetGenerator.generateArchetype( null, archetypeFile, basedir );
216 
217             File reference = new File( goalFile.getParentFile(), "reference" );
218 
219             assertTest( reference, new File( basedir, properties.getProperty( Constants.ARTIFACT_ID ) ) );
220         }
221         catch ( ArchetypeNotConfigured ex )
222         {
223             throw new IntegrationTestFailure( ex );
224         }
225         catch ( UnknownArchetype ex )
226         {
227             throw new IntegrationTestFailure( ex );
228         }
229         catch ( PomFileExists ex )
230         {
231             throw new IntegrationTestFailure( ex );
232         }
233         catch ( ProjectDirectoryExists ex )
234         {
235             throw new IntegrationTestFailure( ex );
236         }
237         catch ( ArchetypeGenerationFailure ex )
238         {
239             throw new IntegrationTestFailure( ex );
240         }
241         catch ( IOException ex )
242         {
243             throw new IntegrationTestFailure( ex );
244         }
245         catch ( OutputFileExists ex )
246         {
247             throw new IntegrationTestFailure( ex );
248         }
249     }
250 
251     private Properties getProperties( File goalFile )
252         throws IOException
253     {
254         File propertiesFile = new File( goalFile.getParentFile(), "archetype.properties" );
255 
256         return loadProperties( propertiesFile );
257     }
258 
259     private Properties getTestProperties( File goalFile )
260         throws IOException
261     {
262         return loadProperties( goalFile );
263     }
264 
265     class IntegrationTestFailure
266         extends Exception
267     {
268         IntegrationTestFailure()
269         {
270             super();
271         }
272 
273         IntegrationTestFailure( String message )
274         {
275             super( message );
276         }
277 
278         IntegrationTestFailure( Throwable cause )
279         {
280             super( cause );
281         }
282 
283         IntegrationTestFailure( String message, Throwable cause )
284         {
285             super( message, cause );
286         }
287     }
288 }