package hudson.model;
import hudson.model.queue.QueueTaskFuture;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.SleepBuilder;
public class RunMapTest {
@Rule public JenkinsRule r = new JenkinsRule();
// TODO https://github.com/jenkinsci/jenkins/pull/2438: @Rule public LoggerRule logs = new LoggerRule();
/**
* Makes sure that reloading the project while a build is in progress won't clobber that in-progress build.
*/
@Issue("JENKNS-12318")
@Test public void reloadWhileBuildIsInProgress() throws Exception {
FreeStyleProject p = r.createFreeStyleProject();
// want some completed build records
FreeStyleBuild b1 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
// now create a build that hangs until we signal the OneShotEvent
p.getBuildersList().add(new SleepBuilder(9999999));
FreeStyleBuild b2 = p.scheduleBuild2(0).waitForStart();
assertEquals(2, b2.number);
// now reload
p.updateByXml((Source) new StreamSource(p.getConfigFile().getFile()));
// we should still see the same object for #2 because that's in progress
assertSame(p.getBuildByNumber(b2.number), b2);
// build #1 should be reloaded
assertNotSame(b1, p.getBuildByNumber(1));
// and reference gets fixed up
b1 = p.getBuildByNumber(1);
assertSame(b1.getNextBuild(), b2);
assertSame(b2.getPreviousBuild(), b1);
}
@Issue("JENKINS-27530")
@Test public void reloadWhileBuildIsInQueue() throws Exception {
//logs.record(Queue.class, Level.FINE);
FreeStyleProject p = r.createFreeStyleProject("p");
p.getBuildersList().add(new SleepBuilder(9999999));
r.jenkins.setNumExecutors(1);
assertEquals(1, p.scheduleBuild2(0).waitForStart().number);
p.scheduleBuild2(0);
// Note that the bug does not reproduce simply from p.doReload(), since in that case Job identity remains intact:
r.jenkins.reload();
p = r.jenkins.getItemByFullName("p", FreeStyleProject.class);
FreeStyleBuild b1 = p.getLastBuild();
assertEquals(1, b1.getNumber());
/* Currently fails since Run.project is final. But anyway that is not the problem:
assertEquals(p, b1.getParent());
*/
Queue.Item[] items = Queue.getInstance().getItems();
assertEquals(1, items.length);
assertEquals(p, items[0].task); // the real issue: assignBuildNumber was being called on the wrong Job
QueueTaskFuture<Queue.Executable> b2f = items[0].getFuture();
b1.getExecutor().interrupt();
r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b1));
FreeStyleBuild b2 = (FreeStyleBuild) b2f.waitForStart();
assertEquals(2, b2.getNumber());
assertEquals(p, b2.getParent());
b2.getExecutor().interrupt();
r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b2));
FreeStyleBuild b3 = p.scheduleBuild2(0).waitForStart();
assertEquals(3, b3.getNumber());
assertEquals(p, b3.getParent());
b3.getExecutor().interrupt();
r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b3));
}
/**
* Testing if the lazy loading can gracefully tolerate a RuntimeException during unmarshalling.
*/
@Issue("JENKINS-15533")
@Test public void runtimeExceptionInUnmarshalling() throws Exception {
FreeStyleProject p = r.createFreeStyleProject();
FreeStyleBuild b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
b.addAction(new BombAction());
b.save();
p._getRuns().purgeCache();
b = p.getBuildByNumber(b.number);
// Original test assumed that b == null, but after JENKINS-21024 this is no longer true,
// so this may not really be testing anything interesting:
assertNotNull(b);
assertNull(b.getAction(BombAction.class));
assertTrue(bombed);
}
public static class BombAction extends InvisibleAction {
public Object readResolve() {
bombed = true;
throw new NullPointerException();
}
}
private static boolean bombed;
@Issue("JENKINS-25788")
@Test public void remove() throws Exception {
FreeStyleProject p = r.createFreeStyleProject();
FreeStyleBuild b1 = r.buildAndAssertSuccess(p);
FreeStyleBuild b2 = r.buildAndAssertSuccess(p);
RunMap<FreeStyleBuild> runs = p._getRuns();
assertEquals(2, runs.size());
assertTrue(runs.remove(b1));
assertEquals(1, runs.size());
assertFalse(runs.remove(b1));
assertEquals(1, runs.size());
assertTrue(runs.remove(b2));
assertEquals(0, runs.size());
assertFalse(runs.remove(b2));
assertEquals(0, runs.size());
}
}