/** * ***************************************************************************** * * Copyright (c) 2004-2010 Oracle Corporation. * * All rights reserved. This program and the accompanying materials are made * available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * ****************************************************************************** */ package hudson.model; import hudson.model.RunMap.RunValue; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.SortedMap; import java.util.TreeMap; import junit.framework.Assert; import junit.framework.TestCase; /** * Unit test for {@link Job}. */ public class SimpleJobTest extends TestCase { public void testGetEstimatedDuration() throws IOException { final SortedMap<Integer, TestBuild> runs = new TreeMap<Integer, TestBuild>(); Job project = createMockProject(runs); TestBuild previousPreviousBuild = new TestBuild(project, Result.SUCCESS, 20, null); runs.put(3, previousPreviousBuild); TestBuild previousBuild = new TestBuild(project, Result.SUCCESS, 15, previousPreviousBuild); runs.put(2, previousBuild); TestBuild lastBuild = new TestBuild(project, Result.SUCCESS, 42, previousBuild); runs.put(1, lastBuild); // without assuming to know to much about the internal calculation // we can only assume that the result is between the maximum and the minimum Assert.assertTrue(project.getEstimatedDuration() < 42); Assert.assertTrue(project.getEstimatedDuration() > 15); } public void testGetEstimatedDurationWithOneRun() throws IOException { final SortedMap<Integer, TestBuild> runs = new TreeMap<Integer, TestBuild>(); Job project = createMockProject(runs); TestBuild lastBuild = new TestBuild(project, Result.SUCCESS, 42, null); runs.put(1, lastBuild); Assert.assertEquals(42, project.getEstimatedDuration()); } public void testGetEstimatedDurationWithFailedRun() throws IOException { final SortedMap<Integer, TestBuild> runs = new TreeMap<Integer, TestBuild>(); Job project = createMockProject(runs); TestBuild lastBuild = new TestBuild(project, Result.FAILURE, 42, null); runs.put(1, lastBuild); Assert.assertEquals(-1, project.getEstimatedDuration()); } public void testGetEstimatedDurationWithNoRuns() throws IOException { final SortedMap<Integer, TestBuild> runs = new TreeMap<Integer, TestBuild>(); Job project = createMockProject(runs); Assert.assertEquals(-1, project.getEstimatedDuration()); } public void testGetEstimatedDurationIfPrevious3BuildsFailed() throws IOException { final SortedMap<Integer, TestBuild> runs = new TreeMap<Integer, TestBuild>(); Job project = createMockProject(runs); TestBuild prev4Build = new TestBuild(project, Result.SUCCESS, 1, null); runs.put(5, prev4Build); TestBuild prev3Build = new TestBuild(project, Result.SUCCESS, 1, prev4Build); runs.put(4, prev3Build); TestBuild previous2Build = new TestBuild(project, Result.FAILURE, 50, prev3Build); runs.put(3, previous2Build); TestBuild previousBuild = new TestBuild(project, Result.FAILURE, 50, previous2Build); runs.put(2, previousBuild); TestBuild lastBuild = new TestBuild(project, Result.FAILURE, 50, previousBuild); runs.put(1, lastBuild); // failed builds must not be used. Instead the last successful builds before them // must be used Assert.assertEquals(project.getEstimatedDuration(), 1); } private Job createMockProject(final SortedMap<Integer, TestBuild> runs) { Job project = new Job(null, "name") { int i = 1; @Override public int assignBuildNumber() throws IOException { return i++; } @Override public SortedMap<Integer, ? extends Run> _getRuns() { return runs; } @Override public boolean isBuildable() { return true; } @Override protected void removeRun(Run run) { } @Override public BuildHistory getBuildHistoryData() { return createMockBuildHistory(_getRuns()); } public long getEstimatedDuration() { List<Run> builds = getLastBuildsOverThreshold(3, Result.UNSTABLE); if (builds.isEmpty()) { return -1; } long totalDuration = 0; for (Run b : builds) { totalDuration += b.getDuration(); } if (totalDuration == 0) { return -1; } return Math.round((double) totalDuration / builds.size()); } }; return project; } private BuildHistory createMockBuildHistory(final SortedMap<Integer, ? extends Run> runs) { return new BuildHistory() { @Override public BuildHistory.Record getFirst() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLast() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLastCompleted() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLastFailed() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLastStable() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLastUnstable() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLastSuccessful() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public BuildHistory.Record getLastUnsuccessful() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public List<Record> getLastRecordsOverThreshold(int n, Result threshold) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastBuild() { try { return runs.get(runs.lastKey()); } catch (NoSuchElementException e) { return null; } } @Override public Run getFirstBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastSuccessfulBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastUnsuccessfulBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastUnstableBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastStableBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastFailedBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public Run getLastCompletedBuild() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public List getLastBuildsOverThreshold(int n, Result threshold) { List<Run> result = new ArrayList<Run>(n); Run r = getLastBuild(); while (r != null && result.size() < n) { if (!r.isBuilding() && (r.getResult() != null && r.getResult().isBetterOrEqualTo(threshold))) { result.add(r); } r = r.getPreviousBuild(); } return result; } @Override public Iterator iterator() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public List allRecords() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }; } private static class TestBuild extends Run { public TestBuild(Job project, Result result, long duration, TestBuild previousBuild) throws IOException { super(project); setResult(result); this.duration = duration; this.previousBuild = previousBuild; } @Override public int compareTo(Run o) { return 0; } @Override public boolean isBuilding() { return false; } @Override public String toString() { return "TestBuild"; } } }