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