Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #106 from jglick/EnvActionImpl-cache
[JENKINS-42499] Removing caching from EnvActionImpl
  • Loading branch information
abayer committed Sep 5, 2017
2 parents 616e3ad + 9164cbc commit c099e48
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
Expand Up @@ -42,6 +42,7 @@
import javax.annotation.Nonnull;
import jenkins.model.RunAction2;
import org.jenkinsci.plugins.workflow.flow.FlowCopier;
import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner;
import org.jenkinsci.plugins.workflow.steps.EnvironmentExpander;
import org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction;
import org.kohsuke.accmod.Restricted;
Expand All @@ -56,19 +57,25 @@ public class EnvActionImpl extends GroovyObjectSupport implements EnvironmentAct
private static final long serialVersionUID = 1;

private final Map<String,String> env;
private transient EnvVars ownerEnvironment; // cache
private transient Run<?,?> owner;

private EnvActionImpl() {
this.env = new TreeMap<String,String>();
}

@Override public EnvVars getEnvironment() throws IOException, InterruptedException {
if (ownerEnvironment == null) {
// TODO call FlowExecutionOwner.getListener
ownerEnvironment = owner.getEnvironment(new LogTaskListener(LOGGER, Level.INFO));
TaskListener listener;
if (owner instanceof FlowExecutionOwner.Executable) {
FlowExecutionOwner executionOwner = ((FlowExecutionOwner.Executable) owner).asFlowExecutionOwner();
if (executionOwner != null) {
listener = executionOwner.getListener();
} else {
listener = new LogTaskListener(LOGGER, Level.INFO);
}
} else {
listener = new LogTaskListener(LOGGER, Level.INFO);
}
EnvVars e = new EnvVars(ownerEnvironment);
EnvVars e = owner.getEnvironment(listener);
e.putAll(env);
return e;
}
Expand Down
Expand Up @@ -25,16 +25,21 @@
package org.jenkinsci.plugins.workflow;

import hudson.EnvVars;
import hudson.model.EnvironmentContributor;
import hudson.model.Run;
import hudson.model.TaskListener;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback;
import org.jenkinsci.plugins.workflow.steps.EnvironmentExpander;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
import org.jenkinsci.plugins.workflow.steps.StepExecution;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
import org.junit.ClassRule;
import org.junit.Rule;
Expand All @@ -56,7 +61,7 @@ public class DynamicEnvironmentExpanderTest {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("dynamicEnv {echo \"initially ${env.DYNVAR}\"; semaphore 'wait'; echo \"subsequently ${env.DYNVAR}\"}"));
p.setDefinition(new CpsFlowDefinition("dynamicEnv {echo \"initially ${env.DYNVAR}\"; semaphore 'wait'; echo \"subsequently ${env.DYNVAR}\"}", true));
WorkflowRun b = p.scheduleBuild2(0).waitForStart();
SemaphoreStep.waitForStart("wait/1", b);
story.j.waitForMessage("initially one", b);
Expand All @@ -71,9 +76,15 @@ public class DynamicEnvironmentExpanderTest {
}
});
}
public static class DynamicEnvStep extends AbstractStepImpl {
public static class DynamicEnvStep extends Step {
@DataBoundConstructor public DynamicEnvStep() {}
public static class Execution extends AbstractStepExecutionImpl {
@Override public StepExecution start(StepContext context) throws Exception {
return new Execution(context);
}
private static class Execution extends StepExecution {
Execution(StepContext context) {
super(context);
}
private static final long serialVersionUID = 1;
String value;
@Override public boolean start() throws Exception {
Expand Down Expand Up @@ -102,13 +113,36 @@ private static class ExpanderImpl extends EnvironmentExpander {
env.override("DYNVAR", execution.value);
}
}
@TestExtension("dynamics") public static class DescriptorImpl extends AbstractStepDescriptorImpl {
public DescriptorImpl() {
super(Execution.class);
}
@TestExtension("dynamics") public static class DescriptorImpl extends StepDescriptor {
@Override public String getFunctionName() {return "dynamicEnv";}
@Override public String getDisplayName() {return getFunctionName();}
@Override public boolean takesImplicitBlockArgument() {return true;}
@Override public Set<? extends Class<?>> getRequiredContext() {
return Collections.emptySet();
}
}
}

@Issue("JENKINS-42499")
@Test public void changingEnvironment() {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("echo(/before VAR=$VAR/); " + EnvAdder.class.getCanonicalName() + ".value = 'after'; echo(/after VAR=$VAR/)", false));
WorkflowRun b = story.j.buildAndAssertSuccess(p);
story.j.assertLogContains("buildEnvironmentFor #1", b);
story.j.assertLogContains("before VAR=before", b);
story.j.assertLogContains("buildEnvironmentFor #2", b);
story.j.assertLogContains("after VAR=after", b);
}
});
}
@TestExtension("changingEnvironment") public static class EnvAdder extends EnvironmentContributor {
public static String value = "before";
private int count;
@SuppressWarnings("rawtypes")
@Override public void buildEnvironmentFor(Run r, EnvVars envs, TaskListener listener) throws IOException, InterruptedException {
listener.getLogger().println("buildEnvironmentFor #" + count++);
envs.put("VAR", value);
}
}

Expand Down

0 comments on commit c099e48

Please sign in to comment.