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  package org.apache.maven.shared.release;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.Properties;
30  
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.scm.CommandParameters;
33  import org.apache.maven.scm.ScmException;
34  import org.apache.maven.scm.ScmFileSet;
35  import org.apache.maven.scm.ScmTag;
36  import org.apache.maven.scm.command.checkout.CheckOutScmResult;
37  import org.apache.maven.scm.manager.ScmManager;
38  import org.apache.maven.scm.manager.ScmManagerStub;
39  import org.apache.maven.scm.provider.ScmProvider;
40  import org.apache.maven.scm.provider.ScmProviderStub;
41  import org.apache.maven.scm.repository.ScmRepository;
42  import org.apache.maven.shared.release.config.ReleaseDescriptor;
43  import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
44  import org.apache.maven.shared.release.config.ReleaseDescriptorStore;
45  import org.apache.maven.shared.release.config.ReleaseDescriptorStoreException;
46  import org.apache.maven.shared.release.config.ReleaseDescriptorStoreStub;
47  import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
48  import org.apache.maven.shared.release.phase.ReleasePhase;
49  import org.apache.maven.shared.release.phase.ReleasePhaseStub;
50  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
51  import org.codehaus.plexus.testing.PlexusTest;
52  import org.codehaus.plexus.util.FileUtils;
53  import org.junit.jupiter.api.Test;
54  
55  import static org.codehaus.plexus.testing.PlexusExtension.getTestFile;
56  import static org.codehaus.plexus.testing.PlexusExtension.getTestPath;
57  import static org.junit.jupiter.api.Assertions.assertEquals;
58  import static org.junit.jupiter.api.Assertions.assertFalse;
59  import static org.junit.jupiter.api.Assertions.assertNull;
60  import static org.junit.jupiter.api.Assertions.assertTrue;
61  import static org.junit.jupiter.api.Assertions.fail;
62  import static org.mockito.ArgumentMatchers.any;
63  import static org.mockito.ArgumentMatchers.anyString;
64  import static org.mockito.Mockito.doThrow;
65  import static org.mockito.Mockito.mock;
66  import static org.mockito.Mockito.times;
67  import static org.mockito.Mockito.verify;
68  import static org.mockito.Mockito.verifyNoMoreInteractions;
69  import static org.mockito.Mockito.when;
70  
71  /**
72   * Test the default release manager.
73   *
74   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
75   */
76  @PlexusTest
77  class DefaultReleaseManagerTest {
78  
79      @Inject
80      private ReleaseDescriptorStoreStub configStore;
81  
82      @Inject
83      @Named("test")
84      private ReleaseManager releaseManagerTest;
85  
86      @Inject
87      @Named("step1")
88      private ReleasePhase phaseStep1;
89  
90      @Inject
91      @Named("step2")
92      private ReleasePhase phaseStep2;
93  
94      @Inject
95      @Named("step3")
96      private ReleasePhase phaseStep3;
97  
98      @Inject
99      @Named("rollbackPhase1")
100     private ReleasePhase phaseRollbackPhase1;
101 
102     @Inject
103     @Named("updateVersionsPhase1")
104     private ReleasePhase phaseUpdateVersionsPhase1;
105 
106     @Inject
107     @Named("branch1")
108     private ReleasePhase phaseBranch1;
109 
110     @Inject
111     private ScmManager scmManager;
112 
113     @Test
114     void testPrepareNoCompletedPhase() throws Exception {
115         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
116         builder.setCompletedPhase(null);
117 
118         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
119         prepareRequest.setReleaseDescriptorBuilder(builder);
120         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
121         prepareRequest.setUserProperties(new Properties());
122 
123         releaseManagerTest.prepare(prepareRequest);
124 
125         assertTrue(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 executed");
126         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
127         assertTrue(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 executed");
128         assertFalse(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 not simulated");
129         assertTrue(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 executed");
130         assertFalse(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 not simulated");
131     }
132 
133     @Test
134     void testPrepareCompletedPhase() throws Exception {
135         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
136         builder.setCompletedPhase("step1");
137 
138         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
139         prepareRequest.setReleaseDescriptorBuilder(builder);
140         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
141         prepareRequest.setUserProperties(new Properties());
142 
143         releaseManagerTest.prepare(prepareRequest);
144 
145         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 not executed");
146         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
147         assertTrue(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 executed");
148         assertFalse(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 not simulated");
149         assertTrue(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 executed");
150         assertFalse(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 not simulated");
151     }
152 
153     @Test
154     void testPrepareCompletedPhaseNoResume() throws Exception {
155         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
156         builder.setCompletedPhase("step1");
157 
158         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
159         prepareRequest.setReleaseDescriptorBuilder(builder);
160         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
161         prepareRequest.setDryRun(false);
162         prepareRequest.setResume(false);
163         prepareRequest.setUserProperties(new Properties());
164 
165         releaseManagerTest.prepare(prepareRequest);
166 
167         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 executed");
168         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
169         assertTrue(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 executed");
170         assertFalse(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 not simulated");
171         assertTrue(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 executed");
172         assertFalse(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 not simulated");
173     }
174 
175     @Test
176     void testPrepareCompletedAllPhases() throws Exception {
177         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
178         builder.setCompletedPhase("step3");
179 
180         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
181         prepareRequest.setReleaseDescriptorBuilder(builder);
182         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
183         prepareRequest.setUserProperties(new Properties());
184 
185         releaseManagerTest.prepare(prepareRequest);
186 
187         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 not executed");
188         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
189         assertFalse(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 not executed");
190         assertFalse(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 not simulated");
191         assertFalse(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 not executed");
192         assertFalse(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 not simulated");
193     }
194 
195     @Test
196     void testPrepareInvalidCompletedPhase() throws Exception {
197         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
198         builder.setCompletedPhase("foo");
199 
200         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
201         prepareRequest.setReleaseDescriptorBuilder(builder);
202         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
203         prepareRequest.setUserProperties(new Properties());
204 
205         releaseManagerTest.prepare(prepareRequest);
206 
207         assertTrue(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 executed");
208         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
209         assertTrue(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 executed");
210         assertFalse(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 not simulated");
211         assertTrue(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 executed");
212         assertFalse(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 not simulated");
213     }
214 
215     @Test
216     void testPrepareSimulateNoCompletedPhase() throws Exception {
217         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
218         builder.setCompletedPhase(null);
219 
220         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
221         prepareRequest.setReleaseDescriptorBuilder(builder);
222         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
223         prepareRequest.setDryRun(true);
224         prepareRequest.setResume(true);
225         prepareRequest.setUserProperties(new Properties());
226 
227         releaseManagerTest.prepare(prepareRequest);
228 
229         assertTrue(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 simulated");
230         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 not executed");
231         assertTrue(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 simulated");
232         assertFalse(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 not executed");
233         assertTrue(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 simulated");
234         assertFalse(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 not executed");
235     }
236 
237     @Test
238     void testPrepareSimulateCompletedPhase() throws Exception {
239         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
240         builder.setCompletedPhase("step1");
241 
242         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
243         prepareRequest.setReleaseDescriptorBuilder(builder);
244         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
245         prepareRequest.setDryRun(true);
246         prepareRequest.setResume(true);
247         prepareRequest.setUserProperties(new Properties());
248 
249         releaseManagerTest.prepare(prepareRequest);
250 
251         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
252         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 not executed");
253         assertTrue(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 simulated");
254         assertFalse(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 not executed");
255         assertTrue(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 simulated");
256         assertFalse(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 not executed");
257     }
258 
259     @Test
260     void testPrepareSimulateCompletedAllPhases() throws Exception {
261         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
262         builder.setCompletedPhase("step3");
263 
264         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
265         prepareRequest.setReleaseDescriptorBuilder(builder);
266         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
267         prepareRequest.setDryRun(true);
268         prepareRequest.setResume(true);
269         prepareRequest.setUserProperties(new Properties());
270 
271         releaseManagerTest.prepare(prepareRequest);
272 
273         assertFalse(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 not simulated");
274         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 not executed");
275         assertFalse(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 not simulated");
276         assertFalse(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 not executed");
277         assertFalse(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 not simulated");
278         assertFalse(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 not executed");
279     }
280 
281     @Test
282     void testPrepareSimulateInvalidCompletedPhase() throws Exception {
283         ReleaseDescriptorBuilder builder = configStore.getReleaseConfiguration();
284         builder.setCompletedPhase("foo");
285 
286         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
287         prepareRequest.setReleaseDescriptorBuilder(builder);
288         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
289         prepareRequest.setDryRun(true);
290         prepareRequest.setResume(true);
291         prepareRequest.setUserProperties(new Properties());
292 
293         releaseManagerTest.prepare(prepareRequest);
294 
295         assertTrue(((ReleasePhaseStub) phaseStep1).isSimulated(), "step1 simulated");
296         assertFalse(((ReleasePhaseStub) phaseStep1).isExecuted(), "step1 not executed");
297         assertTrue(((ReleasePhaseStub) phaseStep2).isSimulated(), "step2 simulated");
298         assertFalse(((ReleasePhaseStub) phaseStep2).isExecuted(), "step2 not executed");
299         assertTrue(((ReleasePhaseStub) phaseStep3).isSimulated(), "step3 simulated");
300         assertFalse(((ReleasePhaseStub) phaseStep3).isExecuted(), "step3 not executed");
301     }
302 
303     @Test
304     void testReleaseConfigurationStoreReadFailure() throws Exception {
305         // prepare
306         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
307         builder.setScmSourceUrl("scm-url");
308         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
309 
310         ReleaseDescriptorStore configStoreMock = mock(ReleaseDescriptorStore.class);
311         when(configStoreMock.read(builder))
312                 .thenThrow(new ReleaseDescriptorStoreException("message", new IOException("ioExceptionMsg")));
313 
314         ((DefaultReleaseManager) releaseManagerTest).setConfigStore(configStoreMock);
315 
316         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
317         prepareRequest.setReleaseDescriptorBuilder(builder);
318         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
319         prepareRequest.setUserProperties(new Properties());
320 
321         // execute
322         try {
323             releaseManagerTest.prepare(prepareRequest);
324             fail("Should have failed to read configuration");
325         } catch (ReleaseExecutionException e) {
326             // good
327             assertEquals(ReleaseDescriptorStoreException.class, e.getCause().getClass(), "check cause");
328         }
329 
330         // verify
331         verify(configStoreMock).read(builder);
332         verifyNoMoreInteractions(configStoreMock);
333     }
334 
335     @Test
336     void testReleaseConfigurationStoreWriteFailure() throws Exception {
337         // prepare
338         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
339         builder.setScmSourceUrl("scm-url");
340         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
341 
342         ReleaseDescriptorStore configStoreMock = mock(ReleaseDescriptorStore.class);
343         doThrow(new ReleaseDescriptorStoreException("message", new IOException("ioExceptionMsg")))
344                 .when(configStoreMock)
345                 .write(any(ReleaseDescriptor.class));
346 
347         ((DefaultReleaseManager) releaseManagerTest).setConfigStore(configStoreMock);
348 
349         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
350         prepareRequest.setReleaseDescriptorBuilder(builder);
351         prepareRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
352         prepareRequest.setDryRun(false);
353         prepareRequest.setResume(false);
354         prepareRequest.setUserProperties(new Properties());
355 
356         // execute
357         try {
358             releaseManagerTest.prepare(prepareRequest);
359             fail("Should have failed to read configuration");
360         } catch (ReleaseExecutionException e) {
361             // good
362             assertEquals(ReleaseDescriptorStoreException.class, e.getCause().getClass(), "check cause");
363         }
364 
365         // verify
366         verify(configStoreMock).write(any(ReleaseDescriptor.class));
367         verifyNoMoreInteractions(configStoreMock);
368     }
369 
370     @Test
371     void testReleaseConfigurationStoreClean() throws Exception {
372         // prepare
373         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
374         builder.setScmSourceUrl("scm-url");
375         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
376 
377         ReleaseDescriptorStore configStoreMock = mock(ReleaseDescriptorStore.class);
378 
379         ((DefaultReleaseManager) releaseManagerTest).setConfigStore(configStoreMock);
380 
381         ReleaseCleanRequest cleanRequest = new ReleaseCleanRequest();
382         cleanRequest.setReleaseDescriptorBuilder(builder);
383 
384         // execute
385         releaseManagerTest.clean(cleanRequest);
386 
387         // verify
388         assertTrue(((ReleasePhaseStub) phaseStep1).isCleaned(), "step1 not cleaned");
389 
390         assertTrue(((ReleasePhaseStub) phaseStep2).isCleaned(), "step2 not cleaned");
391 
392         assertTrue(((ReleasePhaseStub) phaseStep3).isCleaned(), "step3 not cleaned");
393 
394         //        assertTrue("branch1 not cleaned", phaseBranch1.isCleaned());
395 
396         verify(configStoreMock).delete(any(ReleaseDescriptor.class));
397         verifyNoMoreInteractions(configStoreMock);
398     }
399 
400     private static List<MavenProject> createReactorProjects() throws IOException {
401         MavenProject project = new MavenProject();
402 
403         File projectFile = getTestFile("target/dummy-project/pom.xml");
404         if (!projectFile.exists()) {
405             projectFile.getParentFile().mkdirs();
406             projectFile.createNewFile();
407         }
408         project.setFile(projectFile);
409         return Collections.singletonList(project);
410     }
411 
412     @Test
413     void testReleasePerformWithResult() throws Exception {
414 
415         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
416         builder.setScmSourceUrl("scm-url");
417         File checkoutDirectory = getTestFile("target/checkout-directory");
418         builder.setCheckoutDirectory(checkoutDirectory.getAbsolutePath());
419         builder.setWorkingDirectory(getTestPath("target/dummy-project"));
420 
421         ReleasePerformRequest performRequest = new ReleasePerformRequest();
422         performRequest.setReleaseDescriptorBuilder(builder);
423         performRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
424         performRequest.setReactorProjects(createReactorProjects());
425 
426         ReleaseResult result = releaseManagerTest.performWithResult(performRequest);
427 
428         assertTrue(result.getOutput().length() > 0);
429     }
430 
431     @Test
432     void testReleaseConfigurationStoreReadFailureOnPerform() throws Exception {
433         // prepare
434         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
435         builder.setScmSourceUrl("scm-url");
436         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
437 
438         ReleaseDescriptorStore configStoreMock = mock(ReleaseDescriptorStore.class);
439         when(configStoreMock.read(builder))
440                 .thenThrow(new ReleaseDescriptorStoreException("message", new IOException("ioExceptionMsg")));
441 
442         ((DefaultReleaseManager) releaseManagerTest).setConfigStore(configStoreMock);
443 
444         ReleasePerformRequest performRequest = new ReleasePerformRequest();
445         performRequest.setReleaseDescriptorBuilder(builder);
446         performRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
447 
448         // execute
449         try {
450             builder.setUseReleaseProfile(false);
451 
452             releaseManagerTest.perform(performRequest);
453             fail("Should have failed to read configuration");
454         } catch (ReleaseExecutionException e) {
455             // good
456             assertEquals(ReleaseDescriptorStoreException.class, e.getCause().getClass(), "check cause");
457         }
458 
459         // verify
460         verify(configStoreMock).read(builder);
461         verifyNoMoreInteractions(configStoreMock);
462     }
463 
464     @Test
465     void testReleasePerformWithIncompletePrepare() throws Exception {
466         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
467         builder.setScmSourceUrl("scm-url");
468         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
469 
470         ReleaseDescriptorStoreStub configStore = new ReleaseDescriptorStoreStub();
471         builder.setCompletedPhase("scm-tag");
472         ((DefaultReleaseManager) releaseManagerTest).setConfigStore(configStore);
473 
474         ReleasePerformRequest performRequest = new ReleasePerformRequest();
475         performRequest.setReleaseDescriptorBuilder(builder);
476         performRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
477 
478         try {
479             builder.setUseReleaseProfile(false);
480 
481             releaseManagerTest.perform(performRequest);
482             fail("Should have failed to perform");
483         } catch (ReleaseFailureException e) {
484             // good
485             assertTrue(true);
486         }
487     }
488 
489     // MRELEASE-758: release:perform no longer removes release.properties
490     @Test
491     void testPerformWithDefaultClean() throws Exception {
492         // prepare
493         ReleasePerformRequest performRequest = new ReleasePerformRequest();
494         performRequest.setDryRun(true);
495         performRequest.setReactorProjects(createReactorProjects());
496 
497         ReleaseManagerListener managerListener = mock(ReleaseManagerListener.class);
498         performRequest.setReleaseManagerListener(managerListener);
499 
500         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
501         builder.setScmSourceUrl("scm-url");
502         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
503         performRequest.setReleaseDescriptorBuilder(builder);
504 
505         // test
506         releaseManagerTest.perform(performRequest);
507 
508         // verify
509         verify(managerListener).phaseStart("verify-completed-prepare-phases");
510         verify(managerListener).phaseStart("checkout-project-from-scm");
511         verify(managerListener).phaseStart("run-perform-goals");
512         verify(managerListener, times(3)).phaseEnd();
513 
514         // not part of actual test, but required to confirm 'no more interactions'
515         verify(managerListener).goalStart(anyString(), any());
516         verify(managerListener).goalEnd();
517 
518         verifyNoMoreInteractions(managerListener);
519     }
520 
521     @Test
522     void testNoScmUrlPerform() throws Exception {
523         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
524         builder.setWorkingDirectory(getTestFile("target/test/checkout").getAbsolutePath());
525 
526         ReleasePerformRequest performRequest = new ReleasePerformRequest();
527         performRequest.setReleaseDescriptorBuilder(builder);
528         performRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
529 
530         try {
531             builder.setUseReleaseProfile(false);
532 
533             releaseManagerTest.perform(performRequest);
534 
535             fail("perform should have failed");
536         } catch (ReleaseFailureException e) {
537             assertNull(e.getCause(), "check no cause");
538         }
539     }
540 
541     @Test
542     void testScmExceptionThrown() throws Exception {
543         // prepare
544         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
545         builder.setScmSourceUrl("scm-url");
546         File checkoutDirectory = getTestFile("target/checkout-directory");
547         builder.setCheckoutDirectory(checkoutDirectory.getAbsolutePath());
548 
549         ScmProvider scmProviderMock = mock(ScmProvider.class);
550         when(scmProviderMock.checkOut(
551                         any(ScmRepository.class),
552                         any(ScmFileSet.class),
553                         any(ScmTag.class),
554                         any(CommandParameters.class)))
555                 .thenThrow(new ScmException("..."));
556 
557         ((ScmManagerStub) scmManager).setScmProvider(scmProviderMock);
558 
559         ReleasePerformRequest performRequest = new ReleasePerformRequest();
560         performRequest.setReleaseDescriptorBuilder(builder);
561         performRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
562         performRequest.setReactorProjects(createReactorProjects());
563 
564         // execute
565         try {
566             releaseManagerTest.perform(performRequest);
567 
568             fail("commit should have failed");
569         } catch (ReleaseExecutionException e) {
570             assertEquals(ScmException.class, e.getCause().getClass(), "check cause");
571         }
572 
573         // verify
574         verify(scmProviderMock)
575                 .checkOut(
576                         any(ScmRepository.class), any(ScmFileSet.class),
577                         any(ScmTag.class), any(CommandParameters.class));
578         verifyNoMoreInteractions(scmProviderMock);
579     }
580 
581     @Test
582     void testScmResultFailure() throws Exception {
583 
584         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
585         builder.setScmSourceUrl("scm-url");
586         File checkoutDirectory = getTestFile("target/checkout-directory");
587         builder.setCheckoutDirectory(checkoutDirectory.getAbsolutePath());
588         builder.setWorkingDirectory(getTestPath("target/dummy-project"));
589 
590         ScmProviderStub providerStub = (ScmProviderStub) scmManager.getProviderByUrl("scm-url");
591 
592         providerStub.setCheckOutScmResult(new CheckOutScmResult("", "", "", false));
593 
594         ReleasePerformRequest performRequest = new ReleasePerformRequest();
595         performRequest.setReleaseDescriptorBuilder(builder);
596         performRequest.setReleaseEnvironment(new DefaultReleaseEnvironment());
597         performRequest.setReactorProjects(createReactorProjects());
598 
599         try {
600             releaseManagerTest.perform(performRequest);
601 
602             fail("commit should have failed");
603         } catch (ReleaseScmCommandException e) {
604             assertNull(e.getCause(), "check no other cause");
605         }
606     }
607 
608     // MRELEASE-1042
609     @Test
610     void testKeepProfilesOnPerform() throws Exception {
611         // prepare
612         ReleasePerformRequest performRequest = new ReleasePerformRequest();
613         performRequest.setDryRun(true);
614         performRequest.setReactorProjects(createReactorProjects());
615 
616         ReleaseManagerListener managerListener = mock(ReleaseManagerListener.class);
617         performRequest.setReleaseManagerListener(managerListener);
618 
619         ReleaseDescriptorBuilder builder = new ReleaseDescriptorBuilder();
620         builder.setActivateProfiles(Arrays.asList("aProfile", "anotherOne"));
621         builder.setWorkingDirectory(getTestFile("target/working-directory").getAbsolutePath());
622         performRequest.setReleaseDescriptorBuilder(builder);
623 
624         ReleaseDescriptorBuilder secondBuilder = new ReleaseDescriptorBuilder();
625         secondBuilder.setActivateProfiles(Arrays.asList("aProfile", "bProfile"));
626         secondBuilder.setScmSourceUrl("scm-url");
627         ReleaseDescriptorStore configStoreMock = mock(ReleaseDescriptorStore.class);
628         when(configStoreMock.read(any(ReleaseDescriptorBuilder.class))).thenReturn(secondBuilder);
629         ((DefaultReleaseManager) releaseManagerTest).setConfigStore(configStoreMock);
630 
631         // test
632         ReleaseResult result = releaseManagerTest.performWithResult(performRequest);
633 
634         // verify
635         assertTrue(result.getOutput().contains("-P aProfile,bProfile,anotherOne"));
636     }
637 
638     @Test
639     void testDetermineWorkingDirectory() throws Exception {
640         DefaultReleaseManager defaultReleaseManager = new DefaultReleaseManager(
641                 Collections.emptyMap(), Collections.emptyMap(), mock(ReleaseDescriptorStore.class));
642 
643         File checkoutDir = getTestFile("target/checkout");
644         FileUtils.forceDelete(checkoutDir);
645         checkoutDir.mkdirs();
646 
647         File projectDir = getTestFile("target/checkout/my/project");
648         projectDir.mkdirs();
649 
650         // only checkout dir
651         assertEquals(checkoutDir, defaultReleaseManager.determineWorkingDirectory(checkoutDir, ""));
652         assertEquals(checkoutDir, defaultReleaseManager.determineWorkingDirectory(checkoutDir, null));
653 
654         // checkout dir and relative path project dir
655         assertEquals(projectDir, defaultReleaseManager.determineWorkingDirectory(checkoutDir, "my/project"));
656         assertEquals(projectDir, defaultReleaseManager.determineWorkingDirectory(checkoutDir, "my/project/"));
657         assertEquals(
658                 projectDir,
659                 defaultReleaseManager.determineWorkingDirectory(checkoutDir, "my" + File.separator + "project"));
660 
661         FileUtils.forceDelete(checkoutDir);
662     }
663 
664     // MRELEASE-761
665     @Test
666     void testRollbackCall() throws Exception {
667 
668         ReleaseRollbackRequest rollbackRequest = new ReleaseRollbackRequest();
669         rollbackRequest.setReleaseDescriptorBuilder(configStore.getReleaseConfiguration());
670 
671         releaseManagerTest.rollback(rollbackRequest);
672 
673         assertTrue(((ReleasePhaseStub) phaseRollbackPhase1).isExecuted(), "rollbackPhase1 executed");
674     }
675 
676     // MRELEASE-765
677     @Test
678     void testUpdateVersionsCall() throws Exception {
679 
680         ReleaseUpdateVersionsRequest updateVersionsRequest = new ReleaseUpdateVersionsRequest();
681         updateVersionsRequest.setReleaseDescriptorBuilder(configStore.getReleaseConfiguration());
682         updateVersionsRequest.setUserProperties(new Properties());
683 
684         releaseManagerTest.updateVersions(updateVersionsRequest);
685 
686         assertTrue(((ReleasePhaseStub) phaseUpdateVersionsPhase1).isExecuted(), "updateVersionsPhase1 executed");
687     }
688 }