1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.lifecycle;
20
21 import javax.inject.Inject;
22
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.List;
29
30 import org.apache.maven.AbstractCoreMavenComponentTestCase;
31 import org.apache.maven.api.xml.XmlNode;
32 import org.apache.maven.execution.MavenSession;
33 import org.apache.maven.execution.MojoExecutionEvent;
34 import org.apache.maven.execution.MojoExecutionListener;
35 import org.apache.maven.execution.ProjectDependencyGraph;
36 import org.apache.maven.execution.ProjectExecutionEvent;
37 import org.apache.maven.execution.ProjectExecutionListener;
38 import org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator;
39 import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
40 import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
41 import org.apache.maven.lifecycle.internal.LifecycleTask;
42 import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
43 import org.apache.maven.lifecycle.internal.TaskSegment;
44 import org.apache.maven.model.Plugin;
45 import org.apache.maven.plugin.MojoExecution;
46 import org.apache.maven.plugin.MojoExecutionException;
47 import org.apache.maven.plugin.MojoNotFoundException;
48 import org.apache.maven.plugin.descriptor.MojoDescriptor;
49 import org.apache.maven.project.MavenProject;
50 import org.junit.jupiter.api.Test;
51
52 import static org.hamcrest.MatcherAssert.assertThat;
53 import static org.hamcrest.Matchers.hasSize;
54 import static org.junit.jupiter.api.Assertions.assertEquals;
55 import static org.junit.jupiter.api.Assertions.assertNotNull;
56 import static org.junit.jupiter.api.Assertions.assertNull;
57 import static org.junit.jupiter.api.Assertions.assertThrows;
58
59 class LifecycleExecutorTest extends AbstractCoreMavenComponentTestCase {
60 @Inject
61 private DefaultLifecycleExecutor lifecycleExecutor;
62
63 @Inject
64 private DefaultLifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator;
65
66 @Inject
67 private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
68
69 @Inject
70 private MojoDescriptorCreator mojoDescriptorCreator;
71
72 protected String getProjectsDirectory() {
73 return "src/test/projects/lifecycle-executor";
74 }
75
76
77
78
79
80 @Test
81 void testCalculationOfBuildPlanWithIndividualTaskWherePluginIsSpecifiedInThePom() throws Exception {
82
83
84 File pom = getProject("project-basic");
85 MavenSession session = createMavenSession(pom);
86 assertEquals("project-basic", session.getCurrentProject().getArtifactId());
87 assertEquals("1.0", session.getCurrentProject().getVersion());
88 List<MojoExecution> executionPlan = getExecutions(calculateExecutionPlan(session, "resources:resources"));
89 assertEquals(1, executionPlan.size());
90 MojoExecution mojoExecution = executionPlan.get(0);
91 assertNotNull(mojoExecution);
92 assertEquals(
93 "org.apache.maven.plugins",
94 mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId());
95 assertEquals(
96 "maven-resources-plugin",
97 mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId());
98 assertEquals(
99 "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion());
100 }
101
102 @Test
103 void testCalculationOfBuildPlanWithIndividualTaskOfTheCleanLifecycle() throws Exception {
104
105
106 File pom = getProject("project-basic");
107 MavenSession session = createMavenSession(pom);
108 assertEquals("project-basic", session.getCurrentProject().getArtifactId());
109 assertEquals("1.0", session.getCurrentProject().getVersion());
110 List<MojoExecution> executionPlan = getExecutions(calculateExecutionPlan(session, "clean"));
111 assertEquals(1, executionPlan.size());
112 MojoExecution mojoExecution = executionPlan.get(0);
113 assertNotNull(mojoExecution);
114 assertEquals(
115 "org.apache.maven.plugins",
116 mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId());
117 assertEquals(
118 "maven-clean-plugin",
119 mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId());
120 assertEquals(
121 "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion());
122 }
123
124 @Test
125 void testCalculationOfBuildPlanWithIndividualTaskOfTheCleanCleanGoal() throws Exception {
126
127
128 File pom = getProject("project-basic");
129 MavenSession session = createMavenSession(pom);
130 assertEquals("project-basic", session.getCurrentProject().getArtifactId());
131 assertEquals("1.0", session.getCurrentProject().getVersion());
132 List<MojoExecution> executionPlan = getExecutions(calculateExecutionPlan(session, "clean:clean"));
133 assertEquals(1, executionPlan.size());
134 MojoExecution mojoExecution = executionPlan.get(0);
135 assertNotNull(mojoExecution);
136 assertEquals(
137 "org.apache.maven.plugins",
138 mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId());
139 assertEquals(
140 "maven-clean-plugin",
141 mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId());
142 assertEquals(
143 "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion());
144 }
145
146 List<MojoExecution> getExecutions(MavenExecutionPlan mavenExecutionPlan) {
147 List<MojoExecution> result = new ArrayList<>();
148 for (ExecutionPlanItem executionPlanItem : mavenExecutionPlan) {
149 result.add(executionPlanItem.getMojoExecution());
150 }
151 return result;
152 }
153
154
155 public void testCalculationOfBuildPlanTasksOfTheCleanLifecycleAndTheInstallLifecycle() throws Exception {
156 File pom = getProject("project-with-additional-lifecycle-elements");
157 MavenSession session = createMavenSession(pom);
158 assertEquals(
159 "project-with-additional-lifecycle-elements",
160 session.getCurrentProject().getArtifactId());
161 assertEquals("1.0", session.getCurrentProject().getVersion());
162 List<MojoExecution> executionPlan = getExecutions(calculateExecutionPlan(session, "clean", "install"));
163
164
165
166
167
168
169
170
171
172
173
174
175 assertEquals(10, executionPlan.size());
176
177 assertEquals("clean:clean", executionPlan.get(0).getMojoDescriptor().getFullGoalName());
178 assertEquals(
179 "resources:resources", executionPlan.get(1).getMojoDescriptor().getFullGoalName());
180 assertEquals(
181 "compiler:compile", executionPlan.get(2).getMojoDescriptor().getFullGoalName());
182 assertEquals(
183 "it:generate-metadata", executionPlan.get(3).getMojoDescriptor().getFullGoalName());
184 assertEquals(
185 "resources:testResources",
186 executionPlan.get(4).getMojoDescriptor().getFullGoalName());
187 assertEquals(
188 "compiler:testCompile", executionPlan.get(5).getMojoDescriptor().getFullGoalName());
189 assertEquals(
190 "it:generate-test-metadata",
191 executionPlan.get(6).getMojoDescriptor().getFullGoalName());
192 assertEquals("surefire:test", executionPlan.get(7).getMojoDescriptor().getFullGoalName());
193 assertEquals("jar:jar", executionPlan.get(8).getMojoDescriptor().getFullGoalName());
194 assertEquals("install:install", executionPlan.get(9).getMojoDescriptor().getFullGoalName());
195 }
196
197
198 public void testCalculationOfBuildPlanWithMultipleExecutionsOfModello() throws Exception {
199 File pom = getProject("project-with-multiple-executions");
200 MavenSession session = createMavenSession(pom);
201 assertEquals(
202 "project-with-multiple-executions", session.getCurrentProject().getArtifactId());
203 assertEquals("1.0.1", session.getCurrentProject().getVersion());
204
205 MavenExecutionPlan plan = calculateExecutionPlan(session, "clean", "install");
206
207 List<MojoExecution> executions = getExecutions(plan);
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 assertEquals(16, executions.size());
228
229 assertEquals("clean:clean", executions.get(0).getMojoDescriptor().getFullGoalName());
230 assertEquals("it:xpp3-writer", executions.get(1).getMojoDescriptor().getFullGoalName());
231 assertEquals("it:java", executions.get(2).getMojoDescriptor().getFullGoalName());
232 assertEquals("it:xpp3-reader", executions.get(3).getMojoDescriptor().getFullGoalName());
233 assertEquals("it:xpp3-writer", executions.get(4).getMojoDescriptor().getFullGoalName());
234 assertEquals("it:java", executions.get(5).getMojoDescriptor().getFullGoalName());
235 assertEquals("it:xpp3-reader", executions.get(6).getMojoDescriptor().getFullGoalName());
236 assertEquals(
237 "resources:resources", executions.get(7).getMojoDescriptor().getFullGoalName());
238 assertEquals("compiler:compile", executions.get(8).getMojoDescriptor().getFullGoalName());
239 assertEquals("plugin:descriptor", executions.get(9).getMojoDescriptor().getFullGoalName());
240 assertEquals(
241 "resources:testResources",
242 executions.get(10).getMojoDescriptor().getFullGoalName());
243 assertEquals(
244 "compiler:testCompile", executions.get(11).getMojoDescriptor().getFullGoalName());
245 assertEquals("surefire:test", executions.get(12).getMojoDescriptor().getFullGoalName());
246 assertEquals("jar:jar", executions.get(13).getMojoDescriptor().getFullGoalName());
247 assertEquals(
248 "plugin:addPluginArtifactMetadata",
249 executions.get(14).getMojoDescriptor().getFullGoalName());
250 assertEquals("install:install", executions.get(15).getMojoDescriptor().getFullGoalName());
251
252 assertEquals(
253 "src/main/mdo/remote-resources.mdo",
254 new MojoExecutionXPathContainer(executions.get(1)).getValue("configuration/models[1]/model"));
255 assertEquals(
256 "src/main/mdo/supplemental-model.mdo",
257 new MojoExecutionXPathContainer(executions.get(4)).getValue("configuration/models[1]/model"));
258 }
259
260 @Test
261 void testLifecycleQueryingUsingADefaultLifecyclePhase() throws Exception {
262 File pom = getProject("project-with-additional-lifecycle-elements");
263 MavenSession session = createMavenSession(pom);
264 assertEquals(
265 "project-with-additional-lifecycle-elements",
266 session.getCurrentProject().getArtifactId());
267 assertEquals("1.0", session.getCurrentProject().getVersion());
268 List<MojoExecution> executionPlan = getExecutions(calculateExecutionPlan(session, "package"));
269
270
271
272
273
274
275
276
277
278
279 assertEquals(8, executionPlan.size());
280
281 assertEquals(
282 "resources:resources", executionPlan.get(0).getMojoDescriptor().getFullGoalName());
283 assertEquals(
284 "compiler:compile", executionPlan.get(1).getMojoDescriptor().getFullGoalName());
285 assertEquals(
286 "it:generate-metadata", executionPlan.get(2).getMojoDescriptor().getFullGoalName());
287 assertEquals(
288 "resources:testResources",
289 executionPlan.get(3).getMojoDescriptor().getFullGoalName());
290 assertEquals(
291 "compiler:testCompile", executionPlan.get(4).getMojoDescriptor().getFullGoalName());
292 assertEquals(
293 "it:generate-test-metadata",
294 executionPlan.get(5).getMojoDescriptor().getFullGoalName());
295 assertEquals("surefire:test", executionPlan.get(6).getMojoDescriptor().getFullGoalName());
296 assertEquals("jar:jar", executionPlan.get(7).getMojoDescriptor().getFullGoalName());
297 }
298
299 @Test
300 void testLifecyclePluginsRetrievalForDefaultLifecycle() throws Exception {
301 List<Plugin> plugins = new ArrayList<>(lifecycleExecutor.getPluginsBoundByDefaultToAllLifecycles("jar"));
302
303 assertThat(plugins.toString(), plugins, hasSize(9));
304 }
305
306 @Test
307 void testPluginConfigurationCreation() throws Exception {
308 File pom = getProject("project-with-additional-lifecycle-elements");
309 MavenSession session = createMavenSession(pom);
310 MojoDescriptor mojoDescriptor = mojoDescriptorCreator.getMojoDescriptor(
311 "org.apache.maven.its.plugins:maven-it-plugin:0.1:java", session, session.getCurrentProject());
312 XmlNode dom = MojoDescriptorCreator.convert(mojoDescriptor).getDom();
313 System.out.println(dom);
314 }
315
316 MavenExecutionPlan calculateExecutionPlan(MavenSession session, String... tasks) throws Exception {
317 List<TaskSegment> taskSegments =
318 lifeCycleTaskSegmentCalculator.calculateTaskSegments(session, Arrays.asList(tasks));
319
320 TaskSegment mergedSegment = new TaskSegment(false);
321
322 for (TaskSegment taskSegment : taskSegments) {
323 mergedSegment.getTasks().addAll(taskSegment.getTasks());
324 }
325
326 return lifeCycleExecutionPlanCalculator.calculateExecutionPlan(
327 session, session.getCurrentProject(), mergedSegment.getTasks());
328 }
329
330 @Test
331 void testInvalidGoalName() throws Exception {
332 File pom = getProject("project-basic");
333 MavenSession session = createMavenSession(pom);
334 MojoNotFoundException e = assertThrows(
335 MojoNotFoundException.class,
336 () -> getExecutions(calculateExecutionPlan(session, "resources:")),
337 "expected a MojoNotFoundException");
338 assertEquals("", e.getGoal());
339
340 e = assertThrows(
341 MojoNotFoundException.class,
342 () -> getExecutions(calculateExecutionPlan(
343 session, "org.apache.maven.plugins:maven-resources-plugin:0.1:resources:toomany")),
344 "expected a MojoNotFoundException");
345 assertEquals("resources:toomany", e.getGoal());
346 }
347
348 @Test
349 void testPluginPrefixRetrieval() throws Exception {
350 File pom = getProject("project-basic");
351 MavenSession session = createMavenSession(pom);
352 Plugin plugin = mojoDescriptorCreator.findPluginForPrefix("resources", session);
353 assertEquals("org.apache.maven.plugins", plugin.getGroupId());
354 assertEquals("maven-resources-plugin", plugin.getArtifactId());
355 }
356
357
358
359 @Test
360 void testFindingPluginPrefixForCleanClean() throws Exception {
361 File pom = getProject("project-basic");
362 MavenSession session = createMavenSession(pom);
363 Plugin plugin = mojoDescriptorCreator.findPluginForPrefix("clean", session);
364 assertNotNull(plugin);
365 }
366
367 @Test
368 void testSetupMojoExecution() throws Exception {
369 File pom = getProject("mojo-configuration");
370
371 MavenSession session = createMavenSession(pom);
372
373 LifecycleTask task = new LifecycleTask("generate-sources");
374 MavenExecutionPlan executionPlan = lifeCycleExecutionPlanCalculator.calculateExecutionPlan(
375 session, session.getCurrentProject(), Arrays.asList((Object) task), false);
376
377 MojoExecution execution = executionPlan.getMojoExecutions().get(0);
378 assertEquals("maven-it-plugin", execution.getArtifactId(), execution.toString());
379 assertNull(execution.getConfiguration());
380
381 lifeCycleExecutionPlanCalculator.setupMojoExecution(
382 session, session.getCurrentProject(), execution, new HashSet<>());
383 assertNotNull(execution.getConfiguration());
384 assertEquals("1.0", execution.getConfiguration().getChild("version").getAttribute("default-value"));
385 }
386
387 @Test
388 void testExecutionListeners() throws Exception {
389 final File pom = getProject("project-basic");
390 final MavenSession session = createMavenSession(pom);
391 session.setProjectDependencyGraph(new ProjectDependencyGraph() {
392 @Override
393 public List<MavenProject> getUpstreamProjects(MavenProject project, boolean transitive) {
394 return Collections.emptyList();
395 }
396
397 @Override
398 public List<MavenProject> getAllProjects() {
399 return session.getAllProjects();
400 }
401
402 @Override
403 public List<MavenProject> getSortedProjects() {
404 return Collections.singletonList(session.getCurrentProject());
405 }
406
407 @Override
408 public List<MavenProject> getDownstreamProjects(MavenProject project, boolean transitive) {
409 return Collections.emptyList();
410 }
411 });
412
413 final List<String> log = new ArrayList<>();
414
415 MojoExecutionListener mojoListener = new MojoExecutionListener() {
416 public void beforeMojoExecution(MojoExecutionEvent event) throws MojoExecutionException {
417 assertNotNull(event.getSession());
418 assertNotNull(event.getProject());
419 assertNotNull(event.getExecution());
420 assertNotNull(event.getMojo());
421 assertNull(event.getCause());
422
423 log.add("beforeMojoExecution " + event.getProject().getArtifactId() + ":"
424 + event.getExecution().getExecutionId());
425 }
426
427 public void afterMojoExecutionSuccess(MojoExecutionEvent event) throws MojoExecutionException {
428 assertNotNull(event.getSession());
429 assertNotNull(event.getProject());
430 assertNotNull(event.getExecution());
431 assertNotNull(event.getMojo());
432 assertNull(event.getCause());
433
434 log.add("afterMojoExecutionSuccess " + event.getProject().getArtifactId() + ":"
435 + event.getExecution().getExecutionId());
436 }
437
438 public void afterExecutionFailure(MojoExecutionEvent event) {
439 assertNotNull(event.getSession());
440 assertNotNull(event.getProject());
441 assertNotNull(event.getExecution());
442 assertNotNull(event.getMojo());
443 assertNotNull(event.getCause());
444
445 log.add("afterExecutionFailure " + event.getProject().getArtifactId() + ":"
446 + event.getExecution().getExecutionId());
447 }
448 };
449 ProjectExecutionListener projectListener = new ProjectExecutionListener() {
450 public void beforeProjectExecution(ProjectExecutionEvent event) throws LifecycleExecutionException {
451 assertNotNull(event.getSession());
452 assertNotNull(event.getProject());
453 assertNull(event.getExecutionPlan());
454 assertNull(event.getCause());
455
456 log.add("beforeProjectExecution " + event.getProject().getArtifactId());
457 }
458
459 public void beforeProjectLifecycleExecution(ProjectExecutionEvent event)
460 throws LifecycleExecutionException {
461 assertNotNull(event.getSession());
462 assertNotNull(event.getProject());
463 assertNotNull(event.getExecutionPlan());
464 assertNull(event.getCause());
465
466 log.add("beforeProjectLifecycleExecution " + event.getProject().getArtifactId());
467 }
468
469 public void afterProjectExecutionSuccess(ProjectExecutionEvent event) throws LifecycleExecutionException {
470 assertNotNull(event.getSession());
471 assertNotNull(event.getProject());
472 assertNotNull(event.getExecutionPlan());
473 assertNull(event.getCause());
474
475 log.add("afterProjectExecutionSuccess " + event.getProject().getArtifactId());
476 }
477
478 public void afterProjectExecutionFailure(ProjectExecutionEvent event) {
479 assertNotNull(event.getSession());
480 assertNotNull(event.getProject());
481 assertNull(event.getExecutionPlan());
482 assertNotNull(event.getCause());
483
484 log.add("afterProjectExecutionFailure " + event.getProject().getArtifactId());
485 }
486 };
487 getContainer().lookup(DelegatingProjectExecutionListener.class).addProjectExecutionListener(projectListener);
488 getContainer().lookup(DelegatingMojoExecutionListener.class).addMojoExecutionListener(mojoListener);
489
490 try {
491 lifecycleExecutor.execute(session);
492 } finally {
493 getContainer()
494 .lookup(DelegatingProjectExecutionListener.class)
495 .removeProjectExecutionListener(projectListener);
496 getContainer().lookup(DelegatingMojoExecutionListener.class).removeMojoExecutionListener(mojoListener);
497 }
498
499 List<String> expectedLog = Arrays.asList(
500 "beforeProjectExecution project-basic",
501 "beforeProjectLifecycleExecution project-basic",
502 "beforeMojoExecution project-basic:default-resources",
503 "afterMojoExecutionSuccess project-basic:default-resources",
504 "beforeMojoExecution project-basic:default-compile",
505 "afterMojoExecutionSuccess project-basic:default-compile",
506 "beforeMojoExecution project-basic:default-testResources",
507 "afterMojoExecutionSuccess project-basic:default-testResources",
508 "beforeMojoExecution project-basic:default-testCompile",
509 "afterMojoExecutionSuccess project-basic:default-testCompile",
510 "beforeMojoExecution project-basic:default-test",
511 "afterMojoExecutionSuccess project-basic:default-test",
512 "beforeMojoExecution project-basic:default-jar",
513 "afterMojoExecutionSuccess project-basic:default-jar",
514 "afterProjectExecutionSuccess project-basic"
515 );
516
517 assertEventLog(expectedLog, log);
518 }
519
520 private static void assertEventLog(List<String> expectedList, List<String> actualList) {
521 assertEquals(toString(expectedList), toString(actualList));
522 }
523
524 private static String toString(List<String> lines) {
525 StringBuilder sb = new StringBuilder();
526 for (String line : lines) {
527 sb.append(line).append('\n');
528 }
529 return sb.toString();
530 }
531 }