[MNG-4633] Weave mode operational.

Replaced approximation-based algorithm for detecting upstream-mojo dependencies with
a proper phase based solution. Revised re-resolution strategy of reactor artifacts

There are a few minor performance inefficiencies (only in weave mode), that will be
sorted for beta-2.

Improved logging, and also added initial graphviz-format log output support

git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@934425 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Kristian Rosenvold 2010-04-15 14:34:42 +00:00
parent a315a9dac3
commit 7e5e5eb1da
11 changed files with 444 additions and 171 deletions

View File

@ -25,6 +25,8 @@ import org.apache.maven.plugin.MojoExecution;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -64,7 +66,7 @@ public class MavenExecutionPlan
private final Map<String, ExecutionPlanItem> lastMojoExecutionForAllPhases;
final List<String> phases;
final List<String> phasesInExecutionPlan;
public MavenExecutionPlan( Set<String> requiredDependencyResolutionScopes,
Set<String> requiredDependencyCollectionScopes, List<ExecutionPlanItem> planItem,
@ -73,61 +75,43 @@ public class MavenExecutionPlan
this.requiredDependencyResolutionScopes = requiredDependencyResolutionScopes;
this.requiredDependencyCollectionScopes = requiredDependencyCollectionScopes;
this.planItem = planItem;
lastMojoExecutionForAllPhases = new HashMap<String, ExecutionPlanItem>();
lastMojoExecutionForAllPhases = new LinkedHashMap<String, ExecutionPlanItem>();
String firstPhasePreset = getFirstPhasePresentInPlan();
List<String> phases = null;
LinkedHashSet<String> totalPhaseSet = new LinkedHashSet<String>();
if ( defaultLifecycles != null )
{
final Lifecycle lifecycle = defaultLifecycles.get( firstPhasePreset );
if ( lifecycle != null )
for ( String phase : getDistinctPhasesInOrderOfExecutionPlanAppearance( planItem ) )
{
phases = lifecycle.getPhases();
final Lifecycle lifecycle = defaultLifecycles.get( phase );
if ( lifecycle != null )
{
totalPhaseSet.addAll( lifecycle.getPhases() );
}
}
}
this.phases = phases;
this.phasesInExecutionPlan = new ArrayList<String>( totalPhaseSet );
Map<String, ExecutionPlanItem> lastInExistingPhases = new HashMap<String, ExecutionPlanItem>();
for ( ExecutionPlanItem executionPlanItem : getExecutionPlanItems() )
{
final String phaseName = executionPlanItem.getLifecyclePhase();
if ( phaseName != null )
{
lastInExistingPhases.put( phaseName, executionPlanItem );
}
lastInExistingPhases.put( executionPlanItem.getLifecyclePhase(), executionPlanItem );
}
ExecutionPlanItem lastSeenExecutionPlanItem = null;
ExecutionPlanItem forThis;
ExecutionPlanItem forThisPhase;
if ( phases != null )
for ( String phase : totalPhaseSet )
{
for ( String phase : phases )
forThisPhase = lastInExistingPhases.get( phase );
if ( forThisPhase != null )
{
forThis = lastInExistingPhases.get( phase );
if ( forThis != null )
{
lastSeenExecutionPlanItem = forThis;
}
lastMojoExecutionForAllPhases.put( phase, lastSeenExecutionPlanItem );
lastSeenExecutionPlanItem = forThisPhase;
}
lastMojoExecutionForAllPhases.put( phase, lastSeenExecutionPlanItem );
}
}
private String getFirstPhasePresentInPlan()
{
for ( ExecutionPlanItem executionPlanItem : getExecutionPlanItems() )
{
final String phase = executionPlanItem.getLifecyclePhase();
if ( phase != null )
{
return phase;
}
}
return null;
}
@ -146,15 +130,7 @@ public class MavenExecutionPlan
*/
public ExecutionPlanItem findLastInPhase( String requestedPhase )
{
ExecutionPlanItem result = lastMojoExecutionForAllPhases.get( requestedPhase );
int i = phases.indexOf( requestedPhase );
while ( result == null && i > 0 )
{
final String previousPhase = phases.get( --i );
result = lastMojoExecutionForAllPhases.get( previousPhase );
}
return result;
return lastMojoExecutionForAllPhases.get( requestedPhase );
}
private List<ExecutionPlanItem> getExecutionPlanItems()
@ -162,6 +138,22 @@ public class MavenExecutionPlan
return planItem;
}
private static Iterable<String> getDistinctPhasesInOrderOfExecutionPlanAppearance(
List<ExecutionPlanItem> planItems )
{
LinkedHashSet<String> result = new LinkedHashSet<String>();
for ( ExecutionPlanItem executionPlanItem : planItems )
{
final String phase = executionPlanItem.getLifecyclePhase();
if ( !result.contains( phase ) )
{
result.add( phase );
}
}
return result;
}
public void forceAllComplete()
{
for ( ExecutionPlanItem executionPlanItem : getExecutionPlanItems() )
@ -170,6 +162,20 @@ public class MavenExecutionPlan
}
}
public void waitUntilAllDone()
throws InterruptedException
{
for ( ExecutionPlanItem executionPlanItem : getExecutionPlanItems() )
{
executionPlanItem.waitUntilDone();
}
}
public boolean containsPhase( String phase )
{
return phasesInExecutionPlan.contains( phase );
}
public Set<String> getRequiredResolutionScopes()
{
return requiredDependencyResolutionScopes;
@ -191,6 +197,7 @@ public class MavenExecutionPlan
}
// Used by m2e but will be removed, really.
@SuppressWarnings({"UnusedDeclaration"})
@Deprecated
public List<MojoExecution> getExecutions()

