diff --git a/pom.xml b/pom.xml
index d20d1d70..0787fe2a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.jenkins-ci.plugins
plugin
- 3.4
+ 3.57
matlab
@@ -20,7 +20,7 @@
- 2.7.3
+ 2.164.3
8
@@ -52,14 +52,57 @@
http://github.com/jenkinsci/matlab-plugin
HEAD
-
+
+
+
+ io.jenkins.tools.bom
+ bom-2.164.x
+ 4
+ import
+ pom
+
+
+
-
-
- org.jenkins-ci.plugins
- matrix-project
- 1.14
-
+
+
+
+
+ org.jenkins-ci.plugins
+ matrix-project
+
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-step-api
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-api
+
+
+
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-basic-steps
+ test
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-cps
+ test
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-durable-task-step
+ test
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-job
+ test
+
diff --git a/src/main/java/com/mathworks/ci/MatlabStepExecution.java b/src/main/java/com/mathworks/ci/MatlabStepExecution.java
new file mode 100644
index 00000000..dfffe258
--- /dev/null
+++ b/src/main/java/com/mathworks/ci/MatlabStepExecution.java
@@ -0,0 +1,82 @@
+package com.mathworks.ci;
+
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.io.IOException;
+import org.jenkinsci.plugins.workflow.steps.StepContext;
+import org.jenkinsci.plugins.workflow.steps.StepExecution;
+import hudson.EnvVars;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.Launcher.ProcStarter;
+import hudson.model.Result;
+import hudson.model.TaskListener;
+
+public class MatlabStepExecution extends StepExecution implements MatlabBuild {
+
+ private static final long serialVersionUID = 6704588180717665100L;
+
+ private String command;
+
+
+ public MatlabStepExecution(StepContext context, String command) {
+ super(context);
+ this.command = command;
+ }
+
+ private String getCommand() {
+ return this.command;
+ }
+
+ @Override
+ public boolean start() throws Exception {
+ final Launcher launcher = getContext().get(Launcher.class);
+ final FilePath workspace = getContext().get(FilePath.class);
+ final TaskListener listener = getContext().get(TaskListener.class);
+ final EnvVars env = getContext().get(EnvVars.class);
+
+ //Make sure the Workspace exists before run
+
+ workspace.mkdirs();
+
+ int res = execMatlabCommand(workspace, launcher, listener, env);
+
+ getContext().setResult((res == 0) ? Result.SUCCESS : Result.FAILURE);
+
+ getContext().onSuccess(true);
+
+ //return false represents the asynchronous run.
+ return false;
+ }
+
+ @Override
+ public void stop(Throwable cause) throws Exception {
+ getContext().onFailure(cause);
+ }
+
+ private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher,
+ TaskListener listener, EnvVars envVars) throws IOException, InterruptedException {
+ final String uniqueTmpFldrName = getUniqueNameForRunnerFile();
+ try {
+ ProcStarter matlabLauncher = getProcessToRunMatlabCommand(workspace, launcher, listener, envVars,
+ envVars.expand(getCommand()), uniqueTmpFldrName);
+
+
+ return matlabLauncher.join();
+ } catch (Exception e) {
+ listener.getLogger().println(e.getMessage());
+ return 1;
+ } finally {
+ // Cleanup the runner File from tmp directory
+ final FilePath matlabRunnerScript =
+ getFilePathForUniqueFolder(launcher, uniqueTmpFldrName, workspace);
+ if (matlabRunnerScript.exists()) {
+ matlabRunnerScript.deleteRecursive();
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/com/mathworks/ci/RunMatlabCommandBuilder.java b/src/main/java/com/mathworks/ci/RunMatlabCommandBuilder.java
index 9dbcf410..da289bfa 100644
--- a/src/main/java/com/mathworks/ci/RunMatlabCommandBuilder.java
+++ b/src/main/java/com/mathworks/ci/RunMatlabCommandBuilder.java
@@ -61,7 +61,7 @@ private EnvVars getEnv() {
return this.env;
}
- @Symbol("RunMatlabCommand")
+
@Extension
public static class RunMatlabCommandDescriptor extends BuildStepDescriptor {
diff --git a/src/main/java/com/mathworks/ci/RunMatlabCommandStep.java b/src/main/java/com/mathworks/ci/RunMatlabCommandStep.java
new file mode 100644
index 00000000..3b388185
--- /dev/null
+++ b/src/main/java/com/mathworks/ci/RunMatlabCommandStep.java
@@ -0,0 +1,58 @@
+package com.mathworks.ci;
+
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.util.Set;
+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.kohsuke.stapler.DataBoundConstructor;
+import com.google.common.collect.ImmutableSet;
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+
+public class RunMatlabCommandStep extends Step {
+
+
+ private String command;
+
+ @DataBoundConstructor
+ public RunMatlabCommandStep(String command) {
+ this.command = command;
+ }
+
+
+ public String getCommand() {
+ return this.command;
+ }
+
+ @Override
+ public StepExecution start(StepContext context) throws Exception {
+ return new MatlabStepExecution(context, getCommand());
+ }
+
+ @Extension
+ public static class CommandStepDescriptor extends StepDescriptor {
+
+ @Override
+ public Set extends Class>> getRequiredContext() {
+ return ImmutableSet.of(TaskListener.class, FilePath.class, Launcher.class,
+ EnvVars.class, Run.class);
+ }
+
+ @Override
+ public String getFunctionName() {
+ return Message.getValue("matlab.command.build.step.name");
+ }
+ }
+}
+
+
diff --git a/src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java b/src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java
index 93840829..3c4a8ee3 100644
--- a/src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java
+++ b/src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java
@@ -185,7 +185,7 @@ protected Object readResolve() {
}
- @Symbol("RunMatlabTests")
+
@Extension
public static class RunMatlabTestsDescriptor extends BuildStepDescriptor {
diff --git a/src/main/java/com/mathworks/ci/RunMatlabTestsStep.java b/src/main/java/com/mathworks/ci/RunMatlabTestsStep.java
new file mode 100644
index 00000000..603b8d9f
--- /dev/null
+++ b/src/main/java/com/mathworks/ci/RunMatlabTestsStep.java
@@ -0,0 +1,180 @@
+package com.mathworks.ci;
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.io.FilenameUtils;
+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.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.DataBoundSetter;
+import com.google.common.collect.ImmutableSet;
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+
+public class RunMatlabTestsStep extends Step {
+
+ private String testResultsPDF;
+ private String testResultsTAP;
+ private String testResultsJUnit;
+ private String codeCoverageCobertura;
+ private String testResultsSimulinkTest;
+ private String modelCoverageCobertura;
+
+
+ @DataBoundConstructor
+ public RunMatlabTestsStep() {
+
+ }
+
+ public String getTestResultsTAP() {
+ return testResultsTAP;
+ }
+
+ @DataBoundSetter
+ public void setTestResultsTAP(String testResultsTAP) {
+ this.testResultsTAP = testResultsTAP;
+ }
+
+ public String getTestResultsPDF() {
+ return testResultsPDF;
+ }
+
+ @DataBoundSetter
+ public void setTestResultsPDF(String testResultsPDF) {
+ this.testResultsPDF = testResultsPDF;
+ }
+
+ public String getTestResultsJUnit() {
+ return testResultsJUnit;
+ }
+
+ @DataBoundSetter
+ public void setTestResultsJUnit(String testResultsJUnit) {
+ this.testResultsJUnit = testResultsJUnit;
+ }
+
+ public String getCodeCoverageCobertura() {
+ return codeCoverageCobertura;
+ }
+
+ @DataBoundSetter
+ public void setCodeCoverageCobertura(String codeCoverageCobertura) {
+ this.codeCoverageCobertura = codeCoverageCobertura;
+ }
+
+ public String getTestResultsSimulinkTest() {
+ return testResultsSimulinkTest;
+ }
+
+ @DataBoundSetter
+ public void setTestResultsSimulinkTest(String testResultsSimulinkTest) {
+ this.testResultsSimulinkTest = testResultsSimulinkTest;
+ }
+
+ public String getModelCoverageCobertura() {
+ return modelCoverageCobertura;
+ }
+
+
+ @DataBoundSetter
+ public void setModelCoverageCobertura(String modelCoverageCobertura) {
+ this.modelCoverageCobertura = modelCoverageCobertura;
+ }
+
+
+ @Override
+ public StepExecution start(StepContext context) throws Exception {
+ Launcher launcher = context.get(Launcher.class);
+ FilePath workspace = context.get(FilePath.class);
+
+ //Copy Scratch file needed to run MATLAB tests in workspace
+ FilePath targetWorkspace = new FilePath(launcher.getChannel(), workspace.getRemote());
+ copyScratchFileInWorkspace(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_RESOURCE,
+ MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE, targetWorkspace);
+ return new MatlabStepExecution(context,constructCommandForTest(getInputArgs()));
+ }
+
+ @Extension
+ public static class RunTestsStepDescriptor extends StepDescriptor {
+
+ @Override
+ public Set extends Class>> getRequiredContext() {
+ return ImmutableSet.of(TaskListener.class, FilePath.class, Launcher.class,
+ EnvVars.class, Run.class);
+ }
+
+ @Override
+ public String getFunctionName() {
+ return Message.getValue("matlab.tests.build.step.name");
+ }
+ }
+
+ public String constructCommandForTest(String inputArguments) {
+ final String matlabFunctionName =
+ FilenameUtils.removeExtension(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE);
+ final String runCommand = "exit(" + matlabFunctionName + "(" + inputArguments + "))";
+ return runCommand;
+ }
+
+
+ private String getInputArgs() {
+ final List inputArgs = new ArrayList<>();
+ final Map args = getMatlabArgs();
+
+ args.forEach((key, val) -> {
+ if (val != null) {
+ inputArgs.add("'" + key + "'" + "," + "'" + val.replaceAll("'", "''") + "'");
+ }
+ });
+
+ if (inputArgs.isEmpty()) {
+ return "";
+ }
+
+ return String.join(",", inputArgs);
+ }
+
+ private Map getMatlabArgs() {
+ final Map args = new HashMap();
+ args.put("PDFReportPath", getTestResultsPDF());
+ args.put("TAPResultsPath", getTestResultsTAP());
+ args.put("JUnitResultsPath", getTestResultsJUnit());
+ args.put("SimulinkTestResultsPath", getTestResultsSimulinkTest());
+ args.put("CoberturaCodeCoveragePath", getCodeCoverageCobertura());
+ args.put("CoberturaModelCoveragePath", getModelCoverageCobertura());
+ return args;
+ }
+
+ /*
+ * Method to copy given file from source to target node specific workspace.
+ */
+ private void copyScratchFileInWorkspace(String sourceFile, String targetFile, FilePath targetWorkspace)
+ throws IOException, InterruptedException {
+ final ClassLoader classLoader = getClass().getClassLoader();
+ FilePath targetFilePath = new FilePath(targetWorkspace, targetFile);
+ InputStream in = classLoader.getResourceAsStream(sourceFile);
+ targetFilePath.copyFrom(in);
+ // set executable permission
+ targetFilePath.chmod(0755);
+ }
+}
diff --git a/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java b/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java
index cf6a2eb0..b5a2702d 100644
--- a/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java
+++ b/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java
@@ -56,7 +56,7 @@ private void setEnv(EnvVars env) {
this.env = env;
}
- @Symbol("Matlab")
+
@Extension
public static final class UseMatlabVersionDescriptor extends BuildWrapperDescriptor {
diff --git a/src/main/resources/com/mathworks/ci/RunMatlabCommandStep/config.jelly b/src/main/resources/com/mathworks/ci/RunMatlabCommandStep/config.jelly
new file mode 100644
index 00000000..28414b78
--- /dev/null
+++ b/src/main/resources/com/mathworks/ci/RunMatlabCommandStep/config.jelly
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/com/mathworks/ci/RunMatlabTestsStep/config.jelly b/src/main/resources/com/mathworks/ci/RunMatlabTestsStep/config.jelly
new file mode 100644
index 00000000..564268fd
--- /dev/null
+++ b/src/main/resources/com/mathworks/ci/RunMatlabTestsStep/config.jelly
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties
index 7cf08e48..3c9c1dd1 100644
--- a/src/main/resources/config.properties
+++ b/src/main/resources/config.properties
@@ -16,4 +16,6 @@ Builder.matlab.modelcoverage.support.warning = To generate a Cobertura model cov
Builder.matlab.exportstmresults.support.warning = To export Simulink Test Manager results, use MATLAB R2019a or a newer release.
Builder.matlab.runner.script.target.file.linux.name = run_matlab_command.sh
Builder.matlab.runner.script.target.file.windows.name = run_matlab_command.bat
-build.workspace.computer.not.found = Unable to access the computer for this build.
\ No newline at end of file
+build.workspace.computer.not.found = Unable to access the computer for this build.
+matlab.command.build.step.name = runMATLABCommand
+matlab.tests.build.step.name = runMATLABTests
\ No newline at end of file
diff --git a/src/test/java/com/mathworks/ci/RunMatlabCommandStepTest.java b/src/test/java/com/mathworks/ci/RunMatlabCommandStepTest.java
new file mode 100644
index 00000000..36fe579c
--- /dev/null
+++ b/src/test/java/com/mathworks/ci/RunMatlabCommandStepTest.java
@@ -0,0 +1,107 @@
+package com.mathworks.ci;
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.io.IOException;
+import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
+import org.jenkinsci.plugins.workflow.job.WorkflowJob;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+import hudson.FilePath;
+import hudson.slaves.DumbSlave;
+
+public class RunMatlabCommandStepTest {
+
+
+ private WorkflowJob project;
+
+
+
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ @Before
+ public void testSetup() throws IOException {
+ this.project = j.createProject(WorkflowJob.class);
+ }
+
+
+ /*
+ * Verify when MATLAB is not in PATH variable.
+ */
+
+ @Test
+ public void verifyMATLABPathNotSet() throws Exception {
+ project.setDefinition(
+ new CpsFlowDefinition("node { runMATLABCommand(command: 'pwd')}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("MATLAB_ROOT", build);
+ }
+
+ /*
+ * Verify MATLAB is invoked when valid MATLAB is in PATH.
+ *
+ */
+
+ @Test
+ public void verifyMATLABPathSet() throws Exception {
+ project.setDefinition(
+ new CpsFlowDefinition("node { testMATLABCommand(command: 'pwd')}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("tester_started", build);
+ }
+
+ /*
+ * Verify Pipeline script runs on Slave with valid MATLAB
+ *
+ */
+
+ @Test
+ public void verifyPipelineOnSlave() throws Exception {
+ DumbSlave s = j.createOnlineSlave();
+ project.setDefinition(new CpsFlowDefinition(
+ "node('!master') { testMATLABCommand(command: 'pwd')}",
+ true));
+
+ s.getWorkspaceFor(project);
+ WorkflowRun build = project.scheduleBuild2(0).get();
+
+ j.assertBuildStatusSuccess(build);
+ }
+
+ /*
+ * Verify appropriate command is invoked as in pipeline script
+ *
+ */
+
+ @Test
+ public void verifyCommandSameAsScript() throws Exception {
+ project.setDefinition(
+ new CpsFlowDefinition("node { runMATLABCommand(command: 'pwd')}", true));
+
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("pwd", build);
+ }
+
+ /*
+ * Verify script can run Matrix build
+ *
+ */
+
+ @Test
+ public void verifyMatrixBuild() throws Exception {
+ project.setDefinition(new CpsFlowDefinition(
+ "node { matrix {\n" + "agent any\n" + "axes {\n" + "axis {\n" + "name: 'CMD'\n"
+ + "values: 'pwd','ver'\n }}\n" + "runMATLABCommand(command: '${CMD}')}}",
+ true));
+
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("pwd", build);
+ j.assertLogContains("ver", build);
+ }
+}
diff --git a/src/test/java/com/mathworks/ci/RunMatlabCommandStepTester.java b/src/test/java/com/mathworks/ci/RunMatlabCommandStepTester.java
new file mode 100644
index 00000000..ed51a0ae
--- /dev/null
+++ b/src/test/java/com/mathworks/ci/RunMatlabCommandStepTester.java
@@ -0,0 +1,48 @@
+package com.mathworks.ci;
+
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.util.Set;
+import org.jenkinsci.plugins.workflow.steps.StepContext;
+import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
+import org.jenkinsci.plugins.workflow.steps.StepExecution;
+import org.kohsuke.stapler.DataBoundConstructor;
+import com.google.common.collect.ImmutableSet;
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+
+public class RunMatlabCommandStepTester extends RunMatlabCommandStep {
+ @DataBoundConstructor
+ public RunMatlabCommandStepTester(String command) {
+ super(command);
+ }
+
+ @Override
+ public StepExecution start(StepContext context) throws Exception {
+
+ return new TestStepExecution(context,this.getCommand());
+ }
+
+ @Extension
+ public static class CommandStepTestDescriptor extends StepDescriptor {
+
+ @Override
+ public Set extends Class>> getRequiredContext() {
+ return ImmutableSet.of(TaskListener.class, FilePath.class, Launcher.class,
+ EnvVars.class, Run.class);
+ }
+
+ @Override
+ public String getFunctionName() {
+ return "testMATLABCommand";
+ }
+ }
+
+}
diff --git a/src/test/java/com/mathworks/ci/RunMatlabTestsStepTest.java b/src/test/java/com/mathworks/ci/RunMatlabTestsStepTest.java
new file mode 100644
index 00000000..6501ea2f
--- /dev/null
+++ b/src/test/java/com/mathworks/ci/RunMatlabTestsStepTest.java
@@ -0,0 +1,115 @@
+package com.mathworks.ci;
+
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.io.IOException;
+import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
+import org.jenkinsci.plugins.workflow.job.WorkflowJob;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+import hudson.slaves.DumbSlave;
+
+public class RunMatlabTestsStepTest {
+
+ private WorkflowJob project;
+
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ @Before
+ public void testSetup() throws IOException {
+ this.project = j.createProject(WorkflowJob.class);
+ }
+
+
+ /*
+ * Verify when MATLAB Path is not set
+ */
+ @Test
+ public void verifyMATLABPathNotSet() throws Exception {
+ project.setDefinition(new CpsFlowDefinition(
+ "node {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("MATLAB_ROOT", build);
+ }
+
+
+ /*
+ * VErify when MATLAB PATH is set.
+ */
+
+ @Test
+ public void verifyMATLABPathSet() throws Exception {
+ project.setDefinition(new CpsFlowDefinition(
+ "node {testMATLABTests(testResultsPDF:'myresult/result.pdf')}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("tester_started", build);
+ }
+
+ /*
+ * Verify Pipeline runs on slave node
+ */
+
+ @Test
+ public void verifyOnslave() throws Exception {
+ DumbSlave s = j.createOnlineSlave();
+ project.setDefinition(new CpsFlowDefinition(
+ "node('!master') {testMATLABTests(testResultsPDF:'myresult/result.pdf')}", true));
+ s.getWorkspaceFor(project);
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertBuildStatusSuccess(build);
+ }
+
+ /*
+ * Verify artifact path is correct.
+ */
+
+ @Test
+ public void verifyArtifactPath() throws Exception {
+ project.setDefinition(new CpsFlowDefinition(
+ "node {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("'PDFReportPath','myresult/result.pdf'", build);
+ }
+
+ /*
+ * Verify Artifact is not sent as parameter if not selected in script.
+ */
+
+ @Test
+ public void verifyArtifactParameters() throws Exception {
+ project.setDefinition(new CpsFlowDefinition(
+ "node {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("'PDFReportPath','myresult/result.pdf'", build);
+ j.assertLogNotContains("TAPResultsPath", build);
+ j.assertLogNotContains("JUnitResultsPath", build);
+ j.assertLogNotContains("CoberturaCodeCoveragePath", build);
+ j.assertLogNotContains("SimulinkTestResultsPath", build);
+ j.assertLogNotContains("CoberturaModelCoveragePath", build);
+ }
+
+ /*
+ * Verify runMatlabTests runs with empty parameters when nothing no artifact selected
+ */
+
+ @Test
+ public void verifyEmptyParameter() throws Exception {
+ project.setDefinition(new CpsFlowDefinition(
+ "node {runMATLABTests()}", true));
+ WorkflowRun build = project.scheduleBuild2(0).get();
+ j.assertLogContains("runMatlabTests()", build);
+ j.assertLogNotContains("PDFReportPath", build);
+ j.assertLogNotContains("TAPResultsPath", build);
+ j.assertLogNotContains("JUnitResultsPath", build);
+ j.assertLogNotContains("CoberturaCodeCoveragePath", build);
+ j.assertLogNotContains("SimulinkTestResultsPath", build);
+ j.assertLogNotContains("CoberturaModelCoveragePath", build);
+ }
+}
diff --git a/src/test/java/com/mathworks/ci/RunMatlabTestsStepTester.java b/src/test/java/com/mathworks/ci/RunMatlabTestsStepTester.java
new file mode 100644
index 00000000..60a38311
--- /dev/null
+++ b/src/test/java/com/mathworks/ci/RunMatlabTestsStepTester.java
@@ -0,0 +1,72 @@
+package com.mathworks.ci;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import org.jenkinsci.plugins.workflow.steps.StepContext;
+import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
+import org.jenkinsci.plugins.workflow.steps.StepExecution;
+import org.kohsuke.stapler.DataBoundConstructor;
+import com.google.common.collect.ImmutableSet;
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+
+public class RunMatlabTestsStepTester extends RunMatlabTestsStep {
+
+
+ @DataBoundConstructor
+ public RunMatlabTestsStepTester() {
+
+ }
+
+ @Override
+ public StepExecution start(StepContext context) throws Exception {
+ Launcher launcher = context.get(Launcher.class);
+ FilePath workspace = context.get(FilePath.class);
+
+ // Copy Scratch file needed to run MATLAB tests in workspace
+ FilePath targetWorkspace = new FilePath(launcher.getChannel(), workspace.getRemote());
+ copyScratchFileInWorkspace(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_RESOURCE,
+ MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE, targetWorkspace);
+ return new TestStepExecution(context, constructCommandForTest(getInputArgs()));
+ }
+
+ private void copyScratchFileInWorkspace(String sourceFile, String targetFile,
+ FilePath targetWorkspace) throws IOException, InterruptedException {
+ final ClassLoader classLoader = getClass().getClassLoader();
+ FilePath targetFilePath = new FilePath(targetWorkspace, targetFile);
+ InputStream in = classLoader.getResourceAsStream(sourceFile);
+ targetFilePath.copyFrom(in);
+ // set executable permission
+ targetFilePath.chmod(0755);
+ }
+
+ @Extension
+ public static class CommandStepTestDescriptor extends StepDescriptor {
+
+ @Override
+ public Set extends Class>> getRequiredContext() {
+ return ImmutableSet.of(TaskListener.class, FilePath.class, Launcher.class,
+ EnvVars.class, Run.class);
+ }
+
+ @Override
+ public String getFunctionName() {
+ return "testMATLABTests";
+ }
+ }
+
+ public String getInputArgs() {
+ List args = Arrays.asList(getTestResultsPDF(), getTestResultsTAP(),
+ getTestResultsJUnit(), getTestResultsSimulinkTest(), getCodeCoverageCobertura(),
+ getModelCoverageCobertura());
+
+ return String.join(",", args);
+ }
+}
diff --git a/src/test/java/com/mathworks/ci/TestStepExecution.java b/src/test/java/com/mathworks/ci/TestStepExecution.java
new file mode 100644
index 00000000..aa840f6c
--- /dev/null
+++ b/src/test/java/com/mathworks/ci/TestStepExecution.java
@@ -0,0 +1,48 @@
+package com.mathworks.ci;
+/**
+ * Copyright 2020 The MathWorks, Inc.
+ *
+ */
+
+import java.io.IOException;
+import org.jenkinsci.plugins.workflow.steps.StepContext;
+import hudson.EnvVars;
+import hudson.FilePath;
+import hudson.Launcher;
+import hudson.Launcher.ProcStarter;
+import hudson.model.TaskListener;
+
+public class TestStepExecution extends MatlabStepExecution {
+
+ public TestStepExecution(StepContext context, String command) {
+ super(context, command);
+
+ }
+
+ @Override
+ public ProcStarter getProcessToRunMatlabCommand(FilePath workspace, Launcher launcher,
+ TaskListener listener, EnvVars envVars, String matlabCommand, String uniqueName)
+ throws IOException, InterruptedException {
+ // Get node specific tmp directory to copy matlab runner script
+ String tmpDir = getNodeSpecificTmpFolderPath(workspace);
+ FilePath targetWorkspace = new FilePath(launcher.getChannel(), tmpDir);
+ ProcStarter matlabLauncher;
+ if (launcher.isUnix()) {
+ final String runnerScriptName = uniqueName + "/run_matlab_command_test.sh";
+ matlabLauncher = launcher.launch().pwd(workspace).envs(envVars)
+ .cmds(tmpDir + "/" + runnerScriptName, matlabCommand).stdout(listener);
+
+ // Copy runner .sh for linux platform in workspace.
+ copyFileInWorkspace("run_matlab_command_test.sh", runnerScriptName, targetWorkspace);
+ } else {
+ final String runnerScriptName = uniqueName + "\\run_matlab_command_test.bat";
+ launcher = launcher.decorateByPrefix("cmd.exe", "/C");
+ matlabLauncher = launcher.launch().pwd(workspace).envs(envVars)
+ .cmds(tmpDir + "\\" + runnerScriptName, "\"" + matlabCommand + "\"")
+ .stdout(listener);
+ // Copy runner.bat for Windows platform in workspace.
+ copyFileInWorkspace("run_matlab_command_test.bat", runnerScriptName, targetWorkspace);
+ }
+ return matlabLauncher;
+ }
+}
diff --git a/src/test/resources/run_matlab_command_test.bat b/src/test/resources/run_matlab_command_test.bat
new file mode 100755
index 00000000..f17d2e8a
--- /dev/null
+++ b/src/test/resources/run_matlab_command_test.bat
@@ -0,0 +1,7 @@
+rem Copyright 2020 The MathWorks, Inc.
+
+echo "tester_started"
+
+set "arg1=%~1"
+
+echo "%arg1%"
diff --git a/src/test/resources/run_matlab_command_test.sh b/src/test/resources/run_matlab_command_test.sh
new file mode 100755
index 00000000..1d0ddcaa
--- /dev/null
+++ b/src/test/resources/run_matlab_command_test.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+#Copyright 2020 The MathWorks, Inc.
+
+echo "tester_started"
+echo $1