Skip to content

Commit

Permalink
Merge pull request #102 from jglick/testFailureIgnore
Browse files Browse the repository at this point in the history
Adding `testFailureIgnore` option more similar to a real Maven project
  • Loading branch information
jglick committed Apr 24, 2024
2 parents cfde462 + 38d8837 commit 1fc7e40
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ public Job create(ModifiableTopLevelItemGroup ig, String name, Long averageDurat
project.setDefinition(new CpsFlowDefinition(
String.format(
"node {%n"
+ " withMockLoad(averageDuration: %d) {%n"
+ " withMockLoad(averageDuration: %d, testFailureIgnore: true) {%n"
+ " sh MOCK_LOAD_COMMAND%n"
+ " }%n"
+ " archiveArtifacts allowEmptyArchive: true, artifacts: 'mock-artifact-*.txt'%n"
+ " fingerprint 'mock-artifact-*.txt'%n"
+ " junit 'mock-junit.xml'%n"
+ " archiveArtifacts artifacts: 'mock-artifact-*.txt', fingerprint: true%n"
+ "}",
averageDuration == null || averageDuration < 0 ? Long.valueOf(60L) : averageDuration),
true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,27 @@ public final class WithMockLoadStep extends Step {
@DataBoundSetter
public long averageDuration = 60;

@DataBoundSetter
public boolean testFailureIgnore;

@DataBoundConstructor
public WithMockLoadStep() {}

@Override
public StepExecution start(StepContext context) throws Exception {
return new Execution(context, averageDuration);
return new Execution(context, averageDuration, testFailureIgnore);
}

private static final class Execution extends GeneralNonBlockingStepExecution {

private final long averageDuration;
private final boolean testFailureIgnore;
private String classpathDirPath;

Execution(StepContext context, long averageDuration) {
Execution(StepContext context, long averageDuration, boolean testFailureIgnore) {
super(context);
this.averageDuration = averageDuration;
this.testFailureIgnore = testFailureIgnore;
}

@Override
Expand All @@ -76,7 +81,8 @@ public boolean start() throws Exception {
classpathDir
.child("mock/MockLoad.class")
.copyFrom(WithMockLoadStep.class.getResource("/mock/MockLoad.class"));
var command = "java -classpath \"" + classpathDirPath + "\" mock.MockLoad " + averageDuration;
var command = "java " + (testFailureIgnore ? "-Dmaven.test.failure.ignore=true " : "") + "-classpath \""

Check warning on line 84 in src/main/java/jenkins/plugin/mockloadbuilder/WithMockLoadStep.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 84 is only partially covered, one branch is missing
+ classpathDirPath + "\" mock.MockLoad " + averageDuration;
getContext()
.newBodyInvoker()
.withContexts(EnvironmentExpander.merge(
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/mock/MockLoad.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private static boolean doBuild(File baseDir, Random entropy, long duration, Prin
out.println("[INFO] ------------------------------------------------------------------------");
doWork(entropy, duration, out, baseDir);
String result;
if (runTests(baseDir, entropy, out)) {
if (runTests(baseDir, entropy, out) || Boolean.getBoolean("maven.test.failure.ignore")) {

Check warning on line 57 in src/main/java/mock/MockLoad.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 57 is not covered by tests
result = "SUCCESS";
createArtifacts(baseDir, entropy, out);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ THE SOFTWARE.
<f:entry field="averageDuration" title="${%averageDuration.title}">
<f:number default="60"/>
</f:entry>
<f:entry field="testFailureIgnore" title="Continue after test failures">
<f:checkbox/>
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div>
If selected, failing tests will not cause the command itself to return a nonzero exit status.
Normally used in conjunction with the <code>junit</code> step to mark the build as unstable.
Similar to the <a href="https://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#testFailureIgnore">Maven option</a>.
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
Generates load on the Jenkins build node and over the remoting channel. There will be a random number of build
artifacts created matching the file name pattern <code>mock-artifact-*.txt</code>. There will be a JUnit test
report with the file name <code>mock-junit.xml</code>. Approximately 5% of the time, the build will "fail" its
tests and thus no artifacts will be generated.
tests and thus no artifacts will be generated unless <code>testFailureIgnore</code> was specified.
</p>
<p>
Unlike the <code>mockLoad</code> step, this step does not itself run the load command.
Instead, it copies the program into the workspace and prepares a command for you to run yourself.
Usage:
</p>
<pre><code>withMockLoad(averageDuration: 300) {
<pre><code>withMockLoad(averageDuration: 300, testFailureIgnore: true) {
sh MOCK_LOAD_COMMAND
}</code></pre>
}
junit 'mock-junit.xml'
archiveArtifacts artifacts: 'mock-artifact-*.txt', fingerprint: true</code></pre>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@

package jenkins.plugin.mockloadbuilder;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.in;
import static org.hamcrest.Matchers.is;
import static org.junit.Assume.assumeFalse;

import hudson.Functions;
import hudson.model.Result;
import java.util.Set;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.junit.ClassRule;
Expand All @@ -50,23 +55,24 @@ public void smokes() throws Throwable {
r.createSlave("remote", null, null);
var p = r.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition(
"node('remote') {\n" + " withMockLoad(averageDuration: 15) {\n"
"node('remote') {\n" + " withMockLoad(averageDuration: 15, testFailureIgnore: true) {\n"
+ " if (isUnix()) {\n"
+ " sh MOCK_LOAD_COMMAND\n"
+ " } else {\n"
+ " bat MOCK_LOAD_COMMAND\n"
+ " }\n"
+ " }\n"
+ " junit 'mock-junit.xml'\n"
+ " archiveArtifacts artifacts: 'mock-artifact-*.txt', allowEmptyArchive: true, fingerprint: true\n"
+ " archiveArtifacts artifacts: 'mock-artifact-*.txt', fingerprint: true\n"
+ "}",
true));
var b = p.scheduleBuild2(0).waitForStart();
r.waitForMessage("[INFO] Building mock-load 1.0-SNAPSHOT", b);
});
rr.then(r -> {
var b = r.jenkins.getItemByFullName("p", WorkflowJob.class).getBuildByNumber(1);
r.waitForCompletion(b); // not asserting success—could be unstable or failed
r.waitForCompletion(b);
assertThat(b.getResult(), is(in(Set.of(Result.SUCCESS, Result.UNSTABLE))));
r.assertLogContains("[INFO] Reactor Summary:", b);
});
}
Expand Down

0 comments on commit 1fc7e40

Please sign in to comment.