View File

@ -0,0 +1,214 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.maven.lifecycle.internal;
import org.apache.maven.project.MavenProject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Kristian Rosenvold
* NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
*/
public class BuildLogItem
{
private final ExecutionPlanItem executionPlanItem;
private final MavenProject project;
private final long startTime;
private long endTime;
private final List<DependencyLogEntry> dependencies =
Collections.synchronizedList( new ArrayList<DependencyLogEntry>() );
public BuildLogItem( MavenProject project, ExecutionPlanItem executionPlanItem )
{
this.executionPlanItem = executionPlanItem;
this.project = project;
startTime = System.currentTimeMillis();
}
public MavenProject getProject()
{
return project;
}
public void setComplete()
{
endTime = System.currentTimeMillis();
}
public void addWait( MavenProject upstreamProject, ExecutionPlanItem inSchedule, long startWait )
{
long now = System.currentTimeMillis();
dependencies.add( new DependencyLogEntry( upstreamProject, inSchedule, startWait, now, null ) );
}
public void addDependency( MavenProject upstreamProject, String message )
{
dependencies.add( new DependencyLogEntry( upstreamProject, message ) );
}
public String toString( long rootStart )
{
StringBuilder result = new StringBuilder();
result.append( String.format( "%1d %2d ", startTime - rootStart, endTime - rootStart ) );
result.append( project.getName() );
result.append( " " );
result.append( getMojoExecutionDescription( executionPlanItem ) );
if ( dependencies.size() > 0 )
{
result.append( "\n" );
for ( DependencyLogEntry waitLogEntry : dependencies )
{
result.append( " " );
result.append( waitLogEntry.toString() );
result.append( "\n" );
}
}
return result.toString();
}
public Object toGraph( long rootStart )
{
StringBuilder result = new StringBuilder();
if ( dependencies.size() > 0 )
{
for ( DependencyLogEntry waitLogEntry : dependencies )
{
result.append( " " );
result.append( nodeKey( project, executionPlanItem ) );
result.append( " -> " );
result.append( waitLogEntry.toNodeKey() );
result.append( waitLogEntry.toNodeDescription( rootStart ) );
result.append( "\n" );
}
}
else
{
result.append( " " );
result.append( nodeKey( project, executionPlanItem ) );
result.append( "\n" );
}
return result.toString();
}
private static String nodeKey( MavenProject mavenProject, ExecutionPlanItem executionPlanItem )
{
String key = mavenProject.getArtifactId();
if ( executionPlanItem != null )
{
key += "_" + getMojoExecutionDescription( executionPlanItem );
}
return key.replace( ".", "_" ).replace( ":", "_" );
}
private static String getMojoExecutionDescription( ExecutionPlanItem executionPlanItem )
{
if ( executionPlanItem.getMojoExecution() != null )
{
return executionPlanItem.getMojoExecution().getArtifactId() + getLifeCyclePhase( executionPlanItem );
}
else
{
return "";
}
}
private static String getLifeCyclePhase( ExecutionPlanItem executionPlanItem )
{
return executionPlanItem.getLifecyclePhase() != null ? "[" + executionPlanItem.getLifecyclePhase() + "]" : "";
}
class DependencyLogEntry
{
private final ExecutionPlanItem executionPlanItem;
private final MavenProject upstreamProject;
private final Long start;
private final Long stop;
private final String message;
DependencyLogEntry( MavenProject upstreamProject, ExecutionPlanItem executionPlanItem, Long start, Long stop,
String message )
{
this.upstreamProject = upstreamProject;
this.executionPlanItem = executionPlanItem;
this.start = start;
this.stop = stop;
this.message = message;
}
DependencyLogEntry( MavenProject upstreamProject, String message )
{
this( upstreamProject, null, null, null, message );
}
public String toString()
{
return upstreamProject.getName() + ":" + getExecutionPlanItem() + getElapsed() + getMessage();
}
public String toNodeKey()
{
return nodeKey( upstreamProject, executionPlanItem );
}
public String toNodeDescription( long rootStart )
{
return "";
}
private String getMessage()
{
return message != null ? message : "";
}
private String getExecutionPlanItem()
{
if ( executionPlanItem != null )
{
return getMojoExecutionDescription( executionPlanItem );
}
else
{
return "";
}
}
private String getElapsed()
{
if ( start != null && stop != null )
{
long elapsed = stop - start;
return elapsed > 0 ? ", wait=" + elapsed : "";
}
return "";
}
}
}

