View Javadoc

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 static org.mockito.Matchers.argThat;
23  import static org.mockito.Matchers.eq;
24  import static org.mockito.Matchers.isA;
25  import static org.mockito.Mockito.mock;
26  import static org.mockito.Mockito.verify;
27  import static org.mockito.Mockito.verifyNoMoreInteractions;
28  import static org.mockito.Mockito.when;
29  
30  import java.io.File;
31  import java.io.IOException;
32  import java.util.Collections;
33  import java.util.List;
34  
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.scm.ScmException;
37  import org.apache.maven.scm.ScmFile;
38  import org.apache.maven.scm.ScmFileSet;
39  import org.apache.maven.scm.ScmFileStatus;
40  import org.apache.maven.scm.ScmTagParameters;
41  import org.apache.maven.scm.command.tag.TagScmResult;
42  import org.apache.maven.scm.manager.NoSuchScmProviderException;
43  import org.apache.maven.scm.manager.ScmManager;
44  import org.apache.maven.scm.provider.ScmProvider;
45  import org.apache.maven.scm.provider.ScmProviderStub;
46  import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
47  import org.apache.maven.scm.repository.ScmRepository;
48  import org.apache.maven.scm.repository.ScmRepositoryException;
49  import org.apache.maven.shared.release.ReleaseExecutionException;
50  import org.apache.maven.shared.release.ReleaseFailureException;
51  import org.apache.maven.shared.release.config.ReleaseDescriptor;
52  import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
53  import org.apache.maven.shared.release.scm.DefaultScmRepositoryConfigurator;
54  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
55  import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
56  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
57  import org.apache.maven.shared.release.stubs.ScmManagerStub;
58  import org.apache.maven.shared.release.util.ReleaseUtil;
59  
60  /**
61   * Test the SCM tag phase.
62   *
63   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
64   */
65  public class ScmTagPhaseTest
66      extends AbstractReleaseTestCase
67  {
68      protected void setUp()
69          throws Exception
70      {
71          super.setUp();
72  
73          phase = (ReleasePhase) lookup( ReleasePhase.ROLE, "scm-tag" );
74      }
75  
76      public static String getPath(File file) 
77          throws IOException
78      {
79          return ReleaseUtil.isSymlink( file ) ? file.getCanonicalPath() : file.getAbsolutePath();
80      }
81      
82      public void testTag()
83          throws Exception
84      {
85          // prepare
86          ReleaseDescriptor descriptor = new ReleaseDescriptor();
87          List<MavenProject> reactorProjects = createReactorProjects();
88          descriptor.setScmSourceUrl( "scm-url" );
89          MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
90          descriptor.setWorkingDirectory( getPath(rootProject.getFile().getParentFile() ) );
91          descriptor.setScmReleaseLabel( "release-label" );
92          descriptor.setScmCommentPrefix( "[my prefix]" );
93  
94          ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile() );
95  
96          ScmProvider scmProviderMock = mock( ScmProvider.class );
97          when( scmProviderMock.tag( isA( ScmRepository.class ),
98                                     argThat( new IsScmFileSetEquals( fileSet ) ),
99                                     eq( "release-label" ), 
100                                    argThat( new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) ) ).
101                                    thenReturn( new TagScmResult( "...", 
102                                                                  Collections.singletonList( new ScmFile( getPath (rootProject
103                                                                                                                   .getFile() ), ScmFileStatus.TAGGED ) ) ) );
104         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
105         stub.setScmProvider( scmProviderMock );
106 
107         // execute
108         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
109 
110         // verify
111         verify( scmProviderMock ).tag( isA( ScmRepository.class ),
112                                        argThat( new IsScmFileSetEquals( fileSet ) ),
113                                        eq( "release-label" ), 
114                                        argThat( new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) );
115         verifyNoMoreInteractions( scmProviderMock );
116     }
117 
118     public void testCommitMultiModuleDeepFolders()
119         throws Exception
120     {
121         // prepare
122         List<MavenProject> reactorProjects = createReactorProjects( "scm-commit/", "multimodule-with-deep-subprojects" );
123         String sourceUrl = "http://svn.example.com/repos/project/trunk/";
124         String scmUrl = "scm:svn:" + sourceUrl;
125         ReleaseDescriptor descriptor = new ReleaseDescriptor();
126         descriptor.setScmSourceUrl( scmUrl );
127         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
128         descriptor.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) );
129         descriptor.setScmReleaseLabel( "release-label" );
130         descriptor.setScmCommentPrefix( "[my prefix]" );
131         descriptor.setScmTagBase( "http://svn.example.com/repos/project/releases/" );
132 
133         ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile() );
134 
135         SvnScmProviderRepository scmProviderRepository = new SvnScmProviderRepository( sourceUrl );
136         scmProviderRepository.setTagBase( "http://svn.example.com/repos/project/releases/" );
137         ScmRepository repository = new ScmRepository( "svn", scmProviderRepository );
138         ScmProvider scmProviderMock = mock( ScmProvider.class );
139         when( scmProviderMock.tag( eq( repository ),
140                                    argThat(new IsScmFileSetEquals( fileSet ) ), 
141                                    eq( "release-label" ),
142                                    argThat(new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) ) ).
143                                        thenReturn(  new TagScmResult( "...", Collections.singletonList( new ScmFile( getPath (rootProject
144                                                                                                                               .getFile() ), ScmFileStatus.TAGGED ) ) ) ) ;
145 
146         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
147         stub.setScmProvider( scmProviderMock );
148         stub.addScmRepositoryForUrl( scmUrl, repository );
149 
150         // execute
151         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
152         
153         // verify
154         verify( scmProviderMock ).tag( eq( repository ),
155                                        argThat(new IsScmFileSetEquals( fileSet ) ), 
156                                        eq( "release-label" ),
157                                        argThat(new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) );
158         verifyNoMoreInteractions( scmProviderMock ); 
159     }
160 
161     public void testCommitForFlatMultiModule()
162         throws Exception
163     {
164         // prepare
165         List<MavenProject> reactorProjects =
166             createReactorProjects( "rewrite-for-release/pom-with-parent-flat", "/root-project" );
167         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
168         ReleaseDescriptor descriptor = new ReleaseDescriptor();
169         descriptor.setScmSourceUrl( rootProject.getScm().getConnection() );
170         descriptor.setWorkingDirectory( getPath( rootProject.getFile().getParentFile() ) );
171         descriptor.setScmReleaseLabel( "release-label" );
172         descriptor.setScmCommentPrefix( "[my prefix]" );
173 
174         // one directory up from root project
175         ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile().getParentFile() );
176 
177         String scmUrl = "file://localhost/tmp/scm-repo/trunk";
178         SvnScmProviderRepository scmProviderRepository = new SvnScmProviderRepository( scmUrl );
179         ScmRepository repository = new ScmRepository( "svn", scmProviderRepository );
180         ScmProvider scmProviderMock = mock( ScmProvider.class );
181         when( scmProviderMock.tag( eq( repository ),
182                                    argThat( new IsScmFileSetEquals( fileSet ) ),
183                                    eq( "release-label" ),
184                                    argThat( new IsScmTagParamtersEquals( new ScmTagParameters(
185                                            "[my prefix] copy for tag release-label" ) ) ) ) ).thenReturn( new TagScmResult(
186                                                 "...",
187                                                 Collections.singletonList( new ScmFile(
188                                                                                         getPath( rootProject.getFile() ),
189                                                                                         ScmFileStatus.TAGGED ) ) ) );
190 
191         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
192         stub.setScmProvider( scmProviderMock );
193         stub.addScmRepositoryForUrl( "scm:svn:" + scmUrl, repository );
194 
195         // execute
196         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
197         
198         // verify
199         verify( scmProviderMock ).tag( eq( repository ),
200                                        argThat( new IsScmFileSetEquals( fileSet ) ),
201                                        eq( "release-label" ),
202                                        argThat( new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) );
203         verifyNoMoreInteractions( scmProviderMock );
204     }
205 
206     public void testCommitMultiModule()
207         throws Exception
208     {
209         // prepare
210         ReleaseDescriptor descriptor = new ReleaseDescriptor();
211         List<MavenProject> reactorProjects = createReactorProjects( "scm-commit/", "multiple-poms" );
212         descriptor.setScmSourceUrl( "scm-url" );
213         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
214         descriptor.setWorkingDirectory( getPath (rootProject.getFile().getParentFile() ) );
215         descriptor.setScmReleaseLabel( "release-label" );
216         descriptor.setScmCommentPrefix( "[my prefix]" );
217 
218         ScmFileSet fileSet = new ScmFileSet( rootProject.getFile().getParentFile() );
219 
220         ScmProvider scmProviderMock = mock( ScmProvider.class );
221         when( scmProviderMock.tag( isA( ScmRepository.class ),
222                                    argThat( new IsScmFileSetEquals( fileSet ) ),
223                                    eq( "release-label" ),
224                                    argThat( new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) ) ).thenReturn( new TagScmResult( "...", Collections.singletonList( new ScmFile( getPath( rootProject
225                        .getFile() ), ScmFileStatus.TAGGED ) ) ) );
226 
227         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
228         stub.setScmProvider( scmProviderMock );
229 
230         // exeucte
231         phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
232 
233         // verify
234         verify( scmProviderMock ).tag( isA( ScmRepository.class ),
235                                        argThat( new IsScmFileSetEquals( fileSet ) ),
236                                        eq( "release-label" ),
237                                        argThat( new IsScmTagParamtersEquals( new ScmTagParameters( "[my prefix] copy for tag release-label" ) ) ) );
238         verifyNoMoreInteractions( scmProviderMock );
239     }
240 
241     public void testTagNoReleaseLabel()
242         throws Exception
243     {
244         ReleaseDescriptor descriptor = new ReleaseDescriptor();
245         List<MavenProject> reactorProjects = createReactorProjects();
246 
247         try
248         {
249             phase.execute( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
250             fail( "Should have thrown an exception" );
251         }
252         catch ( ReleaseFailureException e )
253         {
254             assertTrue( true );
255         }
256     }
257 
258     public void testSimulateTag()
259         throws Exception
260     {
261         ReleaseDescriptor descriptor = new ReleaseDescriptor();
262         List<MavenProject> reactorProjects = createReactorProjects();
263         descriptor.setScmSourceUrl( "scm-url" );
264         MavenProject rootProject = ReleaseUtil.getRootProject( reactorProjects );
265         descriptor.setWorkingDirectory( getPath ( rootProject.getFile().getParentFile() ) );
266         descriptor.setScmReleaseLabel( "release-label" );
267 
268         ScmProvider scmProviderMock = mock( ScmProvider.class );
269 
270         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
271         stub.setScmProvider( scmProviderMock );
272 
273         // execute
274         phase.simulate( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
275 
276         // verify
277         // no scmProvider invocation
278         verifyNoMoreInteractions( scmProviderMock );
279     }
280 
281     public void testSimulateTagNoReleaseLabel()
282         throws Exception
283     {
284         ReleaseDescriptor descriptor = new ReleaseDescriptor();
285         List<MavenProject> reactorProjects = createReactorProjects();
286 
287         try
288         {
289             phase.simulate( descriptor, new DefaultReleaseEnvironment(), reactorProjects );
290             fail( "Should have thrown an exception" );
291         }
292         catch ( ReleaseFailureException e )
293         {
294             assertTrue( true );
295         }
296     }
297 
298     public void testNoSuchScmProviderExceptionThrown()
299         throws Exception
300     {
301         // prepare
302         List<MavenProject> reactorProjects = createReactorProjects();
303         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
304 
305         ScmManager scmManagerMock = mock( ScmManager.class );
306         when( scmManagerMock.makeScmRepository( "scm-url" ) ).thenThrow( new NoSuchScmProviderException( "..." ) );
307 
308         DefaultScmRepositoryConfigurator configurator =
309             (DefaultScmRepositoryConfigurator) lookup( ScmRepositoryConfigurator.ROLE );
310         configurator.setScmManager( scmManagerMock );
311 
312         // execute
313         try
314         {
315             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
316 
317             fail( "Status check should have failed" );
318         }
319         catch ( ReleaseExecutionException e )
320         {
321             assertEquals( "check cause", NoSuchScmProviderException.class, e.getCause().getClass() );
322         }
323         
324         // verify
325         verify( scmManagerMock ).makeScmRepository( "scm-url" );
326         verifyNoMoreInteractions( scmManagerMock );
327     }
328 
329     public void testScmRepositoryExceptionThrown()
330         throws Exception
331     {
332         // prepare
333         List<MavenProject> reactorProjects = createReactorProjects();
334         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
335 
336         ScmManager scmManagerMock = mock( ScmManager.class );
337         when( scmManagerMock.makeScmRepository( "scm-url" ) ).thenThrow( new ScmRepositoryException( "..." ) );
338         DefaultScmRepositoryConfigurator configurator =
339             (DefaultScmRepositoryConfigurator) lookup( ScmRepositoryConfigurator.ROLE );
340         configurator.setScmManager( scmManagerMock );
341 
342         // execute
343         try
344         {
345             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
346 
347             fail( "Status check should have failed" );
348         }
349         catch ( ReleaseScmRepositoryException e )
350         {
351             assertNull( "Check no additional cause", e.getCause() );
352         }
353         
354         // verify
355         verify( scmManagerMock ).makeScmRepository( "scm-url" );
356         verifyNoMoreInteractions( scmManagerMock );
357     }
358 
359     public void testScmExceptionThrown()
360         throws Exception
361     {
362         // prepare
363         List<MavenProject> reactorProjects = createReactorProjects();
364         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
365 
366         ScmProvider scmProviderMock = mock( ScmProvider.class );
367         when( scmProviderMock.tag( isA( ScmRepository.class ),
368                                    isA( ScmFileSet.class ),
369                                    isA( String.class ),
370                                    isA( ScmTagParameters.class ) ) ).thenThrow( new ScmException( "..." ) );
371 
372         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
373         stub.setScmProvider( scmProviderMock );
374 
375         // execute
376         try
377         {
378             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
379 
380             fail( "Status check should have failed" );
381         }
382         catch ( ReleaseExecutionException e )
383         {
384             assertEquals( "check cause", ScmException.class, e.getCause().getClass() );
385         }
386         
387         // verify
388         verify( scmProviderMock ).tag( isA( ScmRepository.class ),
389                                        isA( ScmFileSet.class ),
390                                        isA( String.class ),
391                                        isA( ScmTagParameters.class ) );
392         verifyNoMoreInteractions( scmProviderMock );
393     }
394 
395     public void testScmResultFailure()
396         throws Exception
397     {
398         List<MavenProject> reactorProjects = createReactorProjects();
399         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
400 
401         ScmManager scmManager = (ScmManager) lookup( ScmManager.ROLE );
402         ScmProviderStub providerStub =
403             (ScmProviderStub) scmManager.getProviderByUrl( releaseDescriptor.getScmSourceUrl() );
404 
405         providerStub.setTagScmResult( new TagScmResult( "", "", "", false ) );
406 
407         try
408         {
409             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), reactorProjects );
410 
411             fail( "Commit should have failed" );
412         }
413         catch ( ReleaseScmCommandException e )
414         {
415             assertNull( "check no other cause", e.getCause() );
416         }
417     }
418 
419     private List<MavenProject> createReactorProjects()
420         throws Exception
421     {
422         return createReactorProjects( "scm-commit/", "single-pom" );
423     }
424 
425     private static ReleaseDescriptor createReleaseDescriptor() 
426         throws IOException
427     {
428         ReleaseDescriptor descriptor = new ReleaseDescriptor();
429         descriptor.setScmSourceUrl( "scm-url" );
430         descriptor.setScmReleaseLabel( "release-label" );
431         descriptor.setWorkingDirectory( getPath(getTestFile( "target/test/checkout" ) ) );
432         return descriptor;
433     }
434 }