提交 b9b433b1 编写于 作者: K kutzi

[FIXED HUDSON-6544] calculate estimated remaining time for incremental Maven...

[FIXED HUDSON-6544] calculate estimated remaining time for incremental Maven builds based on the modules which are actually being build

git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@36164 71c3de6d-444a-0410-be80-ed276b4c234a
上级 6f007c88
......@@ -269,7 +269,7 @@ public class Executor extends Thread implements ModelObject {
public int getProgress() {
Queue.Executable e = executable;
if(e==null) return -1;
long d = getParentOf(e).getEstimatedDuration();
long d = e.getEstimatedDuration();
if(d<0) return -1;
int num = (int)(getElapsedTime()*100/d);
......@@ -290,7 +290,7 @@ public class Executor extends Thread implements ModelObject {
if(e==null) return false;
long elapsed = getElapsedTime();
long d = getParentOf(e).getEstimatedDuration();
long d = e.getEstimatedDuration();
if(d>=0) {
// if it's taking 10 times longer than ETA, consider it stuck
return d*10 < elapsed;
......@@ -322,7 +322,7 @@ public class Executor extends Thread implements ModelObject {
Queue.Executable e = executable;
if(e==null) return Messages.Executor_NotAvailable();
long d = getParentOf(e).getEstimatedDuration();
long d = e.getEstimatedDuration();
if(d<0) return Messages.Executor_NotAvailable();
long eta = d-getElapsedTime();
......@@ -339,7 +339,7 @@ public class Executor extends Thread implements ModelObject {
Queue.Executable e = executable;
if(e==null) return -1;
long d = getParentOf(e).getEstimatedDuration();
long d = e.getEstimatedDuration();
if(d<0) return -1;
long eta = d-getElapsedTime();
......@@ -379,7 +379,7 @@ public class Executor extends Thread implements ModelObject {
if (isIdle())
return Math.max(finishTime, owner.getConnectTime());
else {
return Math.max(startTime + Math.max(0, getParentOf(executable).getEstimatedDuration()),
return Math.max(startTime + Math.max(0, executable.getEstimatedDuration()),
System.currentTimeMillis() + 15000);
}
}
......
......@@ -1111,6 +1111,15 @@ public class Queue extends ResourceController implements Saveable {
*/
void run();
/**
* Estimate of how long will it take to execute this executable.
* Measured in milliseconds.
*
* @return -1 if it's impossible to estimate.
* @since 1.383
*/
long getEstimatedDuration();
/**
* Used to render the HTML. Should be a human readable text of what this executable is.
*/
......
......@@ -690,6 +690,29 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
return r;
}
/**
* Returns the last 'numberOfBuilds' builds with a build result >= 'threshold'
*
* @return a list with the builds (youngest build first).
* May be smaller than 'numberOfBuilds' or even empty
* if not enough builds satisfying the threshold have been found. Never null.
* @since 1.383
*/
public List<RunT> getPreviousBuildsOverThreshold(int numberOfBuilds, Result threshold) {
List<RunT> result = new ArrayList<RunT>(numberOfBuilds);
RunT r = getPreviousBuild();
while (r != null && result.size() < numberOfBuilds) {
if (!r.isBuilding() &&
(r.getResult() != null && r.getResult().isBetterOrEqualTo(threshold))) {
result.add(r);
}
r = r.getPreviousBuild();
}
return result;
}
public RunT getNextBuild() {
return nextBuild;
}
......@@ -1740,6 +1763,17 @@ public abstract class Run <JobT extends Job<JobT,RunT>,RunT extends Run<JobT,Run
return job.getBuildByNumber(number);
}
/**
* Returns the estimated duration for this run if it is currently running.
* Default to {@link Job#getEstimatedDuration()}, may be overridden in subclasses
* if duration may depend on run specific parameters (like incremental Maven builds).
*
* @return the estimated duration in milliseconds
* @since 1.383
*/
public long getEstimatedDuration() {
return project.getEstimatedDuration();
}
public static final XStream XSTREAM = new XStream2();
static {
......
......@@ -212,6 +212,64 @@ public class MavenModuleSetBuild extends AbstractMavenBuild<MavenModuleSet,Maven
return r;
}
/**
* Returns the estimated duration for this builds.
* Takes only the modules into account which are actually being build in
* case of incremental builds.
*/
@Override
public long getEstimatedDuration() {
if (!project.isIncrementalBuild()) {
return super.getEstimatedDuration();
}
long result = 0;
Map<MavenModule, List<MavenBuild>> moduleBuilds = getModuleBuilds();
for (List<MavenBuild> builds : moduleBuilds.values()) {
if (!builds.isEmpty()) {
MavenBuild build = builds.get(0);
if (build.getResult() != Result.NOT_BUILT) {
if (build.getEstimatedDuration() != -1) {
result += build.getEstimatedDuration();
}
}
}
}
result += estimateModuleSetBuildDurationOverhead(3);
return result != 0 ? result : -1;
}
/**
* Estimates the duration overhead the {@link MavenModuleSetBuild} itself adds
* to the sum of duration of the module builds.
*/
private long estimateModuleSetBuildDurationOverhead(int numberOfBuilds) {
List<MavenModuleSetBuild> moduleSetBuilds = getPreviousBuildsOverThreshold(numberOfBuilds, Result.UNSTABLE);
if (moduleSetBuilds.isEmpty()) {
return 0;
}
long overhead = 0;
for(MavenModuleSetBuild moduleSetBuild : moduleSetBuilds) {
long sumOfModuleBuilds = 0;
for (List<MavenBuild> builds : moduleSetBuild.getModuleBuilds().values()) {
if (!builds.isEmpty()) {
MavenBuild moduleBuild = builds.get(0);
sumOfModuleBuilds += moduleBuild.getDuration();
}
}
overhead += Math.max(0, moduleSetBuild.getDuration() - sumOfModuleBuilds);
}
return Math.round((double)overhead / moduleSetBuilds.size());
}
@Override
public synchronized void delete() throws IOException {
super.delete();
......
......@@ -110,6 +110,33 @@ public class MavenMultiModuleTest extends HudsonTestCase {
pBuild.getDuration() >= summedModuleDuration);
}
@Bug(6544)
public void testEstimatedDurationForIncrementalMultiModMaven()
throws Exception {
configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_21);
MavenModuleSet m = createMavenProject();
m.getReporters().add(new TestReporter());
m.setScm(new ExtractResourceWithChangesSCM(getClass().getResource(
"maven-multimod.zip"), getClass().getResource(
"maven-multimod-changes.zip")));
buildAndAssertSuccess(m);
// Now run a second, incremental build with the changes.
m.setIncrementalBuild(true);
buildAndAssertSuccess(m);
MavenModuleSetBuild lastBuild = m.getLastBuild();
MavenModuleSetBuild previousBuild = lastBuild.getPreviousBuild();
assertNull("There should be only one previous build", previousBuild.getPreviousBuild());
// since the estimated duration is calculated based on the previous builds
// and there was only one previous build (which built all modules) and this build
// did only build one module, the estimated duration of this build must be
// smaller than the duration of the previous build.
assertTrue(lastBuild.getEstimatedDuration() < previousBuild.getDuration());
}
/**
* NPE in {@code getChangeSetFor(m)} in {@link MavenModuleSetBuild} when incremental build is
* enabled and a new module is added.
......
......@@ -61,6 +61,10 @@ public class WideExecutionTest extends HudsonTestCase {
e.printStackTrace();
}
}
public long getEstimatedDuration() {
return 0;
}
};
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册