Skip to content
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

Merged
merged 1 commit into from Apr 2, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 38 additions & 7 deletions src/main/java/org/jvnet/hudson/test/RestartableJenkinsRule.java
Expand Up @@ -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;
Expand All @@ -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;

/**
Expand All @@ -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<>();
Copy link
Member

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.


private TemporaryFolder tmp = new TemporaryFolder();

Expand Down Expand Up @@ -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 {
Expand All @@ -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.");
Copy link
Member

Choose a reason for hiding this comment

The 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
Copy link
Member

Choose a reason for hiding this comment

The 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.

}
}
}

Expand Down