提交 2f4d8907 编写于 作者: J Jesse Glick 提交者: Oliver Gondža

JUnit 4.

(cherry picked from commit 778e9e19)
上级 4c4fb740
...@@ -47,7 +47,7 @@ import hudson.security.GlobalMatrixAuthorizationStrategy; ...@@ -47,7 +47,7 @@ import hudson.security.GlobalMatrixAuthorizationStrategy;
import hudson.security.SparseACL; import hudson.security.SparseACL;
import hudson.slaves.DumbSlave; import hudson.slaves.DumbSlave;
import hudson.slaves.DummyCloudImpl; import hudson.slaves.DummyCloudImpl;
import hudson.slaves.NodeProvisioner; import hudson.slaves.NodeProvisionerRule;
import hudson.tasks.Shell; import hudson.tasks.Shell;
import hudson.triggers.SCMTrigger.SCMTriggerCause; import hudson.triggers.SCMTrigger.SCMTriggerCause;
import hudson.triggers.TimerTrigger.TimerTriggerCause; import hudson.triggers.TimerTrigger.TimerTriggerCause;
...@@ -65,7 +65,6 @@ import java.util.concurrent.Future; ...@@ -65,7 +65,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
...@@ -80,8 +79,11 @@ import org.apache.commons.fileupload.FileUploadException; ...@@ -80,8 +79,11 @@ import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.jvnet.hudson.test.Bug; import static org.junit.Assert.*;
import org.jvnet.hudson.test.HudsonTestCase; 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.MockQueueItemAuthenticator; import org.jvnet.hudson.test.MockQueueItemAuthenticator;
import org.jvnet.hudson.test.SequenceLock; import org.jvnet.hudson.test.SequenceLock;
import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestBuilder;
...@@ -93,22 +95,25 @@ import org.mortbay.jetty.servlet.ServletHolder; ...@@ -93,22 +95,25 @@ import org.mortbay.jetty.servlet.ServletHolder;
/** /**
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public class QueueTest extends HudsonTestCase { public class QueueTest {
@Rule public JenkinsRule r = new NodeProvisionerRule(-1, 0, 10);
/** /**
* Checks the persistence of queue. * Checks the persistence of queue.
*/ */
public void testPersistence() throws Exception { @Test public void persistence() throws Exception {
Queue q = jenkins.getQueue(); Queue q = r.jenkins.getQueue();
// prevent execution to push stuff into the queue // prevent execution to push stuff into the queue
jenkins.setNumExecutors(0); r.jenkins.setNumExecutors(0);
jenkins.setNodes(jenkins.getNodes()); r.jenkins.setNodes(r.jenkins.getNodes());
FreeStyleProject testProject = createFreeStyleProject("test"); FreeStyleProject testProject = r.createFreeStyleProject("test");
testProject.scheduleBuild(new UserIdCause()); testProject.scheduleBuild(new UserIdCause());
q.save(); q.save();
System.out.println(FileUtils.readFileToString(new File(jenkins.getRootDir(), "queue.xml"))); System.out.println(FileUtils.readFileToString(new File(r.jenkins.getRootDir(), "queue.xml")));
assertEquals(1,q.getItems().length); assertEquals(1,q.getItems().length);
q.clear(); q.clear();
...@@ -125,18 +130,18 @@ public class QueueTest extends HudsonTestCase { ...@@ -125,18 +130,18 @@ public class QueueTest extends HudsonTestCase {
/** /**
* Can {@link Queue} successfully recover removal? * Can {@link Queue} successfully recover removal?
*/ */
public void testPersistence2() throws Exception { @Test public void persistence2() throws Exception {
Queue q = jenkins.getQueue(); Queue q = r.jenkins.getQueue();
// prevent execution to push stuff into the queue // prevent execution to push stuff into the queue
jenkins.setNumExecutors(0); r.jenkins.setNumExecutors(0);
jenkins.setNodes(jenkins.getNodes()); r.jenkins.setNodes(r.jenkins.getNodes());
FreeStyleProject testProject = createFreeStyleProject("test"); FreeStyleProject testProject = r.createFreeStyleProject("test");
testProject.scheduleBuild(new UserIdCause()); testProject.scheduleBuild(new UserIdCause());
q.save(); q.save();
System.out.println(FileUtils.readFileToString(new File(jenkins.getRootDir(), "queue.xml"))); System.out.println(FileUtils.readFileToString(new File(r.jenkins.getRootDir(), "queue.xml")));
assertEquals(1,q.getItems().length); assertEquals(1,q.getItems().length);
q.clear(); q.clear();
...@@ -151,11 +156,11 @@ public class QueueTest extends HudsonTestCase { ...@@ -151,11 +156,11 @@ public class QueueTest extends HudsonTestCase {
/** /**
* {@link hudson.model.Queue.BlockedItem} is not static. Make sure its persistence doesn't end up re-persisting the whole Queue instance. * {@link hudson.model.Queue.BlockedItem} is not static. Make sure its persistence doesn't end up re-persisting the whole Queue instance.
*/ */
public void testPersistenceBlockedItem() throws Exception { @Test public void persistenceBlockedItem() throws Exception {
Queue q = jenkins.getQueue(); Queue q = r.jenkins.getQueue();
final SequenceLock seq = new SequenceLock(); final SequenceLock seq = new SequenceLock();
FreeStyleProject p = createFreeStyleProject(); FreeStyleProject p = r.createFreeStyleProject();
p.getBuildersList().add(new TestBuilder() { p.getBuildersList().add(new TestBuilder() {
@Override @Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
...@@ -204,7 +209,7 @@ public class QueueTest extends HudsonTestCase { ...@@ -204,7 +209,7 @@ public class QueueTest extends HudsonTestCase {
} }
} }
public void testFileItemPersistence() throws Exception { @Test public void fileItemPersistence() throws Exception {
// TODO: write a synchronous connector? // TODO: write a synchronous connector?
byte[] testData = new byte[1024]; byte[] testData = new byte[1024];
for( int i=0; i<testData.length; i++ ) testData[i] = (byte)i; for( int i=0; i<testData.length; i++ ) testData[i] = (byte)i;
...@@ -220,11 +225,10 @@ public class QueueTest extends HudsonTestCase { ...@@ -220,11 +225,10 @@ public class QueueTest extends HudsonTestCase {
server.start(); server.start();
localPort = connector.getLocalPort();
try { try {
WebClient wc = new WebClient(); JenkinsRule.WebClient wc = r.createWebClient();
HtmlPage p = (HtmlPage) wc.getPage("http://localhost:" + localPort + '/'); @SuppressWarnings("deprecation")
HtmlPage p = (HtmlPage) wc.getPage("http://localhost:" + connector.getLocalPort() + '/');
HtmlForm f = p.getFormByName("main"); HtmlForm f = p.getFormByName("main");
HtmlFileInput input = (HtmlFileInput) f.getInputByName("test"); HtmlFileInput input = (HtmlFileInput) f.getInputByName("test");
input.setData(testData); input.setData(testData);
...@@ -234,12 +238,12 @@ public class QueueTest extends HudsonTestCase { ...@@ -234,12 +238,12 @@ public class QueueTest extends HudsonTestCase {
} }
} }
public void testFoldableCauseAction() throws Exception { @Test public void foldableCauseAction() throws Exception {
final OneShotEvent buildStarted = new OneShotEvent(); final OneShotEvent buildStarted = new OneShotEvent();
final OneShotEvent buildShouldComplete = new OneShotEvent(); final OneShotEvent buildShouldComplete = new OneShotEvent();
setQuietPeriod(0); r.setQuietPeriod(0);
FreeStyleProject project = createFreeStyleProject(); FreeStyleProject project = r.createFreeStyleProject();
// Make build sleep a while so it blocks new builds // Make build sleep a while so it blocks new builds
project.getBuildersList().add(new TestBuilder() { project.getBuildersList().add(new TestBuilder() {
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
...@@ -288,7 +292,7 @@ public class QueueTest extends HudsonTestCase { ...@@ -288,7 +292,7 @@ public class QueueTest extends HudsonTestCase {
causes.toString()); causes.toString());
// View for build should group duplicates // View for build should group duplicates
WebClient wc = new WebClient(); JenkinsRule.WebClient wc = r.createWebClient();
String nl = System.getProperty("line.separator"); String nl = System.getProperty("line.separator");
String buildPage = wc.getPage(build, "").asText().replace(nl," "); String buildPage = wc.getPage(build, "").asText().replace(nl," ");
assertTrue("Build page should combine duplicates and show counts: " + buildPage, assertTrue("Build page should combine duplicates and show counts: " + buildPage,
...@@ -300,54 +304,42 @@ public class QueueTest extends HudsonTestCase { ...@@ -300,54 +304,42 @@ public class QueueTest extends HudsonTestCase {
+ "Started by remote host 1.2.3.4 with note: foo")); + "Started by remote host 1.2.3.4 with note: foo"));
} }
@Bug(8790) @Issue("JENKINS-8790")
public void testFlyweightTasks() throws Exception { @Test public void flyweightTasks() throws Exception {
MatrixProject m = createMatrixProject(); MatrixProject m = r.createMatrixProject();
m.addProperty(new ParametersDefinitionProperty( m.addProperty(new ParametersDefinitionProperty(
new StringParameterDefinition("FOO","value") new StringParameterDefinition("FOO","value")
)); ));
m.getBuildersList().add(new Shell("sleep 3")); m.getBuildersList().add(new Shell("sleep 3"));
m.setAxes(new AxisList(new TextAxis("DoesntMatter", "aaa","bbb"))); m.setAxes(new AxisList(new TextAxis("DoesntMatter", "aaa","bbb")));
List<Future<MatrixBuild>> r = new ArrayList<Future<MatrixBuild>>(); List<Future<MatrixBuild>> futures = new ArrayList<Future<MatrixBuild>>();
for (int i=0; i<3; i++) for (int i = 0; i < 3; i++) {
r.add(m.scheduleBuild2(0,new UserIdCause(),new ParametersAction(new StringParameterValue("FOO","value"+i)))); futures.add(m.scheduleBuild2(0, new UserIdCause(), new ParametersAction(new StringParameterValue("FOO", "value" + i))));
}
for (Future<MatrixBuild> f : r) for (Future<MatrixBuild> f : futures) {
assertBuildStatusSuccess(f); r.assertBuildStatusSuccess(f);
}
} }
private int INITIALDELAY; @Issue("JENKINS-7291")
private int RECURRENCEPERIOD; @Test public void flyweightTasksWithoutMasterExecutors() throws Exception {
@Override protected void setUp() throws Exception { DummyCloudImpl cloud = new DummyCloudImpl(r, 0);
INITIALDELAY = NodeProvisioner.NodeProvisionerInvoker.INITIALDELAY; cloud.label = r.jenkins.getLabel("remote");
NodeProvisioner.NodeProvisionerInvoker.INITIALDELAY = 0; r.jenkins.clouds.add(cloud);
RECURRENCEPERIOD = NodeProvisioner.NodeProvisionerInvoker.RECURRENCEPERIOD; r.jenkins.setNumExecutors(0);
NodeProvisioner.NodeProvisionerInvoker.RECURRENCEPERIOD = 10; r.jenkins.setNodes(Collections.<Node>emptyList());
super.setUp(); MatrixProject m = r.createMatrixProject();
}
@Override protected void tearDown() throws Exception {
super.tearDown();
NodeProvisioner.NodeProvisionerInvoker.INITIALDELAY = INITIALDELAY;
NodeProvisioner.NodeProvisionerInvoker.RECURRENCEPERIOD = RECURRENCEPERIOD;
}
@Bug(7291)
public void testFlyweightTasksWithoutMasterExecutors() throws Exception {
DummyCloudImpl cloud = new DummyCloudImpl(this, 0);
cloud.label = jenkins.getLabel("remote");
jenkins.clouds.add(cloud);
jenkins.setNumExecutors(0);
jenkins.setNodes(Collections.<Node>emptyList());
MatrixProject m = createMatrixProject();
m.setAxes(new AxisList(new LabelAxis("label", Arrays.asList("remote")))); m.setAxes(new AxisList(new LabelAxis("label", Arrays.asList("remote"))));
MatrixBuild build; MatrixBuild build;
try { try {
build = m.scheduleBuild2(0).get(60, TimeUnit.SECONDS); build = m.scheduleBuild2(0).get(60, TimeUnit.SECONDS);
} catch (TimeoutException x) { } catch (TimeoutException x) {
throw (AssertionError) new AssertionError(jenkins.getQueue().getApproximateItemsQuickly().toString()).initCause(x); throw (AssertionError) new AssertionError(r.jenkins.getQueue().getApproximateItemsQuickly().toString()).initCause(x);
} }
assertBuildStatusSuccess(build); r.assertBuildStatusSuccess(build);
assertEquals("", build.getBuiltOnStr()); assertEquals("", build.getBuiltOnStr());
List<MatrixRun> runs = build.getRuns(); List<MatrixRun> runs = build.getRuns();
assertEquals(1, runs.size()); assertEquals(1, runs.size());
...@@ -397,14 +389,14 @@ public class QueueTest extends HudsonTestCase { ...@@ -397,14 +389,14 @@ public class QueueTest extends HudsonTestCase {
} }
} }
public void testTaskEquality() throws Exception { @Test public void taskEquality() throws Exception {
AtomicInteger cnt = new AtomicInteger(); AtomicInteger cnt = new AtomicInteger();
ScheduleResult result = jenkins.getQueue().schedule2(new TestTask(cnt), 0); ScheduleResult result = r.jenkins.getQueue().schedule2(new TestTask(cnt), 0);
assertTrue(result.isCreated()); assertTrue(result.isCreated());
WaitingItem item = result.getCreateItem(); WaitingItem item = result.getCreateItem();
assertFalse(jenkins.getQueue().schedule2(new TestTask(cnt), 0).isCreated()); assertFalse(r.jenkins.getQueue().schedule2(new TestTask(cnt), 0).isCreated());
item.getFuture().get(); item.getFuture().get();
waitUntilNoActivity(); r.waitUntilNoActivity();
assertEquals(1, cnt.get()); assertEquals(1, cnt.get());
} }
private static class TestTask extends AbstractQueueTask { private static class TestTask extends AbstractQueueTask {
...@@ -443,9 +435,9 @@ public class QueueTest extends HudsonTestCase { ...@@ -443,9 +435,9 @@ public class QueueTest extends HudsonTestCase {
} }
} }
public void testWaitForStart() throws Exception { @Test public void waitForStart() throws Exception {
final OneShotEvent ev = new OneShotEvent(); final OneShotEvent ev = new OneShotEvent();
FreeStyleProject p = createFreeStyleProject(); FreeStyleProject p = r.createFreeStyleProject();
p.getBuildersList().add(new TestBuilder() { p.getBuildersList().add(new TestBuilder() {
@Override @Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
...@@ -461,20 +453,17 @@ public class QueueTest extends HudsonTestCase { ...@@ -461,20 +453,17 @@ public class QueueTest extends HudsonTestCase {
assertSame(p,b.getProject()); assertSame(p,b.getProject());
ev.signal(); // let the build complete ev.signal(); // let the build complete
FreeStyleBuild b2 = assertBuildStatusSuccess(v); FreeStyleBuild b2 = r.assertBuildStatusSuccess(v);
assertSame(b,b2); assertSame(b,b2);
} }
@Inject
QueueItemAuthenticatorConfiguration qac;
/** /**
* Make sure that the running build actually carries an credential. * Make sure that the running build actually carries an credential.
*/ */
public void testAccessControl() throws Exception { @Test public void accessControl() throws Exception {
configureUserRealm(); r.configureUserRealm();
FreeStyleProject p = createFreeStyleProject(); FreeStyleProject p = r.createFreeStyleProject();
qac.getAuthenticators().add(new MockQueueItemAuthenticator(Collections.singletonMap(p.getFullName(), alice))); QueueItemAuthenticatorConfiguration.get().getAuthenticators().add(new MockQueueItemAuthenticator(Collections.singletonMap(p.getFullName(), alice)));
p.getBuildersList().add(new TestBuilder() { p.getBuildersList().add(new TestBuilder() {
@Override @Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
...@@ -482,7 +471,7 @@ public class QueueTest extends HudsonTestCase { ...@@ -482,7 +471,7 @@ public class QueueTest extends HudsonTestCase {
return true; return true;
} }
}); });
assertBuildStatusSuccess(p.scheduleBuild2(0)); r.assertBuildStatusSuccess(p.scheduleBuild2(0));
} }
private static Authentication alice = new UsernamePasswordAuthenticationToken("alice","alice",new GrantedAuthority[0]); private static Authentication alice = new UsernamePasswordAuthenticationToken("alice","alice",new GrantedAuthority[0]);
...@@ -494,14 +483,14 @@ public class QueueTest extends HudsonTestCase { ...@@ -494,14 +483,14 @@ public class QueueTest extends HudsonTestCase {
* We do this test by letting a build run twice to determine its natural home, * We do this test by letting a build run twice to determine its natural home,
* and then introduce a security restriction to prohibit that. * and then introduce a security restriction to prohibit that.
*/ */
public void testPermissionSensitiveSlaveAllocations() throws Exception { @Test public void permissionSensitiveSlaveAllocations() throws Exception {
jenkins.setNumExecutors(0); // restrict builds to those slaves r.jenkins.setNumExecutors(0); // restrict builds to those slaves
DumbSlave s1 = createSlave(); DumbSlave s1 = r.createSlave();
DumbSlave s2 = createSlave(); DumbSlave s2 = r.createSlave();
configureUserRealm(); r.configureUserRealm();
FreeStyleProject p = createFreeStyleProject(); FreeStyleProject p = r.createFreeStyleProject();
qac.getAuthenticators().add(new MockQueueItemAuthenticator(Collections.singletonMap(p.getFullName(), alice))); QueueItemAuthenticatorConfiguration.get().getAuthenticators().add(new MockQueueItemAuthenticator(Collections.singletonMap(p.getFullName(), alice)));
p.getBuildersList().add(new TestBuilder() { p.getBuildersList().add(new TestBuilder() {
@Override @Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
...@@ -510,8 +499,8 @@ public class QueueTest extends HudsonTestCase { ...@@ -510,8 +499,8 @@ public class QueueTest extends HudsonTestCase {
} }
}); });
final FreeStyleBuild b1 = assertBuildStatusSuccess(p.scheduleBuild2(0)); final FreeStyleBuild b1 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
final FreeStyleBuild b2 = assertBuildStatusSuccess(p.scheduleBuild2(0)); final FreeStyleBuild b2 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
// scheduling algorithm would prefer running the same job on the same node // scheduling algorithm would prefer running the same job on the same node
// kutzi: 'prefer' != 'enforce', therefore disabled this assertion: assertSame(b1.getBuiltOn(),b2.getBuiltOn()); // kutzi: 'prefer' != 'enforce', therefore disabled this assertion: assertSame(b1.getBuiltOn(),b2.getBuiltOn());
...@@ -530,18 +519,18 @@ public class QueueTest extends HudsonTestCase { ...@@ -530,18 +519,18 @@ public class QueueTest extends HudsonTestCase {
} }
}; };
auth.add(Jenkins.ADMINISTER,"anonymous"); auth.add(Jenkins.ADMINISTER,"anonymous");
jenkins.setAuthorizationStrategy(auth); r.jenkins.setAuthorizationStrategy(auth);
// now that we prohibit alice to do a build on the same node, the build should run elsewhere // now that we prohibit alice to do a build on the same node, the build should run elsewhere
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
FreeStyleBuild b3 = assertBuildStatusSuccess(p.scheduleBuild2(0)); FreeStyleBuild b3 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
assertNotSame(b3.getBuiltOnStr(), b1.getBuiltOnStr()); assertNotSame(b3.getBuiltOnStr(), b1.getBuiltOnStr());
} }
} }
public void testPendingsConsistenceAfterErrorDuringMaintain() throws IOException, ExecutionException, InterruptedException{ @Test public void pendingsConsistenceAfterErrorDuringMaintain() throws IOException, ExecutionException, InterruptedException{
FreeStyleProject project1 = createFreeStyleProject(); FreeStyleProject project1 = r.createFreeStyleProject();
FreeStyleProject project2 = createFreeStyleProject(); FreeStyleProject project2 = r.createFreeStyleProject();
TopLevelItemDescriptor descriptor = new TopLevelItemDescriptor(FreeStyleProject.class){ TopLevelItemDescriptor descriptor = new TopLevelItemDescriptor(FreeStyleProject.class){
@Override @Override
public FreeStyleProject newInstance(ItemGroup parent, String name) { public FreeStyleProject newInstance(ItemGroup parent, String name) {
...@@ -563,14 +552,14 @@ public class QueueTest extends HudsonTestCase { ...@@ -563,14 +552,14 @@ public class QueueTest extends HudsonTestCase {
return "simulate-error"; return "simulate-error";
} }
}; };
FreeStyleProject projectError = (FreeStyleProject) jenkins.createProject(descriptor, "throw-error"); FreeStyleProject projectError = (FreeStyleProject) r.jenkins.createProject(descriptor, "throw-error");
project1.setAssignedLabel(jenkins.getSelfLabel()); project1.setAssignedLabel(r.jenkins.getSelfLabel());
project2.setAssignedLabel(jenkins.getSelfLabel()); project2.setAssignedLabel(r.jenkins.getSelfLabel());
project1.getBuildersList().add(new Shell("sleep 2")); project1.getBuildersList().add(new Shell("sleep 2"));
project1.scheduleBuild2(0); project1.scheduleBuild2(0);
QueueTaskFuture<FreeStyleBuild> v = project2.scheduleBuild2(0); QueueTaskFuture<FreeStyleBuild> v = project2.scheduleBuild2(0);
projectError.scheduleBuild2(0); projectError.scheduleBuild2(0);
Executor e = jenkins.toComputer().getExecutors().get(0); Executor e = r.jenkins.toComputer().getExecutors().get(0);
Thread.sleep(2000); Thread.sleep(2000);
while(project2.getLastBuild()==null){ while(project2.getLastBuild()==null){
if(!e.isAlive()){ if(!e.isAlive()){
...@@ -595,15 +584,15 @@ public class QueueTest extends HudsonTestCase { ...@@ -595,15 +584,15 @@ public class QueueTest extends HudsonTestCase {
} }
} }
public void testCancelInQueue() throws Exception @Test public void cancelInQueue() throws Exception
{ {
// parepare an offline slave. // parepare an offline slave.
DumbSlave slave = createOnlineSlave(); DumbSlave slave = r.createOnlineSlave();
assertFalse(slave.toComputer().isOffline()); assertFalse(slave.toComputer().isOffline());
slave.toComputer().disconnect(null).get(); slave.toComputer().disconnect(null).get();
assertTrue(slave.toComputer().isOffline()); assertTrue(slave.toComputer().isOffline());
FreeStyleProject p = createFreeStyleProject(); FreeStyleProject p = r.createFreeStyleProject();
p.setAssignedNode(slave); p.setAssignedNode(slave);
QueueTaskFuture<FreeStyleBuild> f = p.scheduleBuild2(0); QueueTaskFuture<FreeStyleBuild> f = p.scheduleBuild2(0);
......
...@@ -28,13 +28,13 @@ import hudson.model.Descriptor; ...@@ -28,13 +28,13 @@ import hudson.model.Descriptor;
import hudson.model.Node; import hudson.model.Node;
import hudson.model.Label; import hudson.model.Label;
import hudson.slaves.NodeProvisioner.PlannedNode; import hudson.slaves.NodeProvisioner.PlannedNode;
import org.jvnet.hudson.test.HudsonTestCase;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import org.jvnet.hudson.test.JenkinsRule;
/** /**
* {@link Cloud} implementation useful for testing. * {@link Cloud} implementation useful for testing.
...@@ -45,7 +45,7 @@ import java.util.concurrent.Future; ...@@ -45,7 +45,7 @@ import java.util.concurrent.Future;
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public class DummyCloudImpl extends Cloud { public class DummyCloudImpl extends Cloud {
private final transient HudsonTestCase caller; private final transient JenkinsRule rule;
/** /**
* Configurable delay between the {@link Cloud#provision(Label,int)} and the actual launch of a slave, * Configurable delay between the {@link Cloud#provision(Label,int)} and the actual launch of a slave,
...@@ -64,9 +64,9 @@ public class DummyCloudImpl extends Cloud { ...@@ -64,9 +64,9 @@ public class DummyCloudImpl extends Cloud {
*/ */
public Label label; public Label label;
public DummyCloudImpl(HudsonTestCase caller, int delay) { public DummyCloudImpl(JenkinsRule rule, int delay) {
super("test"); super("test");
this.caller = caller; this.rule = rule;
this.delay = delay; this.delay = delay;
} }
...@@ -105,7 +105,7 @@ public class DummyCloudImpl extends Cloud { ...@@ -105,7 +105,7 @@ public class DummyCloudImpl extends Cloud {
Thread.sleep(time); Thread.sleep(time);
System.out.println("launching slave"); System.out.println("launching slave");
DumbSlave slave = caller.createSlave(label); DumbSlave slave = rule.createSlave(label);
computer = slave.toComputer(); computer = slave.toComputer();
computer.connect(false).get(); computer.connect(false).get();
synchronized (DummyCloudImpl.this) { synchronized (DummyCloudImpl.this) {
......
/*
* The MIT License
*
* Copyright 2015 Jesse Glick.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.slaves;
import hudson.model.LoadStatistics;
import hudson.slaves.NodeProvisioner.NodeProvisionerInvoker;
import org.jvnet.hudson.test.JenkinsRule;
/** Overrides {@link LoadStatistics#CLOCK}, {@link NodeProvisionerInvoker#INITIALDELAY}, and/or {@link NodeProvisionerInvoker#RECURRENCEPERIOD} during the test. */
public class NodeProvisionerRule extends JenkinsRule {
private final int clock;
private int clockOrig;
private final int initialDelay;
private int initialDelayOrig;
private final int recurrencePeriod;
private int recurrencePeriodOrig;
public NodeProvisionerRule(int clock, int initialDelay, int recurrencePeriod) {
this.clock = clock;
this.initialDelay = initialDelay;
this.recurrencePeriod = recurrencePeriod;
}
@Override public void before() throws Throwable {
clockOrig = LoadStatistics.CLOCK;
initialDelayOrig = NodeProvisionerInvoker.INITIALDELAY;
recurrencePeriodOrig = NodeProvisionerInvoker.RECURRENCEPERIOD;
if (clock != -1) {
LoadStatistics.CLOCK = clock;
}
if (initialDelay != -1) {
NodeProvisionerInvoker.INITIALDELAY = initialDelay;
}
if (recurrencePeriod != -1) {
NodeProvisionerInvoker.RECURRENCEPERIOD = recurrencePeriod;
}
super.before();
}
@Override public void after() throws Exception {
super.after();
// TODO should we really restore prior values? That makes tests using this rule not safe to run concurrently. Should rather have Configuration be per-Jenkins.
LoadStatistics.CLOCK = clockOrig;
NodeProvisionerInvoker.INITIALDELAY = initialDelayOrig;
NodeProvisionerInvoker.RECURRENCEPERIOD = recurrencePeriodOrig;
}
}
...@@ -26,12 +26,7 @@ package hudson.slaves; ...@@ -26,12 +26,7 @@ package hudson.slaves;
import hudson.BulkChange; import hudson.BulkChange;
import hudson.Launcher; import hudson.Launcher;
import hudson.model.*; import hudson.model.*;
import hudson.slaves.NodeProvisioner.NodeProvisionerInvoker;
import hudson.tasks.Builder; import hudson.tasks.Builder;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.SleepBuilder;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
...@@ -40,31 +35,19 @@ import java.util.concurrent.CountDownLatch; ...@@ -40,31 +35,19 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.RandomlyFails;
import org.jvnet.hudson.test.SleepBuilder;
/** /**
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
*/ */
public class NodeProvisionerTest extends HudsonTestCase { public class NodeProvisionerTest {
private int original;
@Override
protected void setUp() throws Exception {
original = LoadStatistics.CLOCK;
LoadStatistics.CLOCK = 10; // run x1000 the regular speed to speed up the test
NodeProvisionerInvoker.INITIALDELAY = 100;
NodeProvisionerInvoker.RECURRENCEPERIOD = 10;
super.setUp();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
LoadStatistics.CLOCK = original;
NodeProvisionerInvoker.INITIALDELAY = original*10;
NodeProvisionerInvoker.RECURRENCEPERIOD = original;
}
public void testDummy() {} // just to make Surefire happy @Rule public JenkinsRule r = new NodeProvisionerRule(/* run x1000 the regular speed to speed up the test */10, 100, 10);
/** /**
* Latch synchronization primitive that waits for N thread to pass the checkpoint. * Latch synchronization primitive that waits for N thread to pass the checkpoint.
...@@ -102,8 +85,9 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -102,8 +85,9 @@ public class NodeProvisionerTest extends HudsonTestCase {
/** /**
* Scenario: schedule a build and see if one slave is provisioned. * Scenario: schedule a build and see if one slave is provisioned.
*/ */
public void _testAutoProvision() throws Exception {// excluded since it's fragile @RandomlyFails("fragile")
BulkChange bc = new BulkChange(jenkins); @Test public void autoProvision() throws Exception {
BulkChange bc = new BulkChange(r.jenkins);
try { try {
DummyCloudImpl cloud = initHudson(10); DummyCloudImpl cloud = initHudson(10);
...@@ -123,8 +107,9 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -123,8 +107,9 @@ public class NodeProvisionerTest extends HudsonTestCase {
/** /**
* Scenario: we got a lot of jobs all of the sudden, and we need to fire up a few nodes. * Scenario: we got a lot of jobs all of the sudden, and we need to fire up a few nodes.
*/ */
public void _testLoadSpike() throws Exception {// excluded since it's fragile @RandomlyFails("fragile")
BulkChange bc = new BulkChange(jenkins); @Test public void loadSpike() throws Exception {
BulkChange bc = new BulkChange(r.jenkins);
try { try {
DummyCloudImpl cloud = initHudson(0); DummyCloudImpl cloud = initHudson(0);
...@@ -141,13 +126,14 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -141,13 +126,14 @@ public class NodeProvisionerTest extends HudsonTestCase {
/** /**
* Scenario: make sure we take advantage of statically configured slaves. * Scenario: make sure we take advantage of statically configured slaves.
*/ */
public void _testBaselineSlaveUsage() throws Exception {// excluded since it's fragile @RandomlyFails("fragile")
BulkChange bc = new BulkChange(jenkins); @Test public void baselineSlaveUsage() throws Exception {
BulkChange bc = new BulkChange(r.jenkins);
try { try {
DummyCloudImpl cloud = initHudson(0); DummyCloudImpl cloud = initHudson(0);
// add slaves statically upfront // add slaves statically upfront
createSlave().toComputer().connect(false).get(); r.createSlave().toComputer().connect(false).get();
createSlave().toComputer().connect(false).get(); r.createSlave().toComputer().connect(false).get();
verifySuccessfulCompletion(buildAll(create5SlowJobs(new Latch(5)))); verifySuccessfulCompletion(buildAll(create5SlowJobs(new Latch(5))));
...@@ -161,12 +147,13 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -161,12 +147,13 @@ public class NodeProvisionerTest extends HudsonTestCase {
/** /**
* Scenario: loads on one label shouldn't translate to load on another label. * Scenario: loads on one label shouldn't translate to load on another label.
*/ */
public void _testLabels() throws Exception {// excluded since it's fragile @RandomlyFails("fragile")
BulkChange bc = new BulkChange(jenkins); @Test public void labels() throws Exception {
BulkChange bc = new BulkChange(r.jenkins);
try { try {
DummyCloudImpl cloud = initHudson(0); DummyCloudImpl cloud = initHudson(0);
Label blue = jenkins.getLabel("blue"); Label blue = r.jenkins.getLabel("blue");
Label red = jenkins.getLabel("red"); Label red = r.jenkins.getLabel("red");
cloud.label = red; cloud.label = red;
// red jobs // red jobs
...@@ -196,7 +183,7 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -196,7 +183,7 @@ public class NodeProvisionerTest extends HudsonTestCase {
private FreeStyleProject createJob(Builder builder) throws IOException { private FreeStyleProject createJob(Builder builder) throws IOException {
FreeStyleProject p = createFreeStyleProject(); FreeStyleProject p = r.createFreeStyleProject();
p.setAssignedLabel(null); // let it roam free, or else it ties itself to the master since we have no slaves p.setAssignedLabel(null); // let it roam free, or else it ties itself to the master since we have no slaves
p.getBuildersList().add(builder); p.getBuildersList().add(builder);
return p; return p;
...@@ -204,12 +191,12 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -204,12 +191,12 @@ public class NodeProvisionerTest extends HudsonTestCase {
private DummyCloudImpl initHudson(int delay) throws IOException { private DummyCloudImpl initHudson(int delay) throws IOException {
// start a dummy service // start a dummy service
DummyCloudImpl cloud = new DummyCloudImpl(this, delay); DummyCloudImpl cloud = new DummyCloudImpl(r, delay);
jenkins.clouds.add(cloud); r.jenkins.clouds.add(cloud);
// no build on the master, to make sure we get everything from the cloud // no build on the master, to make sure we get everything from the cloud
jenkins.setNumExecutors(0); r.jenkins.setNumExecutors(0);
jenkins.setNodes(Collections.<Node>emptyList()); r.jenkins.setNodes(Collections.<Node>emptyList());
return cloud; return cloud;
} }
...@@ -237,7 +224,7 @@ public class NodeProvisionerTest extends HudsonTestCase { ...@@ -237,7 +224,7 @@ public class NodeProvisionerTest extends HudsonTestCase {
System.out.println("Waiting for a completion"); System.out.println("Waiting for a completion");
for (Future<FreeStyleBuild> f : builds) { for (Future<FreeStyleBuild> f : builds) {
try { try {
assertBuildStatus(Result.SUCCESS, f.get(90, TimeUnit.SECONDS)); r.assertBuildStatus(Result.SUCCESS, f.get(90, TimeUnit.SECONDS));
} catch (TimeoutException e) { } catch (TimeoutException e) {
// time out so that the automated test won't hang forever, even when we have bugs // time out so that the automated test won't hang forever, even when we have bugs
System.out.println("Build didn't complete in time"); System.out.println("Build didn't complete in time");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册