Skip to content
Permalink
Browse files

Merge pull request #47 from jglick/argumentsToString-JENKINS-45101

[JENKINS-45101] argumentsToString implementations
  • Loading branch information...
jglick committed Jun 30, 2017
2 parents 1cd4d63 + 2834d59 commit c5468bf465def5c2e4bc86e6e9faafa36c538eb4
Showing with 221 additions and 14 deletions.
  1. +15 −3 pom.xml
  2. +27 −3 src/main/java/org/jenkinsci/plugins/workflow/steps/CoreStep.java
  3. +5 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/CoreWrapperStep.java
  4. +21 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/EnvStep.java
  5. +6 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/MailStep.java
  6. +5 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/PwdStep.java
  7. +2 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/SleepStep.java
  8. +2 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/TimeoutStep.java
  9. +6 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/ToolStep.java
  10. +6 −0 src/main/java/org/jenkinsci/plugins/workflow/steps/WriteFileStep.java
  11. +6 −0 src/main/java/org/jenkinsci/plugins/workflow/support/steps/stash/StashStep.java
  12. +14 −3 src/test/java/org/jenkinsci/plugins/workflow/steps/CoreStepTest.java
  13. +30 −0 src/test/java/org/jenkinsci/plugins/workflow/steps/CoreWrapperStepTest.java
  14. +16 −0 src/test/java/org/jenkinsci/plugins/workflow/steps/EnvStepTest.java
  15. +12 −1 src/test/java/org/jenkinsci/plugins/workflow/steps/MailStepTest.java
  16. +14 −1 src/test/java/org/jenkinsci/plugins/workflow/steps/PwdStepTest.java
  17. +14 −2 src/test/java/org/jenkinsci/plugins/workflow/steps/ReadWriteFileStepTest.java
  18. +11 −1 src/test/java/org/jenkinsci/plugins/workflow/steps/ToolStepTest.java
  19. +9 −0 src/test/java/org/jenkinsci/plugins/workflow/support/steps/stash/StashTest.java
18 pom.xml
@@ -28,7 +28,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.30</version>
<version>2.31</version>
<relativePath />
</parent>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@@ -63,8 +63,8 @@
</pluginRepositories>
<properties>
<jenkins.version>1.642.3</jenkins.version>
<workflow-step-api-plugin.version>2.11</workflow-step-api-plugin.version>
<workflow-cps-plugin.version>2.30</workflow-cps-plugin.version>
<workflow-step-api-plugin.version>2.12</workflow-step-api-plugin.version>
<workflow-cps-plugin.version>2.32</workflow-cps-plugin.version>
<workflow-support-plugin.version>2.14</workflow-support-plugin.version>
</properties>
<dependencies>
@@ -156,6 +156,12 @@
<artifactId>mock-javamail</artifactId>
<version>1.9</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
@@ -175,5 +181,11 @@
<version>1.28</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>ansicolor</artifactId>
<version>0.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -36,15 +36,17 @@
import hudson.model.TaskListener;
import hudson.tasks.Builder;
import hudson.tasks.Publisher;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.CheckForNull;
import jenkins.model.Jenkins;
import jenkins.tasks.SimpleBuildStep;

import org.jenkinsci.plugins.structs.describable.DescribableModel;
import org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable;
import org.kohsuke.stapler.DataBoundConstructor;

