1   package org.apache.maven.shared.release.phase;
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.apache.maven.scm.ScmException;
24  import org.apache.maven.scm.ScmFileSet;
25  import org.apache.maven.scm.command.checkin.CheckInScmResult;
26  import org.apache.maven.scm.manager.NoSuchScmProviderException;
27  import org.apache.maven.scm.manager.ScmManager;
28  import org.apache.maven.scm.manager.ScmManagerStub;
29  import org.apache.maven.scm.provider.ScmProvider;
30  import org.apache.maven.scm.provider.ScmProviderStub;
31  import org.apache.maven.scm.repository.ScmRepositoryException;
32  import org.apache.maven.shared.release.ReleaseExecutionException;
33  import org.apache.maven.shared.release.ReleaseFailureException;
34  import org.apache.maven.shared.release.config.ReleaseDescriptor;
35  import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
36  import org.apache.maven.shared.release.scm.DefaultScmRepositoryConfigurator;
37  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
38  import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
39  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
40  import org.apache.maven.shared.release.util.ReleaseUtil;
41  import org.jmock.Mock;
42  import org.jmock.core.Constraint;
43  import org.jmock.core.constraint.IsAnything;
44  import org.jmock.core.constraint.IsEqual;
45  import org.jmock.core.constraint.IsNull;
46  import org.jmock.core.matcher.InvokeOnceMatcher;
47  import org.jmock.core.matcher.TestFailureMatcher;
48  import org.jmock.core.stub.ReturnStub;
49  import org.jmock.core.stub.ThrowStub;
50  
51  import java.io.File;
52  import java.util.ArrayList;
53  import java.util.Collections;
54  import java.util.Iterator;
55  import java.util.List;
56  
57  /**
58   * Test the SCM commit phase.
59   *
60   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
61   */
62  public class ScmCommitPhaseTest
63      extends AbstractReleaseTestCase
64  {
65      private static final String PREFIX = "[maven-release-manager] prepare release ";
66  
67      private static final File[] EMPTY_FILE_ARRAY = new File[0];
68  
69      protected void setUp()
70          throws Exception
71      {
72          super.setUp();
73  
74          phase = (ReleasePhase) lookup( ReleasePhase.ROLE, "scm-commit-release" );
75      }
76  
77      public void testCommit()
78          throws Exception
79      {
80          List reactorProjects = createReactorProjects();
81          ReleaseDescriptor descriptor = new ReleaseDescriptor();
82          descriptor.setScmSourceUrl( "scm-url" );
83          MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
84          descriptor.setWorkingDirectory( rootProject.getFile().getParentFile().getAbsolutePath() );
85          descriptor.setScmReleaseLabel( "release-label" );
86  
87          ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile(), rootProject.getFile() );
88  
89          Mock scmProviderMock = new Mock( ScmProvider.class );
90          Constraint[] arguments = new Constraint[]{new IsAnything(), new IsScmFileSetEquals( fileSet ), new IsNull(),
91              new IsEqual( PREFIX + "release-label" )};
92          scmProviderMock.expects( new InvokeOnceMatcher() ).method( "checkIn" ).with( arguments ).will(
93              new ReturnStub( new CheckInScmResult( "...", Collections.singletonList( rootProject.getFile() ) ) ) );
94  
95          ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
96          stub.setScmProvider( (ScmProvider) scmProviderMock.proxy() );
97  
98          phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
99  
100         assertTrue( true );
101     }
102 
103     public void testCommitMultiModule()
104         throws Exception
105     {
106         ReleaseDescriptor descriptor = new ReleaseDescriptor();
107         List reactorProjects = createReactorProjects( "scm-commit/", "multiple-poms", false );
108         descriptor.setScmSourceUrl( "scm-url" );
109         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
110         descriptor.setWorkingDirectory( rootProject.getFile().getParentFile().getAbsolutePath() );
111         descriptor.setScmReleaseLabel( "release-label" );
112 
113         List poms = new ArrayList();
114         for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
115         {
116             MavenProject project = (MavenProject) i.next();
117             poms.add( project.getFile() );
118         }
119         ScmFileSet fileSet =
120             new ScmFileSet( rootProject.getFile().getParentFile(), (File[]) poms.toArray( EMPTY_FILE_ARRAY ) );
121 
122         Mock scmProviderMock = new Mock( ScmProvider.class );
123         Constraint[] arguments = new Constraint[]{new IsAnything(), new IsScmFileSetEquals( fileSet ), new IsNull(),
124             new IsEqual( PREFIX + "release-label" )};
125         scmProviderMock.expects( new InvokeOnceMatcher() ).method( "checkIn" ).with( arguments ).will(
126             new ReturnStub( new CheckInScmResult( "...", Collections.singletonList( rootProject.getFile() ) ) ) );
127 
128         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
129         stub.setScmProvider( (ScmProvider) scmProviderMock.proxy() );
130 
131         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
132 
133         assertTrue( true );
134     }
135 
136     public void testCommitDevelopment()
137         throws Exception
138     {
139         phase = (ReleasePhase) lookup( ReleasePhase.ROLE, "scm-commit-development" );
140 
141         ReleaseDescriptor descriptor = new ReleaseDescriptor();
142         List reactorProjects = createReactorProjects();
143         descriptor.setScmSourceUrl( "scm-url" );
144         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
145         descriptor.setWorkingDirectory( rootProject.getFile().getParentFile().getAbsolutePath() );
146         descriptor.setScmReleaseLabel( "release-label" );
147 
148         ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile(), rootProject.getFile() );
149 
150         Mock scmProviderMock = new Mock( ScmProvider.class );
151         Constraint[] arguments = new Constraint[]{new IsAnything(), new IsScmFileSetEquals( fileSet ), new IsNull(),
152             new IsEqual( "[maven-release-manager] prepare for next development iteration" )};
153         scmProviderMock.expects( new InvokeOnceMatcher() ).method( "checkIn" ).with( arguments ).will(
154             new ReturnStub( new CheckInScmResult( "...", Collections.singletonList( rootProject.getFile() ) ) ) );
155 
156         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
157         stub.setScmProvider( (ScmProvider) scmProviderMock.proxy() );
158 
159         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
160 
161         assertTrue( true );
162     }
163 
164     public void testCommitNoReleaseLabel()
165         throws Exception
166     {
167         ReleaseDescriptor descriptor = new ReleaseDescriptor();
168         List reactorProjects = createReactorProjects();
169 
170         try
171         {
172             phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
173             fail( "Should have thrown an exception" );
174         }
175         catch ( ReleaseFailureException e )
176         {
177             assertTrue( true );
178         }
179     }
180 
181     public void testCommitGenerateReleasePoms()
182         throws Exception
183     {
184         List reactorProjects = createReactorProjects();
185         ReleaseDescriptor descriptor = new ReleaseDescriptor();
186         descriptor.setScmSourceUrl( "scm-url" );
187         descriptor.setGenerateReleasePoms( true );
188         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
189         descriptor.setWorkingDirectory( rootProject.getFile().getParentFile().getAbsolutePath() );
190         descriptor.setScmReleaseLabel( "release-label" );
191 
192         List files = new ArrayList();
193         files.add( rootProject.getFile() );
194         files.add( ReleaseUtil.getReleasePom( rootProject ) );
195         ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile(), files );
196 
197         Mock scmProviderMock = new Mock( ScmProvider.class );
198         Constraint[] arguments = new Constraint[] { new IsAnything(), new IsScmFileSetEquals( fileSet ), new IsNull(),
199             new IsEqual( PREFIX + "release-label" ) };
200         scmProviderMock.expects( new InvokeOnceMatcher() ).method( "checkIn" ).with( arguments ).will(
201             new ReturnStub( new CheckInScmResult( "...", Collections.singletonList( rootProject.getFile() ) ) ) );
202 
203         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
204         stub.setScmProvider( (ScmProvider) scmProviderMock.proxy() );
205 
206         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
207 
208         assertTrue( true );
209     }
210 
211     public void testSimulateCommit()
212         throws Exception
213     {
214         ReleaseDescriptor descriptor = new ReleaseDescriptor();
215         List reactorProjects = createReactorProjects();
216         descriptor.setScmSourceUrl( "scm-url" );
217         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
218         descriptor.setWorkingDirectory( rootProject.getFile().getParentFile().getAbsolutePath() );
219         descriptor.setScmReleaseLabel( "release-label" );
220 
221         Mock scmProviderMock = new Mock( ScmProvider.class );
222         scmProviderMock.expects( new TestFailureMatcher( "Shouldn't have called checkIn" ) ).method( "checkIn" );
223 
224         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
225         stub.setScmProvider( (ScmProvider) scmProviderMock.proxy() );
226 
227         phase.simulate( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
228 
229         assertTrue( true );
230     }
231 
232     public void testSimulateCommitNoReleaseLabel()
233         throws Exception
234     {
235         ReleaseDescriptor descriptor = new ReleaseDescriptor();
236         List reactorProjects = createReactorProjects();
237 
238         try
239         {
240             phase.simulate( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
241             fail( "Should have thrown an exception" );
242         }
243         catch ( ReleaseFailureException e )
244         {
245             assertTrue( true );
246         }
247     }
248 
249     public void testNoSuchScmProviderExceptionThrown()
250         throws Exception
251     {
252         List reactorProjects = createReactorProjects();
253         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
254 
255         Mock scmManagerMock = new Mock( ScmManager.class );
256         scmManagerMock.expects( new InvokeOnceMatcher() ).method( "makeScmRepository" ).with(
257             new IsEqual( "scm-url" ) ).will( new ThrowStub( new NoSuchScmProviderException( "..." ) ) );
258 
259         ScmManager scmManager = (ScmManager) scmManagerMock.proxy();
260         DefaultScmRepositoryConfigurator configurator =
261             (DefaultScmRepositoryConfigurator) lookup( ScmRepositoryConfigurator.ROLE );
262         configurator.setScmManager( scmManager );
263 
264         try
265         {
266             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
267 
268             fail( "Status check should have failed" );
269         }
270         catch ( ReleaseExecutionException e )
271         {
272             assertEquals( "check cause", NoSuchScmProviderException.class, e.getCause().getClass() );
273         }
274     }
275 
276     public void testScmRepositoryExceptionThrown()
277         throws Exception
278     {
279         List reactorProjects = createReactorProjects();
280         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
281 
282         Mock scmManagerMock = new Mock( ScmManager.class );
283         scmManagerMock.expects( new InvokeOnceMatcher() ).method( "makeScmRepository" ).with(
284             new IsEqual( "scm-url" ) ).will( new ThrowStub( new ScmRepositoryException( "..." ) ) );
285 
286         ScmManager scmManager = (ScmManager) scmManagerMock.proxy();
287         DefaultScmRepositoryConfigurator configurator =
288             (DefaultScmRepositoryConfigurator) lookup( ScmRepositoryConfigurator.ROLE );
289         configurator.setScmManager( scmManager );
290 
291         try
292         {
293             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
294 
295             fail( "Status check should have failed" );
296         }
297         catch ( ReleaseScmRepositoryException e )
298         {
299             assertNull( "Check no additional cause", e.getCause() );
300         }
301     }
302 
303     public void testScmExceptionThrown()
304         throws Exception
305     {
306         List reactorProjects = createReactorProjects();
307         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
308 
309         Mock scmProviderMock = new Mock( ScmProvider.class );
310         scmProviderMock.expects( new InvokeOnceMatcher() ).method( "checkIn" ).will(
311             new ThrowStub( new ScmException( "..." ) ) );
312 
313         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
314         stub.setScmProvider( (ScmProvider) scmProviderMock.proxy() );
315 
316         try
317         {
318             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
319 
320             fail( "Status check should have failed" );
321         }
322         catch ( ReleaseExecutionException e )
323         {
324             assertEquals( "check cause", ScmException.class, e.getCause().getClass() );
325         }
326     }
327 
328     public void testScmResultFailure()
329         throws Exception
330     {
331         List reactorProjects = createReactorProjects();
332         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
333 
334         ScmManager scmManager = (ScmManager) lookup( ScmManager.ROLE );
335         ScmProviderStub providerStub =
336             (ScmProviderStub) scmManager.getProviderByUrl( releaseDescriptor.getScmSourceUrl() );
337 
338         providerStub.setCheckInScmResult( new CheckInScmResult( "", "", "", false ) );
339 
340         try
341         {
342             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
343 
344             fail( "Commit should have failed" );
345         }
346         catch ( ReleaseScmCommandException e )
347         {
348             assertNull( "check no other cause", e.getCause() );
349         }
350     }
351 
352     private List createReactorProjects()
353         throws Exception
354     {
355         return createReactorProjects( "scm-commit/", "single-pom", false );
356     }
357 
358     private static ReleaseDescriptor createReleaseDescriptor()
359     {
360         ReleaseDescriptor descriptor = new ReleaseDescriptor();
361         descriptor.setScmSourceUrl( "scm-url" );
362         descriptor.setScmReleaseLabel( "release-label" );
363         descriptor.setWorkingDirectory( getTestFile( "target/test/checkout" ).getAbsolutePath() );
364         return descriptor;
365     }
366 
367 }