提交 80cf4906 编写于 作者: K Kohsuke Kawaguchi

[FIXED JENKINS-18259]

Added a listener that gets called at the end of the test to provide opportunity for a cleanup.
This avoids the code duplication between HudsonTestCase vs JenkinsRule, too.
上级 8c5cf05f
package org.jvnet.hudson.test;
import hudson.Extension;
import hudson.model.Computer;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.slaves.ComputerListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Runs at the end of the test to cleanup any live channels.
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class ChannelShutdownListener extends ComputerListener implements EndOfTestListener {
/**
* Remember channels that are created, to release them at the end.
*/
private List<Channel> channels = new ArrayList<Channel>();
@Override
public synchronized void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException {
VirtualChannel ch = c.getChannel();
if (ch instanceof Channel) {
channels.add((Channel)ch);
}
}
@Override
public synchronized void onTearDown() throws Exception {
for (Channel c : channels)
c.close();
for (Channel c : channels)
c.join();
channels.clear();
}
}
package org.jvnet.hudson.test;
import hudson.ExtensionPoint;
/**
* Gets notified before the test completes to perform additional cleanup.
*
* @author Kohsuke Kawaguchi
* @since 1.520
*/
public interface EndOfTestListener extends ExtensionPoint {
/**
* Called for clean up.
*/
void onTearDown() throws Exception;
}
...@@ -57,8 +57,6 @@ import hudson.model.*; ...@@ -57,8 +57,6 @@ import hudson.model.*;
import hudson.model.Executor; import hudson.model.Executor;
import hudson.model.Node.Mode; import hudson.model.Node.Mode;
import hudson.model.Queue.Executable; import hudson.model.Queue.Executable;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.remoting.Which; import hudson.remoting.Which;
import hudson.security.ACL; import hudson.security.ACL;
import hudson.security.AbstractPasswordBasedSecurityRealm; import hudson.security.AbstractPasswordBasedSecurityRealm;
...@@ -77,7 +75,6 @@ import hudson.tasks.BuildWrapper; ...@@ -77,7 +75,6 @@ import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrapperDescriptor; import hudson.tasks.BuildWrapperDescriptor;
import hudson.tasks.Builder; import hudson.tasks.Builder;
import hudson.tasks.Mailer; import hudson.tasks.Mailer;
import hudson.tasks.Mailer.DescriptorImpl;
import hudson.tasks.Maven; import hudson.tasks.Maven;
import hudson.tasks.Maven.MavenInstallation; import hudson.tasks.Maven.MavenInstallation;
import hudson.tasks.Publisher; import hudson.tasks.Publisher;
...@@ -177,7 +174,6 @@ import com.gargoylesoftware.htmlunit.DefaultCssErrorHandler; ...@@ -177,7 +174,6 @@ import com.gargoylesoftware.htmlunit.DefaultCssErrorHandler;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.Page; import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebRequestSettings; import com.gargoylesoftware.htmlunit.WebRequestSettings;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.html.DomNode; import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlButton; import com.gargoylesoftware.htmlunit.html.HtmlButton;
import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlElement;
...@@ -234,11 +230,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction { ...@@ -234,11 +230,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
*/ */
private List<WebClient> clients = new ArrayList<WebClient>(); private List<WebClient> clients = new ArrayList<WebClient>();
/**
* Remember channels that are created, to release them at the end.
*/
private List<Channel> channels = new ArrayList<Channel>();
/** /**
* JavaScript "debugger" that provides you information about the JavaScript call stack * JavaScript "debugger" that provides you information about the JavaScript call stack
* and the current values of the local variables in those stack frame. * and the current values of the local variables in those stack frame.
...@@ -390,6 +381,9 @@ public abstract class HudsonTestCase extends TestCase implements RootAction { ...@@ -390,6 +381,9 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
try { try {
for (EndOfTestListener tl : jenkins.getExtensionList(EndOfTestListener.class))
tl.onTearDown();
if (timeoutTimer!=null) { if (timeoutTimer!=null) {
timeoutTimer.cancel(); timeoutTimer.cancel();
timeoutTimer = null; timeoutTimer = null;
...@@ -402,15 +396,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction { ...@@ -402,15 +396,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
client.closeAllWindows(); client.closeAllWindows();
} }
clients.clear(); clients.clear();
synchronized(channels) {
for (Channel c : channels)
c.close();
for (Channel c : channels)
c.join();
channels.clear();
}
} finally { } finally {
if (server!=null) if (server!=null)
server.stop(); server.stop();
...@@ -545,22 +530,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction { ...@@ -545,22 +530,6 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
return realm; return realm;
} }
@TestExtension
public static class ComputerListenerImpl extends ComputerListener {
@Override
public void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException {
VirtualChannel ch = c.getChannel();
if (ch instanceof Channel)
TestEnvironment.get().testCase.addChannel((Channel)ch);
}
}
private void addChannel(Channel ch) {
synchronized (channels) {
channels.add(ch);
}
}
/** /**
* Returns the older default Maven, while still allowing specification of other bundled Mavens. * Returns the older default Maven, while still allowing specification of other bundled Mavens.
*/ */
......
...@@ -88,13 +88,10 @@ import hudson.model.TaskListener; ...@@ -88,13 +88,10 @@ import hudson.model.TaskListener;
import hudson.model.UpdateSite; import hudson.model.UpdateSite;
import hudson.model.User; import hudson.model.User;
import hudson.model.View; import hudson.model.View;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.remoting.Which; import hudson.remoting.Which;
import hudson.security.ACL; import hudson.security.ACL;
import hudson.security.AbstractPasswordBasedSecurityRealm; import hudson.security.AbstractPasswordBasedSecurityRealm;
import hudson.security.GroupDetails; import hudson.security.GroupDetails;
import hudson.security.SecurityRealm;
import hudson.security.csrf.CrumbIssuer; import hudson.security.csrf.CrumbIssuer;
import hudson.slaves.CommandLauncher; import hudson.slaves.CommandLauncher;
import hudson.slaves.ComputerConnector; import hudson.slaves.ComputerConnector;
...@@ -135,6 +132,7 @@ import org.junit.rules.TestRule; ...@@ -135,6 +132,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement; import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.recipes.Recipe;
import org.jvnet.hudson.test.rhino.JavaScriptDebugger; import org.jvnet.hudson.test.rhino.JavaScriptDebugger;
import org.kohsuke.stapler.ClassDescriptor; import org.kohsuke.stapler.ClassDescriptor;
import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundConstructor;
...@@ -173,6 +171,7 @@ import java.lang.management.ThreadInfo; ...@@ -173,6 +171,7 @@ import java.lang.management.ThreadInfo;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
...@@ -229,8 +228,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -229,8 +228,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
private Description testDescription; private Description testDescription;
private static JenkinsRule CURRENT = null;
/** /**
* Points to the same object as {@link #jenkins} does. * Points to the same object as {@link #jenkins} does.
*/ */
...@@ -264,11 +261,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -264,11 +261,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
*/ */
private List<WebClient> clients = new ArrayList<WebClient>(); private List<WebClient> clients = new ArrayList<WebClient>();
/**
* Remember channels that are created, to release them at the end.
*/
private List<Channel> channels = new ArrayList<Channel>();
/** /**
* JavaScript "debugger" that provides you information about the JavaScript call stack * JavaScript "debugger" that provides you information about the JavaScript call stack
* and the current values of the local variables in those stack frame. * and the current values of the local variables in those stack frame.
...@@ -392,8 +384,11 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -392,8 +384,11 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
/** /**
* Override to tear down your specific external resource. * Override to tear down your specific external resource.
*/ */
protected void after() { protected void after() throws Exception {
try { try {
for (EndOfTestListener tl : jenkins.getExtensionList(EndOfTestListener.class))
tl.onTearDown();
if (timeoutTimer!=null) { if (timeoutTimer!=null) {
timeoutTimer.cancel(); timeoutTimer.cancel();
timeoutTimer = null; timeoutTimer = null;
...@@ -411,20 +406,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -411,20 +406,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
} }
clients.clear(); clients.clear();
for (Channel c : channels)
try {
c.close();
} catch (IOException e) {
// ignore
}
for (Channel c : channels)
try {
c.join();
} catch (InterruptedException e) {
// ignore
}
channels.clear();
} finally { } finally {
try { try {
server.stop(); server.stop();
...@@ -476,7 +457,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -476,7 +457,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
Thread t = Thread.currentThread(); Thread t = Thread.currentThread();
String o = t.getName(); String o = t.getName();
t.setName("Executing "+ testDescription.getDisplayName()); t.setName("Executing "+ testDescription.getDisplayName());
CURRENT = JenkinsRule.this;
before(); before();
try { try {
System.out.println("=== Starting " + testDescription.getDisplayName()); System.out.println("=== Starting " + testDescription.getDisplayName());
...@@ -503,7 +483,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -503,7 +483,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
after(); after();
testDescription = null; testDescription = null;
t.setName(o); t.setName(o);
CURRENT = null;
} }
} }
}; };
...@@ -615,16 +594,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction { ...@@ -615,16 +594,6 @@ public class JenkinsRule implements TestRule, MethodRule, RootAction {
return realm; return realm;
} }
@TestExtension
public static class ComputerListenerImpl extends ComputerListener {
@Override
public void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException {
VirtualChannel ch = c.getChannel();
if (ch instanceof Channel)
CURRENT.channels.add((Channel)ch);
}
}
/** /**
* Returns the older default Maven, while still allowing specification of other bundled Mavens. * Returns the older default Maven, while still allowing specification of other bundled Mavens.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册