提交 4378827a 编写于 作者: O Oliver Gondža

Revert "Merge branch 'stable-1.642' of github.com:jenkinsci/jenkins into stable-1.642"

This reverts commit 48ef1542, reversing
changes made to dc4a9b1f.
上级 48ef1542
......@@ -54,28 +54,12 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
</ul>
</div><!--=TRUNK-END=-->
<h3><a name=v1.643>What's new in 1.643</a> (2015/12/20)</h3>
<ul class=image>
<li class="bug">
Fix when multiple clouds are set up and provisioning of a node is denied.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-31219">issue 31219</a>)
<li class="rfe">
Allow retrying core update when the first attempt failed.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-11016">issue 11016</a>)
<li class="rfe">
Allow specifying the default TCP slave agent listener port via system property.
(<a href="https://github.com/jenkinsci/jenkins/commit/653fbdb65024b1b528e21f682172885f7111bba9">commit 653fbdb</a>)
</ul>
<h3><a name=v1.642>What's new in 1.642</a> (2015/12/13)</h3>
<ul class=image>
<li class="major bug">
Various kinds of settings could not be saved since 1.640.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-31954">issue 31954</a>)
</ul>
</div><!--=TRUNK-END=-->
<h3><a name=v1.641>What's new in 1.641</a> (2015/12/09)</h3>
<ul class=image>
<li class="major bug">
......
......@@ -24,5 +24,4 @@ NewVersionAvailable=New version of Jenkins ({0}) is available for <a href="{1}">
(<a href="${changelog.url}">changelog</a>).
UpgradeComplete=Upgrade to Jenkins {0} is complete, awaiting <a href="{1}/safeRestart">restart</a>.
UpgradeCompleteRestartNotSupported=Upgrade to Jenkins {0} is complete, awaiting restart.
UpgradeProgress=Upgrade to Jenkins {0} is <a href="{1}">in progress</a>.
UpgradeFailed=Upgrade to Jenkins {0} failed: <a href="{2}">{1}</a>.
UpgradeProgress=Upgrade to Jenkins {0} is <a href="{1}">in progress or failed</a>.
......@@ -37,7 +37,6 @@ import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.name.Names;
import com.google.common.collect.ImmutableList;
import hudson.init.InitMilestone;
import hudson.model.Descriptor;
import hudson.model.Hudson;
import jenkins.ExtensionComponentSet;
......@@ -245,7 +244,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
*/
private List<IndexItem<?,Object>> sezpozIndex;
private final Map<Key,Annotation> annotations = new HashMap<>();
private final Map<Key,Annotation> annotations = new HashMap<Key,Annotation>();
private final Sezpoz moduleFinder = new Sezpoz();
/**
......@@ -261,7 +260,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
sezpozIndex = loadSezpozIndices(Jenkins.getInstance().getPluginManager().uberClassLoader);
List<Module> modules = new ArrayList<>();
List<Module> modules = new ArrayList<Module>();
modules.add(new AbstractModule() {
@Override
protected void configure() {
......@@ -325,7 +324,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
l.addAll(delta);
sezpozIndex = l;
List<Module> modules = new ArrayList<>();
List<Module> modules = new ArrayList<Module>();
modules.add(new SezpozModule(delta));
for (ExtensionComponent<Module> ec : moduleFinder.refresh().find(Module.class)) {
modules.add(ec.getInstance());
......@@ -338,7 +337,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
return new ExtensionComponentSet() {
@Override
public <T> Collection<ExtensionComponent<T>> find(Class<T> type) {
List<ExtensionComponent<T>> result = new ArrayList<>();
List<ExtensionComponent<T>> result = new ArrayList<ExtensionComponent<T>>();
_find(type, result, child);
return result;
}
......@@ -352,11 +351,14 @@ public abstract class ExtensionFinder implements ExtensionPoint {
private Object instantiate(IndexItem<?,Object> item) {
try {
return item.instance();
} catch (LinkageError | Exception e) {
} catch (LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
} catch (Exception e) {
LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
}
return null;
}
......@@ -373,7 +375,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
public <U> Collection<ExtensionComponent<U>> find(Class<U> type, Hudson jenkins) {
// the find method contract requires us to traverse all known components
List<ExtensionComponent<U>> result = new ArrayList<>();
List<ExtensionComponent<U>> result = new ArrayList<ExtensionComponent<U>>();
for (Injector i=container; i!=null; i=i.getParent()) {
_find(type, result, i);
}
......@@ -387,7 +389,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
Object o = e.getValue().getProvider().get();
if (o!=null) {
GuiceExtensionAnnotation gea = a!=null ? extensionAnnotations.get(a.annotationType()) : null;
result.add(new ExtensionComponent<>(type.cast(o), gea != null ? gea.getOrdinal(a) : 0));
result.add(new ExtensionComponent<U>(type.cast(o),gea!=null?gea.getOrdinal(a):0));
}
}
}
......@@ -441,7 +443,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
}
};
}
}
};
private static final Logger LOGGER = Logger.getLogger(GuiceFinder.class.getName());
......@@ -530,11 +532,14 @@ public abstract class ExtensionFinder implements ExtensionPoint {
}
}).in(scope);
}
} catch (Exception|LinkageError e) {
} catch (LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(optional ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
} catch (Exception e) {
LOGGER.log(optional ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
}
}
}
......@@ -616,7 +621,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
* Finds all the matching {@link IndexItem}s that match the given type and instantiate them.
*/
private <T> Collection<ExtensionComponent<T>> _find(Class<T> type, List<IndexItem<Extension,Object>> indices) {
List<ExtensionComponent<T>> result = new ArrayList<>();
List<ExtensionComponent<T>> result = new ArrayList<ExtensionComponent<T>>();
for (IndexItem<Extension,Object> item : indices) {
try {
......@@ -636,12 +641,14 @@ public abstract class ExtensionFinder implements ExtensionPoint {
if(type.isAssignableFrom(extType)) {
Object instance = item.instance();
if(instance!=null)
result.add(new ExtensionComponent<>(type.cast(instance),item.annotation()));
result.add(new ExtensionComponent<T>(type.cast(instance),item.annotation()));
}
} catch (LinkageError|Exception e) {
} catch (LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(logLevel(item), "Failed to load "+item.className(), e);
} catch (Exception e) {
LOGGER.log(logLevel(item), "Failed to load "+item.className(), e);
}
}
......@@ -671,7 +678,9 @@ public abstract class ExtensionFinder implements ExtensionPoint {
// according to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459208
// this appears to be the only way to force a class initialization
Class.forName(extType.getName(),true,extType.getClassLoader());
} catch (Exception | LinkageError e) {
} catch (Exception e) {
LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e);
} catch (LinkageError e) {
LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e);
}
}
......
......@@ -38,6 +38,6 @@ import static hudson.init.InitMilestone.*;
public class GroovyInitScript {
@Initializer(after=JOB_LOADED)
public static void init(Jenkins j) {
new GroovyHookScript("init", j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader).run();
new GroovyHookScript("init").run();
}
}
......@@ -23,17 +23,17 @@
*/
package hudson.security;
import hudson.Extension;
import hudson.model.Descriptor;
import jenkins.model.Jenkins;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
import hudson.Extension;
import javax.inject.Inject;
import java.util.Collections;
import java.util.List;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
/**
* {@link AuthorizationStrategy} that grants full-control to authenticated user
* (other than anonymous users.)
......@@ -41,10 +41,6 @@ import java.util.List;
* @author Kohsuke Kawaguchi
*/
public class FullControlOnceLoggedInAuthorizationStrategy extends AuthorizationStrategy {
@DataBoundConstructor
public FullControlOnceLoggedInAuthorizationStrategy() {
}
@Override
public ACL getRootACL() {
return THE_ACL;
......@@ -62,21 +58,15 @@ public class FullControlOnceLoggedInAuthorizationStrategy extends AuthorizationS
THE_ACL.add(ACL.ANONYMOUS,Permission.READ,true);
}
/**
* @deprecated as of 1.643
* Inject descriptor via {@link Inject}.
*/
@Restricted(NoExternalUse.class)
public static Descriptor<AuthorizationStrategy> DESCRIPTOR;
@Extension
public static class DescriptorImpl extends Descriptor<AuthorizationStrategy> {
public DescriptorImpl() {
DESCRIPTOR = this;
}
public static final Descriptor<AuthorizationStrategy> DESCRIPTOR = new Descriptor<AuthorizationStrategy>() {
public String getDisplayName() {
return Messages.FullControlOnceLoggedInAuthorizationStrategy_DisplayName();
}
}
@Override
public AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new FullControlOnceLoggedInAuthorizationStrategy();
}
};
}
......@@ -23,11 +23,12 @@
*/
package hudson.security;
import hudson.Extension;
import hudson.model.Descriptor;
import jenkins.model.Jenkins;
import hudson.Extension;
import org.acegisecurity.acls.sid.GrantedAuthoritySid;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import net.sf.json.JSONObject;
import java.util.Collection;
import java.util.Collections;
......@@ -42,10 +43,6 @@ public final class LegacyAuthorizationStrategy extends AuthorizationStrategy {
add(new GrantedAuthoritySid("admin"), Jenkins.ADMINISTER,true);
}};
@DataBoundConstructor
public LegacyAuthorizationStrategy() {
}
public ACL getRootACL() {
return LEGACY_ACL;
}
......@@ -59,5 +56,9 @@ public final class LegacyAuthorizationStrategy extends AuthorizationStrategy {
public String getDisplayName() {
return Messages.LegacyAuthorizationStrategy_DisplayName();
}
public LegacyAuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new LegacyAuthorizationStrategy();
}
}
}
......@@ -690,10 +690,11 @@ public class NodeProvisioner {
int workloadToProvision = (int) Math.round(Math.floor(excessWorkload + m));
for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
for (CloudProvisioningListener cl : CloudProvisioningListener.all())
// consider displaying reasons in a future cloud ux
{
if (cl.canProvision(c, state.getLabel(), workloadToProvision) != null) {
// consider displaying reasons in a future cloud ux
continue CLOUD;
break CLOUD;
}
}
......
......@@ -155,14 +155,4 @@ public abstract class OfflineCause {
this.message = message;
}
}
/**
* Caused by idle period.
* @since TODO
*/
public static class IdleOfflineCause extends SimpleOfflineCause {
public IdleOfflineCause () {
super(hudson.slaves.Messages._RetentionStrategy_Demand_OfflineIdle());
}
}
}
......@@ -267,7 +267,7 @@ public abstract class RetentionStrategy<T extends Computer> extends AbstractDesc
// we've been idle for long enough
logger.log(Level.INFO, "Disconnecting computer {0} as it has been idle for {1}",
new Object[]{c.getName(), Util.getTimeSpanString(idleMilliseconds)});
c.disconnect(new OfflineCause.IdleOfflineCause());
c.disconnect(OfflineCause.create(Messages._RetentionStrategy_Demand_OfflineIdle()));
} else {
// no point revisiting until we can be confident we will be idle
return TimeUnit.MILLISECONDS.toMinutes(TimeUnit.MINUTES.toMillis(idleDelay) - idleMilliseconds);
......
......@@ -40,10 +40,7 @@ public abstract class BootFailure extends ErrorObject {
LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",this);
WebApp.get(context).setApp(this);
if (home == null) {
return;
}
new GroovyHookScript("boot-failure", context, home, BootFailure.class.getClassLoader())
new GroovyHookScript("boot-failure")
.bind("exception",this)
.bind("home",home)
.bind("servletContext", context)
......
......@@ -566,7 +566,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
* TCP slave agent port.
* 0 for random, -1 to disable.
*/
private int slaveAgentPort = Integer.getInteger(Jenkins.class.getName()+".slaveAgentPort",0);
private int slaveAgentPort =0;
/**
* Whitespace-separated labels assigned to the master as a {@link Node}.
......
......@@ -3,6 +3,8 @@ package jenkins.util.groovy;
import groovy.lang.Binding;
import groovy.lang.GroovyCodeSource;
import groovy.lang.GroovyShell;
import jenkins.model.Jenkins;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
......@@ -10,10 +12,9 @@ import java.net.URL;
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;
import static java.util.logging.Level.WARNING;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
import static java.util.logging.Level.WARNING;
/**
* A collection of Groovy scripts that are executed as various hooks.
......@@ -39,15 +40,9 @@ import javax.servlet.ServletContext;
public class GroovyHookScript {
private final String hook;
private final Binding bindings = new Binding();
private final ServletContext servletContext;
private final File home;
private final ClassLoader loader;
public GroovyHookScript(String hook, @Nonnull ServletContext servletContext, @Nonnull File home, @Nonnull ClassLoader loader) {
public GroovyHookScript(String hook) {
this.hook = hook;
this.servletContext = servletContext;
this.home = home;
this.loader = loader;
}
public GroovyHookScript bind(String name, Object o) {
......@@ -60,22 +55,23 @@ public class GroovyHookScript {
}
public void run() {
Jenkins j = Jenkins.getInstance();
final String hookGroovy = hook+".groovy";
final String hookGroovyD = hook+".groovy.d";
try {
URL bundled = servletContext.getResource("/WEB-INF/"+ hookGroovy);
URL bundled = j.servletContext.getResource("/WEB-INF/"+ hookGroovy);
execute(bundled);
} catch (IOException e) {
LOGGER.log(WARNING, "Failed to execute /WEB-INF/"+hookGroovy,e);
}
Set<String> resources = servletContext.getResourcePaths("/WEB-INF/"+ hookGroovyD +"/");
Set<String> resources = j.servletContext.getResourcePaths("/WEB-INF/"+ hookGroovyD +"/");
if (resources!=null) {
// sort to execute them in a deterministic order
for (String res : new TreeSet<String>(resources)) {
try {
URL bundled = servletContext.getResource(res);
URL bundled = j.servletContext.getResource(res);
execute(bundled);
} catch (IOException e) {
LOGGER.log(WARNING, "Failed to execute " + res, e);
......@@ -83,10 +79,10 @@ public class GroovyHookScript {
}
}
File script = new File(home, hookGroovy);
File script = new File(j.getRootDir(), hookGroovy);
execute(script);
File scriptD = new File(home, hookGroovyD);
File scriptD = new File(j.getRootDir(), hookGroovyD);
if (scriptD.isDirectory()) {
File[] scripts = scriptD.listFiles(new FileFilter() {
public boolean accept(File f) {
......@@ -133,7 +129,7 @@ public class GroovyHookScript {
* Can be used to customize the environment in which the script runs.
*/
protected GroovyShell createShell() {
return new GroovyShell(loader, bindings);
return new GroovyShell(Jenkins.getInstance().getPluginManager().uberClassLoader, bindings);
}
private static final Logger LOGGER = Logger.getLogger(GroovyHookScript.class.getName());
......
......@@ -39,14 +39,6 @@ THE SOFTWARE.
</j:otherwise>
</j:choose>
</j:when>
<j:when test="${upJob!=null and upJob.error != null}">
<form method="post" action="${rootURL}/updateCenter/upgrade">
${%UpgradeFailed(ucData.core.version,upJob.errorMessage,rootURL+'/updateCenter/')}
<j:if test="${ucData.canUpgrade()}">
<f:submit value="${%Retry}"/>
</j:if>
</form>
</j:when>
<j:when test="${upJob!=null}">
${%UpgradeProgress(ucData.core.version,rootURL+'/updateCenter/')}
</j:when>
......
......@@ -38,7 +38,7 @@ THE SOFTWARE.
The following value assumes that you have java in your PATH.
-->
<executable>java</executable>
<arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 --webroot="%BASE%\war"</arguments>
<arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080</arguments>
<!--
interactive flag causes the empty black Java window to be displayed.
I'm still debugging this.
......
package hudson.util
import hudson.WebAppMain
import hudson.model.Hudson
import hudson.model.listeners.ItemListener
import jenkins.model.Jenkins
import org.junit.After
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.jvnet.hudson.test.HudsonHomeLoader
import org.jvnet.hudson.test.JenkinsRule
import org.jvnet.hudson.test.TestEnvironment
import org.jvnet.hudson.test.TestExtension
import org.kohsuke.stapler.WebApp
import javax.servlet.ServletContextEvent
/**
*
*
* @author Kohsuke Kawaguchi
*/
class BootFailureTest {
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
static boolean makeBootFail = true;
@Rule
public JenkinsRule j = new JenkinsRule() {
@Override
void before() throws Throwable {
env = new TestEnvironment(testDescription);
env.pin();
// don't let Jenkins start automatically
}
@Override
public Hudson newHudson() throws Exception {
def ws = createWebServer()
def wa = new WebAppMain() {
@Override
WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) {
return new WebAppMain.FileAndDescription(homeLoader.allocate(),"test");
}
}
wa.contextInitialized(new ServletContextEvent(ws));
wa.joinInit();
def a = WebApp.get(ws).app;
if (a instanceof Jenkins)
return a;
return null; // didn't boot
}
}
@After
public void tearDown() {
Jenkins.getInstance()?.cleanUp()
}
public static class SeriousError extends Error {}
@TestExtension()
public static class InduceBootFailure extends ItemListener {
@Override
void onLoaded() {
if (makeBootFail)
throw new SeriousError();
}
}
@Test
void runBootFailureScript() {
final def home = tmpDir.newFolder()
j.with({ -> home} as HudsonHomeLoader)
// creates a script
new File(home,"boot-failure.groovy").text = "hudson.util.BootFailureTest.problem = exception";
def d = new File(home, "boot-failure.groovy.d")
d.mkdirs();
new File(d,"1.groovy").text = "hudson.util.BootFailureTest.runRecord << '1'";
new File(d,"2.groovy").text = "hudson.util.BootFailureTest.runRecord << '2'";
// first failed boot
makeBootFail = true;
assert j.newHudson()==null;
assert bootFailures(home)==1;
// second failed boot
problem = null;
runRecord = [];
assert j.newHudson()==null;
assert bootFailures(home)==2;
assert runRecord==["1","2"]
// make sure the script has actually run
assert problem.cause instanceof SeriousError
// if it boots well, the failure record should be gone
makeBootFail = false;
assert j.newHudson()!=null;
assert !BootFailure.getBootFailureFile(home).exists()
}
private static int bootFailures(File home) {
return BootFailure.getBootFailureFile(home).readLines().size()
}
// to be set by the script
public static Exception problem;
public static def runRecord = [];
}
package hudson.util;
import hudson.WebAppMain;
import hudson.model.Hudson;
import hudson.model.listeners.ItemListener;
import static hudson.util.BootFailureTest.makeBootFail;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import jenkins.model.Jenkins;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.HudsonHomeLoader;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestEnvironment;
import org.jvnet.hudson.test.TestExtension;
import org.kohsuke.stapler.WebApp;
/**
*
*
* @author Kohsuke Kawaguchi
*/
public class BootFailureTest {
@Rule
public TemporaryFolder tmpDir = new TemporaryFolder();
static boolean makeBootFail = true;
static WebAppMain wa;
static class CustomRule extends JenkinsRule {
@Override
public void before() throws Throwable {
env = new TestEnvironment(testDescription);
env.pin();
// don't let Jenkins start automatically
}
@Override
public Hudson newHudson() throws Exception {
ServletContext ws = createWebServer();
wa = new WebAppMain() {
@Override
public WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) {
try {
return new WebAppMain.FileAndDescription(homeLoader.allocate(), "test");
} catch (Exception x) {
throw new AssertionError(x);
}
}
};
wa.contextInitialized(new ServletContextEvent(ws));
wa.joinInit();
Object a = WebApp.get(ws).getApp();
if (a instanceof Hudson) {
return (Hudson) a;
}
return null; // didn't boot
}
}
@Rule
public CustomRule j = new CustomRule();
@After
public void tearDown() {
Jenkins j = Jenkins.getInstance();
if (j != null) {
j.cleanUp();
}
}
public static class SeriousError extends Error {}
@TestExtension("runBootFailureScript")
public static class InduceBootFailure extends ItemListener {
@Override
public void onLoaded() {
if (makeBootFail)
throw new SeriousError();
}
}
@Test
public void runBootFailureScript() throws Exception {
final File home = tmpDir.newFolder();
j.with(new HudsonHomeLoader() {
@Override
public File allocate() throws Exception {
return home;
}
});
// creates a script
FileUtils.write(new File(home, "boot-failure.groovy"), "hudson.util.BootFailureTest.problem = exception");
File d = new File(home, "boot-failure.groovy.d");
d.mkdirs();
FileUtils.write(new File(d, "1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'");
FileUtils.write(new File(d, "2.groovy"), "hudson.util.BootFailureTest.runRecord << '2'");
// first failed boot
makeBootFail = true;
assertNull(j.newHudson());
assertEquals(1, bootFailures(home));
// second failed boot
problem = null;
runRecord = new ArrayList<String>();
assertNull(j.newHudson());
assertEquals(2, bootFailures(home));
assertEquals(Arrays.asList("1", "2"), runRecord);
// make sure the script has actually run
assertEquals(SeriousError.class, problem.getCause().getClass());
// if it boots well, the failure record should be gone
makeBootFail = false;
assertNotNull(j.newHudson());
assertFalse(BootFailure.getBootFailureFile(home).exists());
}
private static int bootFailures(File home) throws IOException {
return FileUtils.readLines(BootFailure.getBootFailureFile(home)).size();
}
@Issue("JENKINS-24696")
@Test
public void interruptedStartup() throws Exception {
final File home = tmpDir.newFolder();
j.with(new HudsonHomeLoader() {
@Override
public File allocate() throws Exception {
return home;
}
});
File d = new File(home, "boot-failure.groovy.d");
d.mkdirs();
FileUtils.write(new File(d, "1.groovy"), "hudson.util.BootFailureTest.runRecord << '1'");
j.newHudson();
assertEquals(Collections.singletonList("1"), runRecord);
}
@TestExtension("interruptedStartup")
public static class PauseBoot extends ItemListener {
@Override
public void onLoaded() {
wa.contextDestroyed(null);
}
}
// to be set by the script
public static Exception problem;
public static List<String> runRecord = new ArrayList<String>();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册