Skip to content
Permalink
Browse files

[FIXED JENKINS-27531] In 1.597+ Run.getId() is not reliable while it …

…is still being loaded.

Originally-Committed-As: bdf1260dcafaf43bac23ec5d76f01916bc432e64
  • Loading branch information
jglick committed Mar 20, 2015
1 parent 1653844 commit 271382c4792341f72771cc364b4ab22129893765
@@ -55,6 +55,7 @@
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.recipes.LocalData;

public class WorkflowRunTest {

@@ -67,11 +68,11 @@

@Before
public void setUp() throws Exception {
p = r.jenkins.createProject(WorkflowJob.class, "p");
r.jenkins.getInjector().injectMembers(this);
}

@Test public void basics() throws Exception {
p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("println('hello')"));
WorkflowRun b1 = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
assertFalse(b1.isBuilding());
@@ -85,6 +86,7 @@ public void setUp() throws Exception {
}

@Test public void parameters() throws Exception {
p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("node {sh('echo param=' + PARAM)}",true));
p.addProperty(new ParametersDefinitionProperty(new StringParameterDefinition("PARAM", null)));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0, new ParametersAction(new StringParameterValue("PARAM", "value"))));
@@ -99,7 +101,7 @@ public void iconColor() throws Exception {
// marker file I use for synchronization
FilePath test = new FilePath(r.jenkins.root).child("touch");


p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition(
"println('hello')\n"+
"watch(new File('"+test.getRemote()+"'))\n"+
@@ -169,6 +171,7 @@ public void iconColor() throws Exception {
gmas.add(p, "devel");
}
r.jenkins.setAuthorizationStrategy(gmas);
p = r.jenkins.createProject(WorkflowJob.class, "p");
final String groovy = "println 'hello'";
ACL.impersonate(User.get("devel").impersonate(), new Runnable() {
@Override public void run() {
@@ -194,7 +197,19 @@ private void assertColor(WorkflowRun b, BallColor color) throws IOException {
@Test @Issue("JENKINS-25630")
public void contextInjectionOfSubParameters() throws Exception {
// see SubtypeInjectingStep
p = r.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("node('master') { injectSubtypesAsContext() }"));
r.assertBuildStatusSuccess(p.scheduleBuild2(0));
}

@Issue("JENKINS-27531")
@LocalData
@Test public void loadMigratedBuildRecord() throws Exception {
WorkflowJob p = r.jenkins.getItemByFullName("p", WorkflowJob.class);
assertNotNull(p);
WorkflowRun b = p.getLastBuild();
assertNotNull(b);
r.assertBuildStatusSuccess(JenkinsRuleExt.waitForCompletion(b));
}

}
Binary file not shown.
@@ -41,6 +41,7 @@
import hudson.model.Queue;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.RunMap;
import hudson.model.StreamBuildListener;
import hudson.model.TaskListener;
import hudson.model.listeners.RunListener;
@@ -54,6 +55,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
@@ -341,8 +343,42 @@ protected void eol(byte[] b, int len) throws IOException {

private static final Map<String,WorkflowRun> LOADING_RUNS = new HashMap<String,WorkflowRun>();

/**
* Same as {@link Run#getId} except it works before the run has been loaded from disk.
* TODO JENKINS-27531 this logic should be handled directly in Run.getId() instead.
*/
private static String getId(WorkflowRun r) {
String id = r.getId();
Class<?> runIdMigratorC;
try {
runIdMigratorC = Class.forName("jenkins.model.RunIdMigrator");
} catch (ClassNotFoundException x) {
// 1.596 or earlier, so the ID is fine.
return id;
}
try {
RunMap<WorkflowRun> runMap = r.getParent()._getRuns();
Field runIdMigratorF = RunMap.class.getField("runIdMigrator");
Object runIdMigratorO = runIdMigratorF.get(runMap);
Field idToNumberF = runIdMigratorC.getDeclaredField("idToNumber");
idToNumberF.setAccessible(true);
Map<String,Integer> idToNumberO = (Map<String,Integer>) idToNumberF.get(runIdMigratorO);
int n = r.getNumber();
for (Map.Entry<String,Integer> entry : idToNumberO.entrySet()) {
if (entry.getValue().equals(n)) {
id = entry.getKey();
LOGGER.log(Level.FINE, "recovered legacy ID {0} for {1}", new Object[] {id, r});
return id;
}
}
} catch (Exception x) {
LOGGER.log(Level.WARNING, null, x);
}
return id;
}

private String key() {
return getParent().getFullName() + '/' + getId();
return getParent().getFullName() + '/' + getId(this);
}

/** Hack to allow {@link #execution} to use an {@link Owner} referring to this run, even when it has not yet been loaded. */
@@ -541,7 +577,7 @@ private String key() {
synchronized (LOADING_RUNS) {
candidate = LOADING_RUNS.get(key());
}
if (candidate != null && candidate.getParent().getFullName().equals(job) && candidate.getId().equals(id)) {
if (candidate != null && candidate.getParent().getFullName().equals(job) && getId(candidate).equals(id)) {
run = candidate;
} else {
Jenkins jenkins = Jenkins.getInstance();

0 comments on commit 271382c

Please sign in to comment.
You can’t perform that action at this time.