001package org.apache.maven.lifecycle;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
005 * agreements. See the NOTICE file distributed with this work for additional information regarding
006 * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance with the License. You may obtain a
008 * copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed under the License
013 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
014 * or implied. See the License for the specific language governing permissions and limitations under
015 * the License.
016 */
017
018import java.io.File;
019import java.util.ArrayList;
020import java.util.Arrays;
021import java.util.Collections;
022import java.util.List;
023
024import org.apache.maven.AbstractCoreMavenComponentTestCase;
025import org.apache.maven.exception.ExceptionHandler;
026import org.apache.maven.execution.MavenSession;
027import org.apache.maven.execution.MojoExecutionEvent;
028import org.apache.maven.execution.MojoExecutionListener;
029import org.apache.maven.execution.ProjectDependencyGraph;
030import org.apache.maven.execution.ProjectExecutionEvent;
031import org.apache.maven.execution.ProjectExecutionListener;
032import org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator;
033import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
034import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
035import org.apache.maven.lifecycle.internal.LifecycleTask;
036import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
037import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
038import org.apache.maven.lifecycle.internal.TaskSegment;
039import org.apache.maven.model.Plugin;
040import org.apache.maven.plugin.MojoExecution;
041import org.apache.maven.plugin.MojoExecutionException;
042import org.apache.maven.plugin.MojoNotFoundException;
043import org.apache.maven.plugin.descriptor.MojoDescriptor;
044import org.apache.maven.project.MavenProject;
045import org.codehaus.plexus.component.annotations.Requirement;
046import org.codehaus.plexus.util.xml.Xpp3Dom;
047
048public class LifecycleExecutorTest
049    extends AbstractCoreMavenComponentTestCase
050{
051    @Requirement
052    private DefaultLifecycleExecutor lifecycleExecutor;
053
054    @Requirement
055    private DefaultLifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator;
056
057    @Requirement
058    private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
059
060    @Requirement
061    private MojoDescriptorCreator mojoDescriptorCreator;
062
063
064    protected void setUp()
065        throws Exception
066    {
067        super.setUp();
068        lifecycleExecutor = (DefaultLifecycleExecutor) lookup( LifecycleExecutor.class );
069        lifeCycleTaskSegmentCalculator =
070            (DefaultLifecycleTaskSegmentCalculator) lookup( LifecycleTaskSegmentCalculator.class );
071        lifeCycleExecutionPlanCalculator = lookup( LifecycleExecutionPlanCalculator.class );
072        mojoDescriptorCreator = lookup( MojoDescriptorCreator.class );
073        lookup( ExceptionHandler.class );
074    }
075
076    @Override
077    protected void tearDown()
078        throws Exception
079    {
080        lifecycleExecutor = null;
081        super.tearDown();
082    }
083
084    protected String getProjectsDirectory()
085    {
086        return "src/test/projects/lifecycle-executor";
087    }
088
089    // -----------------------------------------------------------------------------------------------
090    // Tests which exercise the lifecycle executor when it is dealing with default lifecycle phases.
091    // -----------------------------------------------------------------------------------------------
092
093    public void testCalculationOfBuildPlanWithIndividualTaskWherePluginIsSpecifiedInThePom()
094        throws Exception
095    {
096        // We are doing something like "mvn resources:resources" where no version is specified but this
097        // project we are working on has the version specified in the POM so the version should come from there.
098        File pom = getProject( "project-basic" );
099        MavenSession session = createMavenSession( pom );
100        assertEquals( "project-basic", session.getCurrentProject().getArtifactId() );
101        assertEquals( "1.0", session.getCurrentProject().getVersion() );
102        List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "resources:resources" ) );
103        assertEquals( 1, executionPlan.size() );
104        MojoExecution mojoExecution = executionPlan.get( 0 );
105        assertNotNull( mojoExecution );
106        assertEquals( "org.apache.maven.plugins",
107                      mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId() );
108        assertEquals( "maven-resources-plugin",
109                      mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() );
110        assertEquals( "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion() );
111    }
112
113    public void testCalculationOfBuildPlanWithIndividualTaskOfTheCleanLifecycle()
114        throws Exception
115    {
116        // We are doing something like "mvn clean:clean" where no version is specified but this
117        // project we are working on has the version specified in the POM so the version should come from there.
118        File pom = getProject( "project-basic" );
119        MavenSession session = createMavenSession( pom );
120        assertEquals( "project-basic", session.getCurrentProject().getArtifactId() );
121        assertEquals( "1.0", session.getCurrentProject().getVersion() );
122        List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "clean" ) );
123        assertEquals( 1, executionPlan.size() );
124        MojoExecution mojoExecution = executionPlan.get( 0 );
125        assertNotNull( mojoExecution );
126        assertEquals( "org.apache.maven.plugins",
127                      mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId() );
128        assertEquals( "maven-clean-plugin", mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() );
129        assertEquals( "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion() );
130    }
131
132    public void testCalculationOfBuildPlanWithIndividualTaskOfTheCleanCleanGoal()
133        throws Exception
134    {
135        // We are doing something like "mvn clean:clean" where no version is specified but this
136        // project we are working on has the version specified in the POM so the version should come from there.
137        File pom = getProject( "project-basic" );
138        MavenSession session = createMavenSession( pom );
139        assertEquals( "project-basic", session.getCurrentProject().getArtifactId() );
140        assertEquals( "1.0", session.getCurrentProject().getVersion() );
141        List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "clean:clean" ) );
142        assertEquals( 1, executionPlan.size() );
143        MojoExecution mojoExecution = executionPlan.get( 0 );
144        assertNotNull( mojoExecution );
145        assertEquals( "org.apache.maven.plugins",
146                      mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId() );
147        assertEquals( "maven-clean-plugin", mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() );
148        assertEquals( "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion() );
149    }
150
151    List<MojoExecution> getExecutions( MavenExecutionPlan mavenExecutionPlan )
152    {
153        List<MojoExecution> result = new ArrayList<MojoExecution>();
154        for ( ExecutionPlanItem executionPlanItem : mavenExecutionPlan )
155        {
156            result.add( executionPlanItem.getMojoExecution() );
157        }
158        return result;
159    }
160
161    // We need to take in multiple lifecycles
162    public void testCalculationOfBuildPlanTasksOfTheCleanLifecycleAndTheInstallLifecycle()
163        throws Exception
164    {
165        File pom = getProject( "project-with-additional-lifecycle-elements" );
166        MavenSession session = createMavenSession( pom );
167        assertEquals( "project-with-additional-lifecycle-elements", session.getCurrentProject().getArtifactId() );
168        assertEquals( "1.0", session.getCurrentProject().getVersion() );
169        List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "clean", "install" ) );
170
171        //[01] clean:clean
172        //[02] resources:resources
173        //[03] compiler:compile
174        //[04] it:generate-metadata
175        //[05] resources:testResources
176        //[06] compiler:testCompile
177        //[07] it:generate-test-metadata
178        //[08] surefire:test
179        //[09] jar:jar
180        //[10] install:install
181        //
182        assertEquals( 10, executionPlan.size() );
183
184        assertEquals( "clean:clean", executionPlan.get( 0 ).getMojoDescriptor().getFullGoalName() );
185        assertEquals( "resources:resources", executionPlan.get( 1 ).getMojoDescriptor().getFullGoalName() );
186        assertEquals( "compiler:compile", executionPlan.get( 2 ).getMojoDescriptor().getFullGoalName() );
187        assertEquals( "it:generate-metadata", executionPlan.get( 3 ).getMojoDescriptor().getFullGoalName() );
188        assertEquals( "resources:testResources", executionPlan.get( 4 ).getMojoDescriptor().getFullGoalName() );
189        assertEquals( "compiler:testCompile", executionPlan.get( 5 ).getMojoDescriptor().getFullGoalName() );
190        assertEquals( "it:generate-test-metadata", executionPlan.get( 6 ).getMojoDescriptor().getFullGoalName() );
191        assertEquals( "surefire:test", executionPlan.get( 7 ).getMojoDescriptor().getFullGoalName() );
192        assertEquals( "jar:jar", executionPlan.get( 8 ).getMojoDescriptor().getFullGoalName() );
193        assertEquals( "install:install", executionPlan.get( 9 ).getMojoDescriptor().getFullGoalName() );
194    }
195
196    // We need to take in multiple lifecycles
197    public void testCalculationOfBuildPlanWithMultipleExecutionsOfModello()
198        throws Exception
199    {
200        File pom = getProject( "project-with-multiple-executions" );
201        MavenSession session = createMavenSession( pom );
202        assertEquals( "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        //[01] clean:clean
210        //[02] modello:xpp3-writer
211        //[03] modello:java
212        //[04] modello:xpp3-reader
213        //[05] modello:xpp3-writer
214        //[06] modello:java
215        //[07] modello:xpp3-reader
216        //[08] plugin:descriptor
217        //[09] resources:resources
218        //[10] compiler:compile
219        //[11] resources:testResources
220        //[12] compiler:testCompile
221        //[13] surefire:test
222        //[14] jar:jar
223        //[15] plugin:addPluginArtifactMetadata
224        //[16] install:install
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( "resources:resources", executions.get( 7 ).getMojoDescriptor().getFullGoalName() );
237        assertEquals( "compiler:compile", executions.get( 8 ).getMojoDescriptor().getFullGoalName() );
238        assertEquals( "plugin:descriptor", executions.get( 9 ).getMojoDescriptor().getFullGoalName() );
239        assertEquals( "resources:testResources", executions.get( 10 ).getMojoDescriptor().getFullGoalName() );
240        assertEquals( "compiler:testCompile", executions.get( 11 ).getMojoDescriptor().getFullGoalName() );
241        assertEquals( "surefire:test", executions.get( 12 ).getMojoDescriptor().getFullGoalName() );
242        assertEquals( "jar:jar", executions.get( 13 ).getMojoDescriptor().getFullGoalName() );
243        assertEquals( "plugin:addPluginArtifactMetadata", executions.get( 14 ).getMojoDescriptor().getFullGoalName() );
244        assertEquals( "install:install", executions.get( 15 ).getMojoDescriptor().getFullGoalName() );
245
246        assertEquals( "src/main/mdo/remote-resources.mdo",
247                      new MojoExecutionXPathContainer( executions.get( 1 ) ).getValue(
248                          "configuration/models[1]/model" ) );
249        assertEquals( "src/main/mdo/supplemental-model.mdo",
250                      new MojoExecutionXPathContainer( executions.get( 4 ) ).getValue(
251                          "configuration/models[1]/model" ) );
252    }
253
254    public void testLifecycleQueryingUsingADefaultLifecyclePhase()
255        throws Exception
256    {
257        File pom = getProject( "project-with-additional-lifecycle-elements" );
258        MavenSession session = createMavenSession( pom );
259        assertEquals( "project-with-additional-lifecycle-elements", session.getCurrentProject().getArtifactId() );
260        assertEquals( "1.0", session.getCurrentProject().getVersion() );
261        List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "package" ) );
262
263        //[01] resources:resources
264        //[02] compiler:compile
265        //[03] it:generate-metadata
266        //[04] resources:testResources
267        //[05] compiler:testCompile
268        //[06] plexus-component-metadata:generate-test-metadata
269        //[07] surefire:test
270        //[08] jar:jar
271        //
272        assertEquals( 8, executionPlan.size() );
273
274        assertEquals( "resources:resources", executionPlan.get( 0 ).getMojoDescriptor().getFullGoalName() );
275        assertEquals( "compiler:compile", executionPlan.get( 1 ).getMojoDescriptor().getFullGoalName() );
276        assertEquals( "it:generate-metadata", executionPlan.get( 2 ).getMojoDescriptor().getFullGoalName() );
277        assertEquals( "resources:testResources", executionPlan.get( 3 ).getMojoDescriptor().getFullGoalName() );
278        assertEquals( "compiler:testCompile", executionPlan.get( 4 ).getMojoDescriptor().getFullGoalName() );
279        assertEquals( "it:generate-test-metadata", executionPlan.get( 5 ).getMojoDescriptor().getFullGoalName() );
280        assertEquals( "surefire:test", executionPlan.get( 6 ).getMojoDescriptor().getFullGoalName() );
281        assertEquals( "jar:jar", executionPlan.get( 7 ).getMojoDescriptor().getFullGoalName() );
282    }
283
284    public void testLifecyclePluginsRetrievalForDefaultLifecycle()
285        throws Exception
286    {
287        List<Plugin> plugins =
288            new ArrayList<Plugin>( lifecycleExecutor.getPluginsBoundByDefaultToAllLifecycles( "jar" ) );
289
290        assertEquals( 8, plugins.size() );
291    }
292
293    public void testPluginConfigurationCreation()
294        throws Exception
295    {
296        File pom = getProject( "project-with-additional-lifecycle-elements" );
297        MavenSession session = createMavenSession( pom );
298        MojoDescriptor mojoDescriptor =
299            mojoDescriptorCreator.getMojoDescriptor( "org.apache.maven.its.plugins:maven-it-plugin:0.1:java", session,
300                                                     session.getCurrentProject() );
301        Xpp3Dom dom = MojoDescriptorCreator.convert( mojoDescriptor );
302        System.out.println( dom );
303    }
304
305    MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
306        throws Exception
307    {
308        List<TaskSegment> taskSegments =
309            lifeCycleTaskSegmentCalculator.calculateTaskSegments( session, Arrays.asList( tasks ) );
310
311        TaskSegment mergedSegment = new TaskSegment( false );
312
313        for ( TaskSegment taskSegment : taskSegments )
314        {
315            mergedSegment.getTasks().addAll( taskSegment.getTasks() );
316        }
317
318        return lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, session.getCurrentProject(),
319                                                                        mergedSegment.getTasks() );
320    }
321
322    public void testInvalidGoalName()
323        throws Exception
324    {
325        File pom = getProject( "project-basic" );
326        MavenSession session = createMavenSession( pom );
327        try
328        {
329            getExecutions( calculateExecutionPlan( session, "resources:" ) );
330            fail( "expected a MojoNotFoundException" );
331        }
332        catch ( MojoNotFoundException e )
333        {
334            assertEquals( "", e.getGoal() );
335        }
336
337        try
338        {
339            getExecutions( calculateExecutionPlan( session, "org.apache.maven.plugins:maven-resources-plugin:0.1:resources:toomany" ) );
340            fail( "expected a MojoNotFoundException" );
341        }
342        catch ( MojoNotFoundException e )
343        {
344            assertEquals( "resources:toomany", e.getGoal() );
345        }
346    }
347
348
349    public void testPluginPrefixRetrieval()
350        throws Exception
351    {
352        File pom = getProject( "project-basic" );
353        MavenSession session = createMavenSession( pom );
354        Plugin plugin = mojoDescriptorCreator.findPluginForPrefix( "resources", session );
355        assertEquals( "org.apache.maven.plugins", plugin.getGroupId() );
356        assertEquals( "maven-resources-plugin", plugin.getArtifactId() );
357    }
358
359    // Prefixes
360
361    public void testFindingPluginPrefixforCleanClean()
362        throws Exception
363    {
364        File pom = getProject( "project-basic" );
365        MavenSession session = createMavenSession( pom );
366        Plugin plugin = mojoDescriptorCreator.findPluginForPrefix( "clean", session );
367        assertNotNull( plugin );
368    }
369
370    public void testSetupMojoExecution()
371        throws Exception
372    {
373        File pom = getProject( "mojo-configuration" );
374
375        MavenSession session = createMavenSession( pom );
376
377        LifecycleTask task = new LifecycleTask( "generate-sources" );
378        MavenExecutionPlan executionPlan =
379            lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, session.getCurrentProject(),
380                                                                     Arrays.asList( (Object) task ), false );
381
382        MojoExecution execution = executionPlan.getMojoExecutions().get(0);
383        assertEquals(execution.toString(), "maven-it-plugin", execution.getArtifactId());
384        assertNull(execution.getConfiguration());
385
386        lifeCycleExecutionPlanCalculator.setupMojoExecution( session, session.getCurrentProject(), execution );
387        assertNotNull(execution.getConfiguration());
388        assertEquals("1.0", execution.getConfiguration().getChild( "version" ).getAttribute( "default-value" ));
389    }
390
391    public void testExecutionListeners()
392        throws Exception
393    {
394        final File pom = getProject( "project-basic" );
395        final MavenSession session = createMavenSession( pom );
396        session.setProjectDependencyGraph( new ProjectDependencyGraph()
397        {
398            public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
399            {
400                return Collections.emptyList();
401            }
402
403            public List<MavenProject> getSortedProjects()
404            {
405                return Collections.singletonList( session.getCurrentProject() );
406            }
407
408            public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
409            {
410                return Collections.emptyList();
411            }
412        } );
413
414        final List<String> log = new ArrayList<String>();
415
416        MojoExecutionListener mojoListener = new MojoExecutionListener()
417        {
418            public void beforeMojoExecution( MojoExecutionEvent event )
419                throws MojoExecutionException
420            {
421                assertNotNull( event.getSession() );
422                assertNotNull( event.getProject() );
423                assertNotNull( event.getExecution() );
424                assertNotNull( event.getMojo() );
425                assertNull( event.getCause() );
426
427                log.add( "beforeMojoExecution " + event.getProject().getArtifactId() + ":"
428                    + event.getExecution().getExecutionId() );
429            }
430
431            public void afterMojoExecutionSuccess( MojoExecutionEvent event )
432                throws MojoExecutionException
433            {
434                assertNotNull( event.getSession() );
435                assertNotNull( event.getProject() );
436                assertNotNull( event.getExecution() );
437                assertNotNull( event.getMojo() );
438                assertNull( event.getCause() );
439
440                log.add( "afterMojoExecutionSuccess " + event.getProject().getArtifactId() + ":"
441                    + event.getExecution().getExecutionId() );
442            }
443
444            public void afterExecutionFailure( MojoExecutionEvent event )
445            {
446                assertNotNull( event.getSession() );
447                assertNotNull( event.getProject() );
448                assertNotNull( event.getExecution() );
449                assertNotNull( event.getMojo() );
450                assertNotNull( event.getCause() );
451
452                log.add( "afterExecutionFailure " + event.getProject().getArtifactId() + ":"
453                    + event.getExecution().getExecutionId() );
454            }
455        };
456        ProjectExecutionListener projectListener = new ProjectExecutionListener()
457        {
458            public void beforeProjectExecution( ProjectExecutionEvent event )
459                throws LifecycleExecutionException
460            {
461                assertNotNull( event.getSession() );
462                assertNotNull( event.getProject() );
463                assertNull( event.getExecutionPlan() );
464                assertNull( event.getCause() );
465
466                log.add( "beforeProjectExecution " + event.getProject().getArtifactId() );
467            }
468
469            public void beforeProjectLifecycleExecution( ProjectExecutionEvent event )
470                throws LifecycleExecutionException
471            {
472                assertNotNull( event.getSession() );
473                assertNotNull( event.getProject() );
474                assertNotNull( event.getExecutionPlan() );
475                assertNull( event.getCause() );
476
477                log.add( "beforeProjectLifecycleExecution " + event.getProject().getArtifactId() );
478            }
479
480            public void afterProjectExecutionSuccess( ProjectExecutionEvent event )
481                throws LifecycleExecutionException
482            {
483                assertNotNull( event.getSession() );
484                assertNotNull( event.getProject() );
485                assertNotNull( event.getExecutionPlan() );
486                assertNull( event.getCause() );
487
488                log.add( "afterProjectExecutionSuccess " + event.getProject().getArtifactId() );
489            }
490
491            public void afterProjectExecutionFailure( ProjectExecutionEvent event )
492            {
493                assertNotNull( event.getSession() );
494                assertNotNull( event.getProject() );
495                assertNull( event.getExecutionPlan() );
496                assertNotNull( event.getCause() );
497
498                log.add( "afterProjectExecutionFailure " + event.getProject().getArtifactId() );
499            }
500        };
501        lookup( DelegatingProjectExecutionListener.class ).addProjectExecutionListener( projectListener );
502        lookup( DelegatingMojoExecutionListener.class ).addMojoExecutionListener( mojoListener );
503
504        try
505        {
506            lifecycleExecutor.execute( session );
507        }
508        finally
509        {
510            lookup( DelegatingProjectExecutionListener.class ).removeProjectExecutionListener( projectListener );
511            lookup( DelegatingMojoExecutionListener.class ).removeMojoExecutionListener( mojoListener );
512        }
513
514        List<String> expectedLog = Arrays.asList( "beforeProjectExecution project-basic", //
515                                                  "beforeProjectLifecycleExecution project-basic", //
516                                                  "beforeMojoExecution project-basic:default-resources", //
517                                                  "afterMojoExecutionSuccess project-basic:default-resources", //
518                                                  "beforeMojoExecution project-basic:default-compile", //
519                                                  "afterMojoExecutionSuccess project-basic:default-compile", //
520                                                  "beforeMojoExecution project-basic:default-testResources", //
521                                                  "afterMojoExecutionSuccess project-basic:default-testResources", //
522                                                  "beforeMojoExecution project-basic:default-testCompile", //
523                                                  "afterMojoExecutionSuccess project-basic:default-testCompile", //
524                                                  "beforeMojoExecution project-basic:default-test", //
525                                                  "afterMojoExecutionSuccess project-basic:default-test", //
526                                                  "beforeMojoExecution project-basic:default-jar", //
527                                                  "afterMojoExecutionSuccess project-basic:default-jar", //
528                                                  "afterProjectExecutionSuccess project-basic" //
529        );
530
531        assertEventLog( expectedLog, log );
532    }
533
534    private static void assertEventLog( List<String> expectedList, List<String> actualList )
535    {
536        assertEquals( toString( expectedList ), toString( actualList ) );
537    }
538
539    private static String toString( List<String> lines )
540    {
541        StringBuilder sb = new StringBuilder();
542        for ( String line : lines )
543        {
544            sb.append( line ).append( '\n' );
545        }
546        return sb.toString();
547    }
548}