View Javadoc

1   package org.apache.maven.shared.test.plugin;
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 org.apache.maven.project.MavenProject;
23  import org.codehaus.plexus.component.annotations.Component;
24  import org.codehaus.plexus.component.annotations.Requirement;
25  import org.codehaus.plexus.util.FileUtils;
26  
27  import java.io.File;
28  import java.io.IOException;
29  
30  /**
31   * Test tool that provides a single point of access for staging a maven component artifact - along with its
32   * POM lineage - into a clean test-time local repository. This involves modifying the component POM to
33   * provide a stable test-time version for test-build POMs to reference, then installing the component
34   * jar and associated POMs (including those ancestors that are reachable using <relativePath>)
35   * into the test local repository.
36   *
37   * <p>
38   * <b>WARNING:</b> Currently, the <code>RepositoryTool</code> will not
39   * resolve parent POMs that exist <b>only</b> in your normal local repository, and are not reachable
40   * using the relativePath element. This may result in failed test builds, as one or more of the
41   * component's ancestor POMs cannot be resolved.
42   * </p>
43   *
44   * @author jdcasey
45   * @version $Id$
46   */
47  @Component( role = ComponentTestTool.class )
48  public class ComponentTestTool
49  {
50      /** Plexus role */
51      public static final String ROLE = ComponentTestTool.class.getName();
52  
53      @Requirement
54      private ProjectTool projectTool;
55  
56      @Requirement
57      private RepositoryTool repositoryTool;
58  
59      /**
60       * Stage the component, using a stable version, into a temporary local-repository directory that is
61       * generated by this method. When the component is staged, return the local repository base directory
62       * for use in test builds.
63       *
64       * @param pomFile current POM file
65       * @param testVersion The test version for the component, used for reference in test-build POMs and
66       * fully-qualified goals
67       * @return The base-directory location of the generated local repository
68       * @throws TestToolsException if any
69       */
70      public File prepareComponentForIntegrationTesting( File pomFile, String testVersion )
71          throws TestToolsException
72      {
73          return prepareForTesting( pomFile, testVersion, false, null );
74      }
75  
76      /**
77       * Stage the component, using a stable version, into a temporary local-repository directory that is
78       * generated by this method. When the component is staged, return the local repository base directory
79       * for use in test builds. This method also skips unit testing during component jar production,
80       * since it is assumed that executing these tests would lead to a recursive test-and-build loop.
81       *
82       * @param pomFile current POM file
83       * @param testVersion The test version for the component, used for reference in test-build POMs and
84       * fully-qualified goals
85       * @return The base-directory location of the generated local repository
86       * @throws TestToolsException if any
87       */
88      public File prepareComponentForUnitTestingWithMavenBuilds( File pomFile, String testVersion )
89          throws TestToolsException
90      {
91          return prepareForTesting( pomFile, testVersion, true, null );
92      }
93  
94      /**
95       * Stage the component, using a stable version, into the specified local-repository directory.
96       * When the component is staged, return the local repository base directory for verification.
97       *
98       * @param pomFile current POM file
99       * @param testVersion The test version for the component, used for reference in test-build POMs and
100      *   fully-qualified goals
101      * @param localRepositoryDir The base-directory location of the test local repository, into which
102      *   the component's test version should be staged.
103      * @return The base-directory location of the generated local repository
104      * @throws TestToolsException if any
105      */
106     public File prepareComponentForIntegrationTesting( File pomFile, String testVersion, File localRepositoryDir )
107         throws TestToolsException
108     {
109         return prepareForTesting( pomFile, testVersion, false, localRepositoryDir );
110     }
111 
112     /**
113      * Stage the component, using a stable version, into the specified local-repository directory.
114      * When the component is staged, return the local repository base directory for verification. This
115      * method also skips unit testing during component jar production, since it is assumed that
116      * executing these tests would lead to a recursive test-and-build loop.
117      *
118      * @param pomFile current POM file
119      * @param testVersion The test version for the component, used for reference in test-build POMs and
120      * fully-qualified goals
121      * @param localRepositoryDir The base-directory location of the test local repository, into which
122      * the component's test version should be staged.
123      * @return The base-directory location of the generated local repository
124      * @throws TestToolsException if any
125      */
126     public File prepareComponentForUnitTestingWithMavenBuilds( File pomFile, String testVersion,
127                                                                File localRepositoryDir )
128         throws TestToolsException
129     {
130         return prepareForTesting( pomFile, testVersion, true, localRepositoryDir );
131     }
132 
133     private File prepareForTesting( File pomFile, String testVersion, boolean skipUnitTests, File localRepositoryDir )
134         throws TestToolsException
135     {
136         File realProjectDir = pomFile.getParentFile();
137         try
138         {
139             realProjectDir = realProjectDir.getCanonicalFile();
140         }
141         catch ( IOException e )
142         {
143             throw new TestToolsException( "Failed to stage component for testing.", e );
144         }
145 
146         try
147         {
148             final File tmpDir = File.createTempFile( "component-IT-staging-project", "" );
149 
150             tmpDir.delete();
151 
152             tmpDir.mkdirs();
153 
154             Runtime.getRuntime().addShutdownHook( new Thread( new Runnable()
155             {
156                 public void run()
157                 {
158                     try
159                     {
160                         FileUtils.deleteDirectory( tmpDir );
161                     }
162                     catch ( IOException e )
163                     {
164                         // it'll get cleaned up when the temp dir is purged next...
165                     }
166                 }
167 
168             } ) );
169 
170             FileUtils.copyDirectoryStructure( realProjectDir, tmpDir );
171         }
172         catch ( IOException e )
173         {
174             throw new TestToolsException( "Failed to create temporary staging directory for component project.", e );
175         }
176 
177         File buildLog = new File( "target/test-build-logs/setup.build.log" );
178 
179         buildLog.getParentFile().mkdirs();
180 
181         File localRepoDir = localRepositoryDir;
182 
183         if ( localRepoDir == null )
184         {
185             localRepoDir = new File( "target/test-local-repository" );
186         }
187 
188         MavenProject project = projectTool.packageProjectArtifact( pomFile, testVersion, skipUnitTests, buildLog );
189 
190         repositoryTool.createLocalRepositoryFromComponentProject( project, new File( realProjectDir, "pom.xml" ),
191                                                                   localRepoDir );
192 
193         return localRepoDir;
194     }
195 }