View File

@ -1,98 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.maven.lifecycle.internal;
import org.apache.maven.project.MavenProject;
import java.util.ArrayList;
import java.util.List;
/**
* @author Kristian Rosenvold
* NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
*/
public class BuiltLogItem
{
private final ExecutionPlanItem executionPlanItem;
private final MavenProject project;
private final long startTime;
private long endTime;
private final List<WaitLogEntry> waits = new ArrayList<WaitLogEntry>();
public BuiltLogItem( MavenProject project, ExecutionPlanItem executionPlanItem )
{
this.executionPlanItem = executionPlanItem;
this.project = project;
startTime = System.currentTimeMillis();
}
public void setComplete()
{
endTime = System.currentTimeMillis();
}
public void addWait( MavenProject upstreamProject, ExecutionPlanItem inSchedule, long startWait )
{
long now = System.currentTimeMillis();
if ( ( now - startWait ) > 1 )
{
waits.add( new WaitLogEntry( upstreamProject, inSchedule, startWait, now ) );
}
}
public String toString( long rootStart )
{
StringBuilder result = new StringBuilder();
result.append( String.format( "%1d %2d ", startTime - rootStart, endTime - rootStart ) );
result.append( project.getName() );
result.append( " " );
result.append( executionPlanItem.getMojoExecution().getArtifactId() );
for ( WaitLogEntry waitLogEntry : waits )
{
result.append( waitLogEntry.toString() );
}
return result.toString();
}
class WaitLogEntry
{
private final ExecutionPlanItem executionPlanItem;
private final MavenProject upstreamProject;
private final long start;
private final long stop;
WaitLogEntry( MavenProject upstreamProject, ExecutionPlanItem executionPlanItem, long start, long stop )
{
this.upstreamProject = upstreamProject;
this.executionPlanItem = executionPlanItem;
this.start = start;
this.stop = stop;
}
public String toString()
{
return upstreamProject.getName() + " " + executionPlanItem.getMojoExecution().getArtifactId() + ", wait=" +
( stop - start );
}
}
}

View File

