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.eq;
23  import static org.mockito.Matchers.isA;
24  import static org.mockito.Mockito.mock;
25  import static org.mockito.Mockito.times;
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.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.Iterator;
34  import java.util.List;
35  
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.command.status.StatusScmResult;
41  import org.apache.maven.scm.manager.NoSuchScmProviderException;
42  import org.apache.maven.scm.manager.ScmManager;
43  import org.apache.maven.scm.manager.ScmManagerStub;
44  import org.apache.maven.scm.provider.ScmProvider;
45  import org.apache.maven.scm.provider.ScmProviderStub;
46  import org.apache.maven.scm.repository.ScmRepository;
47  import org.apache.maven.scm.repository.ScmRepositoryException;
48  import org.apache.maven.shared.release.ReleaseExecutionException;
49  import org.apache.maven.shared.release.ReleaseFailureException;
50  import org.apache.maven.shared.release.ReleaseResult;
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.codehaus.plexus.PlexusTestCase;
58  
59  /**
60   * Test the SCM modification check phase.
61   *
62   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
63   */
64  public class ScmCheckModificationsPhaseTest
65      extends PlexusTestCase
66  {
67      private ReleasePhase phase;
68  
69      protected void setUp()
70          throws Exception
71      {
72          super.setUp();
73  
74          phase = (ReleasePhase) lookup( ReleasePhase.ROLE, "scm-check-modifications" );
75      }
76  
77      public void testNoSuchScmProviderExceptionThrown()
78          throws Exception
79      {
80          // prepare
81          ReleaseDescriptor releaseDescriptor = new ReleaseDescriptor();
82          releaseDescriptor.setScmSourceUrl( "scm-url" );
83          releaseDescriptor.setWorkingDirectory( getTestFile( "target/test/checkout" ).getAbsolutePath() );
84  
85          ScmManager scmManagerMock = mock( ScmManager.class );
86          when( scmManagerMock.makeScmRepository( eq( "scm-url" ) ) ).thenThrow( new NoSuchScmProviderException( "..." ) );
87  
88          DefaultScmRepositoryConfigurator configurator =
89              (DefaultScmRepositoryConfigurator) lookup( ScmRepositoryConfigurator.ROLE );
90          configurator.setScmManager( scmManagerMock );
91  
92          // execute
93          try
94          {
95              phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
96  
97              fail( "Status check should have failed" );
98          }
99          catch ( ReleaseExecutionException e )
100         {
101             assertEquals( "check cause", NoSuchScmProviderException.class, e.getCause().getClass() );
102         }
103 
104         try
105         {
106             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
107 
108             fail( "Status check should have failed" );
109         }
110         catch ( ReleaseExecutionException e )
111         {
112             assertEquals( "check cause", NoSuchScmProviderException.class, e.getCause().getClass() );
113         }
114         
115         // verify
116         verify( scmManagerMock, times( 2 ) ).makeScmRepository( eq( "scm-url" ) );
117         verifyNoMoreInteractions( scmManagerMock );
118     }
119 
120     public void testScmRepositoryExceptionThrown()
121         throws Exception
122     {
123         // prepare
124         ReleaseDescriptor releaseDescriptor = new ReleaseDescriptor();
125         releaseDescriptor.setScmSourceUrl( "scm-url" );
126         releaseDescriptor.setWorkingDirectory( getTestFile( "target/test/checkout" ).getAbsolutePath() );
127 
128         ScmManager scmManagerMock = mock( ScmManager.class );
129         when( scmManagerMock.makeScmRepository( eq( "scm-url" ) ) ).thenThrow( new ScmRepositoryException( "..." ) );
130 
131         DefaultScmRepositoryConfigurator configurator =
132             (DefaultScmRepositoryConfigurator) lookup( ScmRepositoryConfigurator.ROLE );
133         configurator.setScmManager( scmManagerMock );
134 
135         // execute
136         try
137         {
138             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
139 
140             fail( "Status check should have failed" );
141         }
142         catch ( ReleaseScmRepositoryException e )
143         {
144             assertNull( "Check no additional cause", e.getCause() );
145         }
146 
147         try
148         {
149             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
150 
151             fail( "Status check should have failed" );
152         }
153         catch ( ReleaseScmRepositoryException e )
154         {
155             assertNull( "Check no additional cause", e.getCause() );
156         }
157         
158         // verify
159         verify( scmManagerMock, times( 2 ) ).makeScmRepository( eq( "scm-url" ) );
160         verifyNoMoreInteractions( scmManagerMock );
161     }
162 
163     public void testScmExceptionThrown()
164         throws Exception
165     {
166         // prepare
167         ReleaseDescriptor releaseDescriptor = new ReleaseDescriptor();
168         releaseDescriptor.setScmSourceUrl( "scm-url" );
169         releaseDescriptor.setWorkingDirectory( getTestFile( "target/test/checkout" ).getAbsolutePath() );
170 
171         ScmProvider scmProviderMock = mock( ScmProvider.class );
172         when( scmProviderMock.status( isA( ScmRepository.class ), isA( ScmFileSet.class ) ) ).thenThrow( new ScmException( "..." ) );
173 
174         ScmManagerStub stub = (ScmManagerStub) lookup( ScmManager.ROLE );
175         stub.setScmProvider( scmProviderMock );
176 
177         // execute
178         try
179         {
180             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
181 
182             fail( "Status check should have failed" );
183         }
184         catch ( ReleaseExecutionException e )
185         {
186             assertEquals( "check cause", ScmException.class, e.getCause().getClass() );
187         }
188 
189         try
190         {
191             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
192 
193             fail( "Status check should have failed" );
194         }
195         catch ( ReleaseExecutionException e )
196         {
197             assertEquals( "check cause", ScmException.class, e.getCause().getClass() );
198         }
199         
200         // verify
201         verify( scmProviderMock, times( 2 ) ).status( isA( ScmRepository.class ), isA( ScmFileSet.class ) );
202         verifyNoMoreInteractions( scmProviderMock );
203     }
204 
205     public void testScmResultFailure()
206         throws Exception
207     {
208         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
209 
210         ScmManager scmManager = (ScmManager) lookup( ScmManager.ROLE );
211         ScmProviderStub providerStub =
212             (ScmProviderStub) scmManager.getProviderByUrl( releaseDescriptor.getScmSourceUrl() );
213 
214         providerStub.setStatusScmResult( new StatusScmResult( "", "", "", false ) );
215 
216         try
217         {
218             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
219 
220             fail( "Status check should have failed" );
221         }
222         catch ( ReleaseScmCommandException e )
223         {
224             assertNull( "check no other cause", e.getCause() );
225         }
226 
227         try
228         {
229             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
230 
231             fail( "Status check should have failed" );
232         }
233         catch ( ReleaseScmCommandException e )
234         {
235             assertNull( "check no other cause", e.getCause() );
236         }
237     }
238 
239     public void testNoModifications()
240         throws Exception
241     {
242         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
243 
244         setChangedFiles( releaseDescriptor, Collections.<String>emptyList() );
245 
246         phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
247 
248         phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
249 
250         // successful execution is verification enough
251         assertTrue( true );
252     }
253 
254     public void testModificationsToExcludedFilesOnly()
255         throws Exception
256     {
257         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
258 
259         setChangedFiles( releaseDescriptor, Arrays.asList( new String[] { "release.properties", "pom.xml.backup",
260             "pom.xml.tag", "pom.xml.next" } ) );
261 
262         phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
263 
264         phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
265 
266         // successful execution is verification enough
267         assertTrue( true );
268     }
269     
270     // MRELEASE-645: Allow File/Directory Patterns for the checkModificationExcludes Option
271     public void testModificationsToCustomExcludedFilesOnly()
272         throws Exception
273     {
274         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
275         
276         releaseDescriptor.setCheckModificationExcludes( Collections.singletonList( "**/keep.me" ) );
277     
278         setChangedFiles( releaseDescriptor, Arrays.asList( new String[] { "release.properties", "pom.xml.backup",
279             "pom.xml.tag", "pom.xml.next", "keep.me", "src/app/keep.me", "config\\keep.me" } ) );
280     
281         assertEquals( ReleaseResult.SUCCESS, phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null ).getResultCode() );
282     
283         assertEquals( ReleaseResult.SUCCESS, phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null ).getResultCode() );
284     }
285 
286     public void testModificationsToPoms()
287         throws Exception
288     {
289         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
290 
291         setChangedFiles( releaseDescriptor, Arrays.asList( new String[] { "pom.xml", "module/pom.xml" } ) );
292 
293         try
294         {
295             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
296 
297             fail( "Status check should have failed" );
298         }
299         catch ( ReleaseFailureException e )
300         {
301             assertTrue( true );
302         }
303 
304         try
305         {
306             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
307 
308             fail( "Status check should have failed" );
309         }
310         catch ( ReleaseFailureException e )
311         {
312             assertTrue( true );
313         }
314     }
315 
316     public void testModificationsToIncludedFilesOnly()
317         throws Exception
318     {
319         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
320 
321         setChangedFiles( releaseDescriptor, Collections.singletonList( "something.txt" ) );
322 
323         try
324         {
325             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
326 
327             fail( "Status check should have failed" );
328         }
329         catch ( ReleaseFailureException e )
330         {
331             assertTrue( true );
332         }
333 
334         try
335         {
336             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
337 
338             fail( "Status check should have failed" );
339         }
340         catch ( ReleaseFailureException e )
341         {
342             assertTrue( true );
343         }
344     }
345 
346     public void testModificationsToIncludedAndExcludedFiles()
347         throws Exception
348     {
349         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
350 
351         setChangedFiles( releaseDescriptor, Arrays.asList( new String[] { "release.properties", "pom.xml.backup",
352             "pom.xml.tag", "pom.xml.release", "something.txt" } ) );
353 
354         try
355         {
356             phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null );
357 
358             fail( "Status check should have failed" );
359         }
360         catch ( ReleaseFailureException e )
361         {
362             assertTrue( true );
363         }
364 
365         try
366         {
367             phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null );
368 
369             fail( "Status check should have failed" );
370         }
371         catch ( ReleaseFailureException e )
372         {
373             assertTrue( true );
374         }
375     }
376     
377     public void testModificationsToAdditionalExcludedFiles()
378         throws Exception
379     {
380         ReleaseDescriptor releaseDescriptor = createReleaseDescriptor();
381         releaseDescriptor.setCheckModificationExcludes( Collections.singletonList( "something.*" ) );
382 
383         setChangedFiles( releaseDescriptor, Collections.singletonList( "something.txt" ) );
384 
385         assertEquals( ReleaseResult.SUCCESS,  phase.execute( releaseDescriptor, new DefaultReleaseEnvironment(), null ).getResultCode() );
386         
387         assertEquals( ReleaseResult.SUCCESS,  phase.simulate( releaseDescriptor, new DefaultReleaseEnvironment(), null ).getResultCode() );
388     }
389 
390     private void setChangedFiles( ReleaseDescriptor releaseDescriptor, List<String> changedFiles )
391         throws Exception
392     {
393         ScmManager scmManager = (ScmManager) lookup( ScmManager.ROLE );
394         ScmProviderStub providerStub =
395             (ScmProviderStub) scmManager.getProviderByUrl( releaseDescriptor.getScmSourceUrl() );
396 
397         providerStub.setStatusScmResult( new StatusScmResult( "", createScmFiles( changedFiles ) ) );
398     }
399 
400     private static List<ScmFile> createScmFiles( List<String> changedFiles )
401     {
402         List<ScmFile> files = new ArrayList<ScmFile>( changedFiles.size() );
403         for ( Iterator<String> i = changedFiles.iterator(); i.hasNext(); )
404         {
405             String fileName = i.next();
406             files.add( new ScmFile( fileName, ScmFileStatus.MODIFIED ) );
407         }
408         return files;
409     }
410 
411     private static ReleaseDescriptor createReleaseDescriptor()
412     {
413         ReleaseDescriptor releaseDescriptor = new ReleaseDescriptor();
414         releaseDescriptor.setScmSourceUrl( "scm:svn:file://localhost/tmp/scm-repo" );
415         releaseDescriptor.setWorkingDirectory( getTestFile( "target/test/checkout" ).getAbsolutePath() );
416         return releaseDescriptor;
417     }
418 }