/**
@@ -122,6 +124,28 @@ public boolean isMetaStep() {
return ImmutableSet.of(Run.class, FilePath.class, Launcher.class, TaskListener.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Map<String, Object> delegateArguments = delegateArguments(namedArgs.get("delegate"));
return delegateArguments != null ? super.argumentsToString(delegateArguments) : null;
}

@SuppressWarnings("unchecked")
static @CheckForNull Map<String, Object> delegateArguments(@CheckForNull Object delegate) {
if (delegate instanceof UninstantiatedDescribable) {
// TODO JENKINS-45101 getStepArgumentsAsString does not resolve its arguments
// thus delegate.model == null and we cannot inspect DescribableModel.soleRequiredParameter
// thus for, e.g., `junit testResults: '*.xml', keepLongStdio: true` we will get null
return new HashMap<>(((UninstantiatedDescribable) delegate).getArguments());
} else if (delegate instanceof Map) {
Map<String, Object> r = new HashMap<>();
r.putAll((Map) delegate);
r.remove(DescribableModel.CLAZZ);
return r;
} else {
return null;
}
}

}

}
@@ -161,6 +161,11 @@ public SimpleBuildWrapper getDelegate() {
return ImmutableSet.of(Run.class, FilePath.class, Launcher.class, TaskListener.class, EnvVars.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Map<String, Object> delegateArguments = CoreStep.DescriptorImpl.delegateArguments(namedArgs.get("delegate"));
return delegateArguments != null ? super.argumentsToString(delegateArguments) : null;
}

}

}
@@ -138,6 +138,27 @@
return Collections.emptySet();
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Object overrides = namedArgs.get("overrides");
if (overrides instanceof List) {
StringBuilder b = new StringBuilder();
for (Object pair : (List) overrides) {
if (pair instanceof String) {
int idx = ((String) pair).indexOf('=');
if (idx > 0) {
if (b.length() > 0) {
b.append(", ");
}
b.append(((String) pair).substring(0, idx));
}
}
}
return b.toString();
} else {
return null;
}
}

}

}
@@ -28,6 +28,7 @@
import hudson.Util;
import hudson.model.TaskListener;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import jenkins.plugins.mailer.tasks.MimeMessageBuilder;

@@ -114,6 +115,11 @@ public StepExecution start(StepContext context) throws Exception {
@Override public Set<? extends Class<?>> getRequiredContext() {
return Collections.singleton(TaskListener.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Object subject = namedArgs.get("subject");
return subject instanceof String ? (String) subject : null;
}
}

/**
@@ -29,6 +29,7 @@
import hudson.FilePath;
import hudson.slaves.WorkspaceList;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
@@ -76,6 +77,10 @@ public boolean isTmp() {
return Collections.singleton(FilePath.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
return null; // "true" is not a reasonable description
}

}

// TODO use 1.652 use WorkspaceList.tempDir
@@ -151,5 +151,7 @@ public ListBoxModel doFillUnitItems() {
return Collections.singleton(TaskListener.class);
}

// TODO argumentsToString should perhaps return "3m" etc.

}
}
@@ -81,6 +81,8 @@ public ListBoxModel doFillUnitItems() {
return Collections.singleton(TaskListener.class);
}

// TODO argumentsToString as for SleepStep

}

private static final long serialVersionUID = 1L;
@@ -36,6 +36,7 @@
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolInstallation;
import hudson.util.ListBoxModel;
import java.util.Map;

import javax.annotation.CheckForNull;

@@ -122,6 +123,11 @@ public ListBoxModel doFillNameItems(@QueryParameter String type) {
return ImmutableSet.of(TaskListener.class, EnvVars.class, Node.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Object name = namedArgs.get("name");
return name instanceof String ? (String) name : null;
}

}

public static final class Execution extends SynchronousNonBlockingStepExecution<String> {
@@ -28,6 +28,7 @@
import hudson.FilePath;
import hudson.Util;
import java.util.Collections;
import java.util.Map;
import java.util.Set;


@@ -79,6 +80,11 @@ public String getEncoding() {
return Collections.singleton(FilePath.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Object file = namedArgs.get("file");
return file instanceof String ? (String) file : null;
}

}

public static final class Execution extends SynchronousNonBlockingStepExecution<Void> {
@@ -30,6 +30,7 @@
import hudson.Util;
import hudson.model.Run;
import hudson.model.TaskListener;
import java.util.Map;
import java.util.Set;
import jenkins.model.Jenkins;
import org.jenkinsci.plugins.workflow.flow.StashManager;
@@ -130,6 +131,11 @@ public boolean isAllowEmpty() {
return ImmutableSet.of(Run.class, FilePath.class, TaskListener.class);
}

@Override public String argumentsToString(Map<String, Object> namedArgs) {
Object name = namedArgs.get("name");
return name instanceof String ? (String) name : null;
}

}

}
@@ -32,9 +32,14 @@
import java.util.List;
import javax.mail.internet.InternetAddress;
import jenkins.plugins.mailer.tasks.i18n.Messages;
import org.hamcrest.Matchers;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.workflow.actions.ArgumentsAction;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.cps.SnippetizerTester;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner;
import org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import static org.junit.Assert.*;
@@ -108,12 +113,15 @@
+ " writeFile text: '''<testsuite name='a'><testcase name='a1'/><testcase name='a2'><error>a2 failed</error></testcase></testsuite>''', file: 'a.xml'\n"
+ " writeFile text: '''<testsuite name='b'><testcase name='b1'/><testcase name='b2'/></testsuite>''', file: 'b.xml'\n"
+ " junit '*.xml'\n"
+ "}"));
+ "}", true));
WorkflowRun b = r.assertBuildStatus(Result.UNSTABLE, p.scheduleBuild2(0).get());
TestResultAction a = b.getAction(TestResultAction.class);
assertNotNull(a);
assertEquals(4, a.getTotalCount());
assertEquals(1, a.getFailCount());
List<FlowNode> coreStepNodes = new DepthFirstScanner().filteredNodes(b.getExecution(), new NodeStepTypePredicate("step"));
assertThat(coreStepNodes, Matchers.hasSize(1));
assertEquals("*.xml", ArgumentsAction.getStepArgumentsAsString(coreStepNodes.get(0)));
}

@Test public void javadoc() throws Exception {
@@ -122,9 +130,12 @@
"node {\n"
+ " writeFile text: 'hello world', file: 'docs/index.html'\n"
+ " step([$class: 'JavadocArchiver', javadocDir: 'docs'])\n"
+ "}"));
r.assertBuildStatusSuccess(p.scheduleBuild2(0));
+ "}", true));
WorkflowRun b = r.assertBuildStatusSuccess(p.scheduleBuild2(0));
assertEquals("hello world", r.createWebClient().getPage(p, "javadoc/").getWebResponse().getContentAsString());
List<FlowNode> coreStepNodes = new DepthFirstScanner().filteredNodes(b.getExecution(), new NodeStepTypePredicate("step"));
assertThat(coreStepNodes, Matchers.hasSize(1));
assertEquals("docs", ArgumentsAction.getStepArgumentsAsString(coreStepNodes.get(0)));
}

@Test public void mailer() throws Exception {
@@ -24,6 +24,8 @@

package org.jenkinsci.plugins.workflow.steps;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Functions;
@@ -49,14 +51,21 @@
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import jenkins.tasks.SimpleBuildWrapper;
import org.hamcrest.Matchers;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.workflow.actions.ArgumentsAction;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.cps.SnippetizerTester;
import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner;
import org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
@@ -220,6 +229,27 @@
}
}

@Issue("JENKINS-45101")
@Test public void argumentsToString() throws Exception {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition(
"node {\n" +
" wrap([$class: 'AnsiColorBuildWrapper', colorMapName: 'xterm']) {}\n" +
"}", true));
WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
List<FlowNode> coreStepNodes = new DepthFirstScanner().filteredNodes(b.getExecution(), Predicates.and(new NodeStepTypePredicate("wrap"), new Predicate<FlowNode>() {
@Override public boolean apply(FlowNode n) {
return n instanceof StepStartNode && !((StepStartNode) n).isBody();
}
}));
assertThat(coreStepNodes, Matchers.hasSize(1));
assertEquals("xterm", ArgumentsAction.getStepArgumentsAsString(coreStepNodes.get(0)));
}
});
}

// TODO add @LocalData serialForm test proving compatibility with executions dating back to workflow 1.4.3 on 1.580.1

// TODO add to jenkins-test-harness
@@ -24,15 +24,24 @@

package org.jenkinsci.plugins.workflow.steps;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import hudson.Functions;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.hamcrest.Matchers;
import org.jenkinsci.plugins.workflow.actions.ArgumentsAction;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graphanalysis.DepthFirstScanner;
import org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -64,6 +73,13 @@
story.j.assertLogContains(Functions.isWindows() ? "inside CUSTOM=override NOVEL=val BUILD_TAG=custom NULLED= FOOPATH=C:\\ball;C:\\foos;" : "inside CUSTOM=override NOVEL=val BUILD_TAG=custom NULLED= FOOPATH=/opt/ball:/opt/foos:", b);
story.j.assertLogContains("groovy NULLED=null", b);
story.j.assertLogContains("outside CUSTOM=initial NOVEL= NULLED=outside", b);
List<FlowNode> coreStepNodes = new DepthFirstScanner().filteredNodes(b.getExecution(), Predicates.and(new NodeStepTypePredicate("withEnv"), new Predicate<FlowNode>() {
@Override public boolean apply(FlowNode n) {
return n instanceof StepStartNode && !((StepStartNode) n).isBody();
}
}));
assertThat(coreStepNodes, Matchers.hasSize(1));
assertEquals("CUSTOM, NOVEL, BUILD_TAG, NULLED, FOOPATH+BALL", ArgumentsAction.getStepArgumentsAsString(coreStepNodes.get(0)));
}
});
}

0 comments on commit c5468bf

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