@ -14,9 +14,12 @@
*/
package org.apache.maven.lifecycle.internal;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.apache.maven.project.MavenProject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -44,12 +47,12 @@ public class ConcurrentBuildLogger
}
List<BuiltLogItem> items = Collections.synchronizedList( new ArrayList<BuiltLogItem>() );
List<BuildLogItem> items = Collections.synchronizedList( new ArrayList<BuildLogItem>() );
public BuiltLogItem createBuildLogItem( MavenProject project, ExecutionPlanItem current )
public BuildLogItem createBuildLogItem( MavenProject project, ExecutionPlanItem current )
{
threadMap.put( project, Thread.currentThread() );
BuiltLogItem result = new BuiltLogItem( project, current );
BuildLogItem result = new BuildLogItem( project, current );
items.add( result );
return result;
}
@ -65,11 +68,44 @@ public class ConcurrentBuildLogger
result.append( "\n" );
}
for ( BuiltLogItem builtLogItem : items )
for ( BuildLogItem builtLogItem : items )
{
result.append( builtLogItem.toString( startTime ) );
result.append( "\n" );
}
return result.toString();
}
public String toGraph()
{
StringBuilder result = new StringBuilder();
Multimap<MavenProject, BuildLogItem> multiMap = ArrayListMultimap.create();
for ( BuildLogItem builtLogItem : items )
{
multiMap.put( builtLogItem.getProject(), builtLogItem );
}
result.append( "digraph build" );
result.append( " {\n " );
for ( MavenProject mavenProject : multiMap.keySet() )
{
final Collection<BuildLogItem> builtLogItems = multiMap.get( mavenProject );
result.append( " subgraph " );
result.append( mavenProject.getArtifactId() );
result.append( " {\n" );
for ( BuildLogItem builtLogItem : builtLogItems )
{
result.append( builtLogItem.toGraph( startTime ) );
}
result.append( "\n }\n" );
}
result.append( "\n}\n " );
return result.toString();
}
}

View File

