Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[JENKINS-14701] Thorough Matrix support.
This allows you to only run the script once - on the parent job, before the "configuration" builds are run. This is supported through a new checkbox in the configuration UI.
- Loading branch information
Showing
6 changed files
with
258 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
src/main/java/com/lookout/jenkins/PersistedEnvironment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.lookout.jenkins; | ||
|
||
import hudson.EnvVars; | ||
import hudson.model.Action; | ||
import hudson.tasks.BuildWrapper.Environment; | ||
|
||
public class PersistedEnvironment implements Action { | ||
private Environment environment; | ||
|
||
public PersistedEnvironment (Environment environment) { | ||
this.environment = environment; | ||
} | ||
|
||
public Environment getEnvironment () { | ||
return environment; | ||
} | ||
|
||
public String getDisplayName() { | ||
return "Environment Script variables"; | ||
} | ||
|
||
public String getIconFileName() { | ||
// TODO Auto-generated method stub | ||
return null; | ||
} | ||
|
||
public String getUrlName() { | ||
// TODO Auto-generated method stub | ||
return null; | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/resources/com/lookout/jenkins/EnvironmentScript/config.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.lookout.jenkins; | ||
|
||
import java.io.IOException; | ||
|
||
import net.sf.json.JSONObject; | ||
|
||
import org.kohsuke.stapler.StaplerRequest; | ||
|
||
import hudson.Extension; | ||
import hudson.Launcher; | ||
import hudson.model.BuildListener; | ||
import hudson.model.AbstractBuild; | ||
import hudson.model.Descriptor; | ||
import hudson.tasks.Builder; | ||
|
||
/** | ||
* {@link Builder} that simply counts how many times it was executed. | ||
* | ||
* @author Jørgen P. Tjernø <jorgen.tjerno@mylookout.com> | ||
*/ | ||
public class CountBuilder extends Builder { | ||
int count = 0; | ||
|
||
public int getCount() { | ||
return count; | ||
} | ||
|
||
public synchronized boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { | ||
count++; | ||
return true; | ||
} | ||
|
||
@Extension | ||
public static final class DescriptorImpl extends Descriptor<Builder> { | ||
public Builder newInstance(StaplerRequest req, JSONObject data) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
public String getDisplayName() { | ||
return "Count Number Of Builds"; | ||
} | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
src/test/java/com/lookout/jenkins/EnvironmentScriptMatrixTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package com.lookout.jenkins; | ||
|
||
import java.io.File; | ||
|
||
import hudson.FilePath; | ||
import hudson.matrix.Axis; | ||
import hudson.matrix.AxisList; | ||
import hudson.matrix.MatrixRun; | ||
import hudson.matrix.DefaultMatrixExecutionStrategyImpl; | ||
import hudson.matrix.MatrixBuild; | ||
import hudson.matrix.MatrixProject; | ||
|
||
import org.jvnet.hudson.test.CaptureEnvironmentBuilder; | ||
import org.jvnet.hudson.test.HudsonTestCase; | ||
|
||
public class EnvironmentScriptMatrixTest extends HudsonTestCase { | ||
class MatrixTestJob { | ||
public MatrixProject project; | ||
public CaptureEnvironmentBuilder captureBuilder; | ||
public CountBuilder countBuilder; | ||
|
||
public MatrixTestJob (String script, boolean onlyRunOnParent) throws Exception { | ||
project = createMatrixProject(); | ||
|
||
// This forces it to run the builds sequentially, to prevent any | ||
// race conditions when concurrently updating the 'counter' file. | ||
project.setExecutionStrategy(new DefaultMatrixExecutionStrategyImpl(true, null, null, null)); | ||
|
||
project.setAxes(new AxisList(new Axis("axis", "value1", "value2"))); | ||
project.getBuildWrappersList().add(new EnvironmentScript(script, onlyRunOnParent)); | ||
|
||
captureBuilder = new CaptureEnvironmentBuilder(); | ||
project.getBuildersList().add(captureBuilder); | ||
|
||
countBuilder = new CountBuilder(); | ||
project.getBuildersList().add(countBuilder); | ||
} | ||
} | ||
|
||
final static String SCRIPT_COUNTER = | ||
"file='%s/counter'\n" | ||
+ "if [ -f $file ]; then\n" | ||
+ " let i=$(cat $file)+1\n" | ||
+ "else\n" | ||
+ " i=1\n" | ||
+ "fi\n" | ||
+ "echo 1 >was_run\n" | ||
+ "echo $i >$file\n" | ||
+ "echo seen=yes"; | ||
|
||
|
||
// Explicit constructor so that we can call createTmpDir. | ||
public EnvironmentScriptMatrixTest () throws Exception {} | ||
|
||
// Generate a random directory that we pass to the shell script. | ||
File tempDir = createTmpDir(); | ||
String script = String.format(SCRIPT_COUNTER, tempDir.getPath()); | ||
|
||
public void testWithParentOnly () throws Exception { | ||
MatrixTestJob job = new MatrixTestJob(script, true); | ||
MatrixBuild build = buildAndAssert(job); | ||
|
||
// We ensure that this was only run once (on the parent) | ||
assertEquals("1", new FilePath(tempDir).child("counter").readToString().trim()); | ||
|
||
// Then make sure that it was in fact in the parent's WS that we ran. | ||
assertTrue(build.getWorkspace().child("was_run").exists()); | ||
for (MatrixRun run : build.getRuns()) | ||
assertFalse(run.getWorkspace().child("was_run").exists()); | ||
} | ||
|
||
public void testWithEachChild () throws Exception { | ||
MatrixTestJob job = new MatrixTestJob(script, false); | ||
MatrixBuild build = buildAndAssert(job); | ||
|
||
// We ensure that this was only run twice - once for each axis combination - but not on the parent. | ||
assertEquals("2", new FilePath(tempDir).child("counter").readToString().trim()); | ||
|
||
// Then make sure that it was in fact in the combination jobs' workspace. | ||
assertFalse(build.getWorkspace().child("was_run").exists()); | ||
for (MatrixRun run : build.getRuns()) | ||
assertTrue(run.getWorkspace().child("was_run").exists()); | ||
} | ||
|
||
private MatrixBuild buildAndAssert(MatrixTestJob job) throws Exception { | ||
MatrixBuild build = assertBuildStatusSuccess(job.project.scheduleBuild2(0).get()); | ||
|
||
// Make sure that the environment variables set in the script are properly propagated. | ||
assertEquals("yes", job.captureBuilder.getEnvVars().get("seen")); | ||
// Make sure that the builder was executed twice, once for each axis value. | ||
assertEquals(2, job.countBuilder.getCount()); | ||
|
||
return build; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters