New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-50476] offer a way to assert that Jenkins won't start #96
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
import groovy.lang.Closure; | ||
import hudson.FilePath; | ||
import org.junit.Assert; | ||
import org.junit.rules.MethodRule; | ||
import org.junit.rules.TemporaryFolder; | ||
import org.junit.runner.Description; | ||
|
@@ -12,7 +13,9 @@ | |
import java.io.IOException; | ||
import java.nio.file.NoSuchFileException; | ||
import java.util.ArrayList; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.Callable; | ||
|
||
/** | ||
|
@@ -34,7 +37,11 @@ | |
public class RestartableJenkinsRule implements MethodRule { | ||
public JenkinsRule j; | ||
private Description description; | ||
private final List<Statement> steps = new ArrayList<Statement>(); | ||
|
||
/** | ||
* List of {@link Statement}. For each one, the boolean value says if Jenkins is expected to start or not. | ||
*/ | ||
private final Map<Statement, Boolean> steps = new LinkedHashMap<>(); | ||
|
||
private TemporaryFolder tmp = new TemporaryFolder(); | ||
|
||
|
@@ -153,30 +160,43 @@ public void evaluate() throws Throwable { | |
}); | ||
} | ||
|
||
public void thenDoesNotStart() { | ||
addStep(new Statement() { | ||
@Override | ||
public void evaluate() throws Throwable { | ||
throw new IllegalStateException("should have failed before reaching here."); | ||
} | ||
}, false); | ||
} | ||
|
||
public void addStep(final Statement step) { | ||
steps.add(new Statement() { | ||
addStep(step, true); | ||
} | ||
|
||
public void addStep(final Statement step, boolean expectedToStartCorrectly) { | ||
steps.put(new Statement() { | ||
@Override | ||
public void evaluate() throws Throwable { | ||
j.jenkins.getInjector().injectMembers(step); | ||
j.jenkins.getInjector().injectMembers(target); | ||
step.evaluate(); | ||
} | ||
}); | ||
}, expectedToStartCorrectly); | ||
} | ||
|
||
/** Similar to {@link #addStep(Statement)} but we simulate a dirty shutdown after the step, rather than a clean one. | ||
* See {@link #thenWithHardShutdown(Step)} for how this is done. | ||
*/ | ||
public void addStepWithDirtyShutdown(final Statement step) { | ||
steps.add(new Statement() { | ||
steps.put(new Statement() { | ||
@Override | ||
public void evaluate() throws Throwable { | ||
j.jenkins.getInjector().injectMembers(step); | ||
j.jenkins.getInjector().injectMembers(target); | ||
step.evaluate(); | ||
simulateAbruptShutdown(); | ||
} | ||
}); | ||
}, true); | ||
} | ||
|
||
private void run() throws Throwable { | ||
|
@@ -188,9 +208,20 @@ public File allocate() throws Exception { | |
}; | ||
|
||
// run each step inside its own JenkinsRule | ||
for (Statement step : steps) { | ||
for (Map.Entry<Statement, Boolean> entry : steps.entrySet()) { | ||
Statement step = entry.getKey(); | ||
j = createJenkinsRule(description).with(loader); | ||
j.apply(step,description).evaluate(); | ||
try { | ||
j.apply(step, description).evaluate(); | ||
if (!entry.getValue()) { | ||
Assert.fail("The current JenkinsRule should have failed to start Jenkins."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Super-🐜 - I like to phrase this as "X happened but we saw Y" because that makes it clearer. |
||
} | ||
} catch (Exception e) { | ||
if(entry.getValue()) { | ||
throw e; | ||
} | ||
// Failure ignored as requested | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth logging something to indicate we saw expected failure, so we know rule ran okay. |
||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐜 I would declare the type here as explicitly LinkedHashmap since no other type could be legally used since we need ordering preserved.
What we're doing here is a bit dodgy (using a LinkedHashmap to simulate a List of Tuple types, with no intent to really use mapping)... but it's also much less verbose than the "proper" alternative and doesn't require adding Apache Commons Lang with a modern version to get tuple types.