@ -52,11 +52,6 @@ public class ExecutionPlanItem
public String getLifecyclePhase()
{
final MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
if ( mojoDescriptor.getPhase() != null )
{
return mojoDescriptor.getPhase();
}
return mojoExecution.getLifecyclePhase();
}
@ -110,18 +105,6 @@ public class ExecutionPlanItem
return schedule;
}
public boolean hasSchedule( Schedule other )
{
if ( getSchedule() != null && !getSchedule().isMissingPhase() )
{
if ( other.getPhase().equals( getSchedule().getPhase() ) )
{
return true;
}
}
return false;
}
public Plugin getPlugin()
{
final MojoDescriptor mojoDescriptor = getMojoExecution().getMojoDescriptor();

View File

@ -142,7 +142,7 @@ public class LifecycleDebugLogger
}
final ProjectDependencyGraph dependencyGraph = session.getProjectDependencyGraph();
logger.info( "=== WEAVE CONCURRENCY BUILD PLAN ================================================" );
logger.info( "=== WEAVE CONCURRENCY BUILD PLAN ======================================" );
for ( MavenProject mavenProject : dependencyGraph.getSortedProjects() )
{

View File

@ -14,6 +14,8 @@
*/
package org.apache.maven.lifecycle.internal;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.execution.BuildSuccess;
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenExecutionRequest;
@ -33,6 +35,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
@ -69,6 +72,9 @@ public class LifecycleWeaveBuilder
@Requirement
private Logger logger;
@Requirement
private LifecycleDependencyResolver lifecycleDependencyResolver;
@Requirement
private ExecutionEventCatapult eventCatapult;
@ -82,6 +88,7 @@ public class LifecycleWeaveBuilder
}
public LifecycleWeaveBuilder( MojoExecutor mojoExecutor, BuilderCommon builderCommon, Logger logger,
LifecycleDependencyResolver lifecycleDependencyResolver,
ExecutionEventCatapult eventCatapult )
{
this.mojoExecutor = mojoExecutor;
@ -118,7 +125,8 @@ public class LifecycleWeaveBuilder
final Callable<ProjectSegment> projectBuilder =
createCallableForBuildingOneFullModule( buildContext, session, reactorBuildStatus,
executionPlan, projectBuild, muxer,
dependencyContext, concurrentBuildLogger );
dependencyContext, concurrentBuildLogger,
projectBuilds );
futures.add( service.submit( projectBuilder ) );
}
@ -150,7 +158,8 @@ public class LifecycleWeaveBuilder
final ProjectSegment projectBuild,
final ThreadOutputMuxer muxer,
final DependencyContext dependencyContext,
final ConcurrentBuildLogger concurrentBuildLogger )
final ConcurrentBuildLogger concurrentBuildLogger,
final ProjectBuildList projectBuilds )
{
return new Callable<ProjectSegment>()
{
@ -178,7 +187,7 @@ public class LifecycleWeaveBuilder
{
PhaseRecorder phaseRecorder = new PhaseRecorder( projectBuild.getProject() );
BuiltLogItem builtLogItem =
BuildLogItem builtLogItem =
concurrentBuildLogger.createBuildLogItem( projectBuild.getProject(), current );
final Schedule schedule = current.getSchedule();
@ -202,6 +211,9 @@ public class LifecycleWeaveBuilder
ExecutionPlanItem nextPlanItem = planItems.hasNext() ? planItems.next() : null;
if ( nextPlanItem != null )
{
boolean mustReResolved = false;
final Schedule scheduleOfNext = nextPlanItem.getSchedule();
if ( scheduleOfNext == null || !scheduleOfNext.isParallel() )
{
@ -210,14 +222,52 @@ public class LifecycleWeaveBuilder
final MavenExecutionPlan upstreamPlan = executionPlans.get( upstreamProject );
final String nextPhase = nextPlanItem.getLifecyclePhase();
final ExecutionPlanItem inSchedule = upstreamPlan.findLastInPhase( nextPhase );
if ( inSchedule != null )
{
if ( upstreamPhaseModifiesArtifactResolutionState( inSchedule ) )
{
String key = ArtifactUtils.key( upstreamProject.getGroupId(),
upstreamProject.getArtifactId(),
upstreamProject.getVersion() );
final Set<Artifact> deps =
projectBuild.getProject().getDependencyArtifacts();
for ( Artifact dep : deps )
{
String depKey =
ArtifactUtils.key( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion() );
if ( key.equals( depKey ) )
{
dep.setResolved( false );
mustReResolved = true;
}
}
}
long startWait = System.currentTimeMillis();
inSchedule.waitUntilDone();
builtLogItem.addWait( upstreamProject, inSchedule, startWait );
}
else if ( !upstreamPlan.containsPhase( nextPhase ) )
{
// Still a bit of a kludge; if we cannot connect in a sensible way to
// the upstream build plan we just revert to waiting for it all to
// complete. Real problem is per-mojo phase->lifecycle mapping
builtLogItem.addDependency( upstreamProject, "No phase tracking possible " );
upstreamPlan.waitUntilAllDone();
}
else
{
builtLogItem.addDependency( upstreamProject, "No schedule" );
}
}
}
if ( mustReResolved )
{
lifecycleDependencyResolver.resolveDependencies( false, projectBuild.getProject(),
projectBuild.getSession(),
executionPlan );
}
}
current = nextPlanItem;
}
@ -246,6 +296,12 @@ public class LifecycleWeaveBuilder
};
}
private boolean upstreamPhaseModifiesArtifactResolutionState( ExecutionPlanItem inSchedule )
{
final String phase = inSchedule.getLifecyclePhase();
return "install".equals( phase ) || "compile".equals( phase ) || "test-compile".equals( phase );
}
private void buildExecutionPlanItem( ReactorContext reactorContext, ExecutionPlanItem node,
ProjectSegment projectBuild, DependencyContext dependencyContext,
PhaseRecorder phaseRecorder )

View File

@ -0,0 +1,73 @@
package org.apache.maven.lifecycle.internal;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
import junit.framework.TestCase;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
import org.apache.maven.project.MavenProject;
import java.util.Iterator;
/**
* @author Kristian Rosenvold
*/
public class ConcurrentBuildLoggerTest
extends TestCase
{
public void testToGraph()
throws Exception
{
ConcurrentBuildLogger concurrentBuildLogger = new ConcurrentBuildLogger();
MojoDescriptorCreator mojoDescriptorCreator =
LifecycleExecutionPlanCalculatorTest.createMojoDescriptorCreator();
LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator =
LifecycleExecutionPlanCalculatorTest.createExecutionPlaceCalculator( mojoDescriptorCreator );
MavenProject A = ProjectDependencyGraphStub.B;
MavenProject B = ProjectDependencyGraphStub.C;
final MavenSession session1 = ProjectDependencyGraphStub.getMavenSession( A );
final GoalTask goalTask1 = new GoalTask( "compiler:compile" );
final GoalTask goalTask2 = new GoalTask( "surefire:test" );
final TaskSegment taskSegment1 = new TaskSegment( false, goalTask1, goalTask2 );
MavenExecutionPlan executionPlan =
lifecycleExecutionPlanCalculator.calculateExecutionPlan( session1, A, taskSegment1.getTasks() );
MavenExecutionPlan executionPlan2 =
lifecycleExecutionPlanCalculator.calculateExecutionPlan( session1, B, taskSegment1.getTasks() );
final Iterator<ExecutionPlanItem> planItemIterator = executionPlan.iterator();
final BuildLogItem a1 = concurrentBuildLogger.createBuildLogItem( A, planItemIterator.next() );
final BuildLogItem a2 = concurrentBuildLogger.createBuildLogItem( A, planItemIterator.next() );
final Iterator<ExecutionPlanItem> plan2ItemIterator = executionPlan.iterator();
final BuildLogItem b1 = concurrentBuildLogger.createBuildLogItem( B, plan2ItemIterator.next() );
final BuildLogItem b2 = concurrentBuildLogger.createBuildLogItem( B, plan2ItemIterator.next() );
b1.addDependency( A, "Project dependency" );
final Iterator<ExecutionPlanItem> aPlan = executionPlan.iterator();
b1.addWait( A, aPlan.next(), System.currentTimeMillis() );
b2.addWait( A, aPlan.next(), System.currentTimeMillis() );
final String response = concurrentBuildLogger.toGraph();
assertTrue( response.indexOf( "digraph" ) >= 0 );
}
}

View File

@ -59,7 +59,7 @@ public class LifecycleExecutionPlanCalculatorTest
// Maybe also make one with LifeCycleTasks
private LifecycleExecutionPlanCalculator createExecutionPlaceCalculator(
public static LifecycleExecutionPlanCalculator createExecutionPlaceCalculator(
MojoDescriptorCreator mojoDescriptorCreator )
{
LifecyclePluginResolver lifecyclePluginResolver =
@ -69,7 +69,7 @@ public class LifecycleExecutionPlanCalculatorTest
mojoDescriptorCreator, lifecyclePluginResolver );
}
private MojoDescriptorCreator createMojoDescriptorCreator()
public static MojoDescriptorCreator createMojoDescriptorCreator()
{
return new MojoDescriptorCreator( new PluginVersionResolverStub(), new BuildPluginManagerStub(),
new PluginPrefixResolverStub() );

View File

@ -122,7 +122,8 @@ public class LifecycleWeaveBuilderTest
final LoggerStub loggerStub = new LoggerStub();
final LifecycleDependencyResolver lifecycleDependencyResolver =
new LifecycleDependencyResolver( new ProjectDependenciesResolverStub(), loggerStub );
return new LifecycleWeaveBuilder( mojoExecutor, builderCommon, loggerStub, new ExecutionEventCatapultStub() );
return new LifecycleWeaveBuilder( mojoExecutor, builderCommon, loggerStub, lifecycleDependencyResolver,
new ExecutionEventCatapultStub() );
}
private BuilderCommon getBuilderCommon()

View File

@ -168,6 +168,7 @@ public class LifecycleExecutionPlanCalculatorStub
MojoExecution result = new MojoExecution( plugin, goal, executionId );
result.setConfiguration( new Xpp3Dom( executionId + "-" + goal ) );
result.setMojoDescriptor( mojoDescriptor );
result.setLifecyclePhase( mojoDescriptor.getPhase() );
return result;
}