Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.

Commit e7c3f49

Browse files
authored
Merge pull request #150 from mathworks/2.1.4-Qualification
matlab-2.1.4-Qualification
2 parents c42e1f5 + 2aaee4c commit e7c3f49

23 files changed

+250
-345
lines changed

CONFIGDOC.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ The **Run MATLAB Tests** build step enables you to generate different types of t
6060

6161
If you do not select any of the test artifact check boxes, the tests still run, and test failures fail the build.
6262

63-
The **Run MATLAB Tests** build step produces a MATLAB script file named `runMatlabTests.m` in the project workspace. The plugin uses this file to run the tests and generate the test artifacts. You can review the contents of the script to understand the testing workflow.
63+
The **Run MATLAB Tests** build step produces a MATLAB script file and uses it to run the tests and generate the test artifacts. The plugin writes the contents of this file to the build log. You can review the build log in **Console Output** to understand the testing workflow.
6464

6565
**Note:**
6666
* The plugin does not create the `matlabTestArtifacts` folder if the name of the folder does not appear in any of the displayed **File path** boxes.

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ strategy:
1010
mac:
1111
imageName: 'macOS-10.15'
1212
windows:
13-
imageName: 'vs2017-win2016'
13+
imageName: 'windows-latest'
1414

1515
pool:
1616
vmImage: $(imageName)

pom.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,22 @@
124124
<url>https://ssd.mathworks.com/supportfiles/ci/run-matlab-command/v0/run-matlab-command.zip</url>
125125
<unpack>true</unpack>
126126
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
127+
<skipCache>true</skipCache>
128+
<overwrite>true</overwrite>
129+
</configuration>
130+
</execution>
131+
<execution>
132+
<id>get-matlab-gen-script</id>
133+
<phase>validate</phase>
134+
<goals>
135+
<goal>wget</goal>
136+
</goals>
137+
<configuration>
138+
<url>https://ssd.mathworks.com/supportfiles/ci/matlab-script-generator/v0/matlab-script-generator.zip</url>
139+
<unpack>false</unpack>
140+
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
141+
<skipCache>true</skipCache>
142+
<overwrite>true</overwrite>
127143
</configuration>
128144
</execution>
129145
</executions>
@@ -186,6 +202,7 @@
186202
<include>**/*.bat</include>
187203
<include>**/*.sh</include>
188204
<include>**/*.txt</include>
205+
<include>**/*.zip</include>
189206
</includes>
190207
<followSymlinks>false</followSymlinks>
191208
</fileset>

src/main/java/com/mathworks/ci/MatlabBuild.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,30 @@ default String getNodeSpecificTmpFolderPath(FilePath workspace) throws IOExcepti
9696
default String getUniqueNameForRunnerFile() {
9797
return UUID.randomUUID().toString();
9898
}
99+
100+
// This method prepares the temp folder by coping all helper files in it.
101+
default void prepareTmpFldr(FilePath tmpFldr, String runnerScript) throws IOException, InterruptedException {
102+
// Write MATLAB scratch file in temp folder.
103+
FilePath scriptFile =
104+
new FilePath(tmpFldr, getValidMatlabFileName(tmpFldr.getBaseName()) + ".m");
105+
scriptFile.write(runnerScript, "UTF-8");
106+
// copy genscript package
107+
copyFileInWorkspace(MatlabBuilderConstants.MATLAB_SCRIPT_GENERATOR,
108+
MatlabBuilderConstants.MATLAB_SCRIPT_GENERATOR, tmpFldr);
109+
FilePath zipFileLocation =
110+
new FilePath(tmpFldr, MatlabBuilderConstants.MATLAB_SCRIPT_GENERATOR);
111+
112+
// Unzip the file in temp folder.
113+
zipFileLocation.unzip(tmpFldr);
114+
}
115+
116+
default String getRunnerScript(String script, String params) {
117+
script = script.replace("${PARAMS}", params);
118+
return script;
119+
}
120+
121+
default String getValidMatlabFileName(String actualName) {
122+
return MatlabBuilderConstants.MATLAB_TEST_RUNNER_FILE_PREFIX
123+
+ actualName.replaceAll("-", "_");
124+
}
99125
}

src/main/java/com/mathworks/ci/MatlabBuilderConstants.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ public class MatlabBuilderConstants {
1313

1414
static final String MATLAB_RUNNER_TARGET_FILE = "Builder.matlab.runner.target.file.name";
1515
static final String MATLAB_TESTS_RUNNER_TARGET_FILE = "runMatlabTests.m";
16-
static final String MATLAB_TESTS_RUNNER_RESOURCE = "com/mathworks/ci/RunMatlabTestsBuilder/runMatlabTests.m";
1716
static final String MATLAB_RUNNER_RESOURCE = "com/mathworks/ci/MatlabBuilder/runMatlabTests.m";
1817
static final String AUTOMATIC_OPTION = "RunTestsAutomaticallyOption";
1918

@@ -28,4 +27,16 @@ public class MatlabBuilderConstants {
2827
// Matlab Runner files
2928
static final String BAT_RUNNER_SCRIPT = "run_matlab_command.bat";
3029
static final String SHELL_RUNNER_SCRIPT = "run_matlab_command.sh";
30+
31+
//Matlab Script generator package
32+
static final String MATLAB_SCRIPT_GENERATOR = "matlab-script-generator.zip";
33+
34+
//Test runner file prefix
35+
static final String MATLAB_TEST_RUNNER_FILE_PREFIX = "test_runner_";
36+
37+
// MATLAB runner script
38+
static final String TEST_RUNNER_SCRIPT = "testScript = genscript(${PARAMS});\n" + "\n"
39+
+ "disp('Running MATLAB script with content:');\n"
40+
+ "disp(strtrim(testScript.writeToText()));\n"
41+
+ "fprintf('___________________________________\\n\\n');\n" + "run(testScript);\n" + "";
3142
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.mathworks.ci;
2+
3+
/**
4+
* Copyright 2020 The MathWorks, Inc.
5+
*
6+
*/
7+
8+
import java.io.FileNotFoundException;
9+
10+
public class MatlabNotFoundError extends Error {
11+
12+
private static final long serialVersionUID = 7918595075502022644L;
13+
14+
MatlabNotFoundError(String errorMessage){
15+
super(errorMessage);
16+
}
17+
18+
}

src/main/java/com/mathworks/ci/MatlabRunTestsStepExecution.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ public class MatlabRunTestsStepExecution extends SynchronousNonBlockingStepExecu
1919

2020
private static final long serialVersionUID = 6704588180717665100L;
2121

22-
private String command;
22+
private String commandArgs;
2323

2424

25-
public MatlabRunTestsStepExecution(StepContext context, String command) {
25+
public MatlabRunTestsStepExecution(StepContext context, String commandArgs) {
2626
super(context);
27-
this.command = command;
27+
this.commandArgs = commandArgs;
2828
}
2929

30-
private String getCommand() {
31-
return this.command;
30+
private String getCommandArgs() {
31+
return this.commandArgs;
3232
}
3333

3434
@Override
@@ -58,10 +58,19 @@ private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher
5858
TaskListener listener, EnvVars envVars) throws IOException, InterruptedException {
5959
final String uniqueTmpFldrName = getUniqueNameForRunnerFile();
6060
try {
61-
ProcStarter matlabLauncher = getProcessToRunMatlabCommand(workspace, launcher, listener, envVars,
62-
envVars.expand(getCommand()), uniqueTmpFldrName);
61+
FilePath genScriptLocation =
62+
getFilePathForUniqueFolder(launcher, uniqueTmpFldrName, workspace);
63+
final String cmdPrefix =
64+
"addpath('" + genScriptLocation.getRemote().replaceAll("'", "''") + "'); ";
65+
final String matlabScriptName = getValidMatlabFileName(genScriptLocation.getBaseName());
66+
67+
ProcStarter matlabLauncher = getProcessToRunMatlabCommand(workspace, launcher, listener,
68+
envVars, cmdPrefix + matlabScriptName, uniqueTmpFldrName);
6369

64-
70+
// prepare temp folder by coping genscript package and writing runner script.
71+
prepareTmpFldr(genScriptLocation,
72+
getRunnerScript(MatlabBuilderConstants.TEST_RUNNER_SCRIPT, envVars.expand(getCommandArgs())));
73+
6574
return matlabLauncher.pwd(workspace).join();
6675
} catch (Exception e) {
6776
listener.getLogger().println(e.getMessage());

src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
import java.io.IOException;
1212
import java.util.*;
1313
import javax.annotation.Nonnull;
14-
import org.apache.commons.collections.map.HashedMap;
15-
import org.apache.commons.io.FilenameUtils;
16-
import org.jenkinsci.Symbol;
1714
import org.kohsuke.stapler.DataBoundConstructor;
1815
import org.kohsuke.stapler.DataBoundSetter;
1916
import org.kohsuke.stapler.StaplerRequest;
@@ -239,13 +236,15 @@ private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher
239236
final String uniqueTmpFldrName = getUniqueNameForRunnerFile();
240237
ProcStarter matlabLauncher;
241238
try {
239+
FilePath genScriptLocation =
240+
getFilePathForUniqueFolder(launcher, uniqueTmpFldrName, workspace);
241+
242242
matlabLauncher = getProcessToRunMatlabCommand(workspace, launcher, listener, envVars,
243-
constructCommandForTest(getInputArguments()), uniqueTmpFldrName);
243+
constructCommandForTest(genScriptLocation), uniqueTmpFldrName);
244244

245-
// Copy MATLAB scratch file into the workspace.
246-
FilePath targetWorkspace = new FilePath(launcher.getChannel(), workspace.getRemote());
247-
copyFileInWorkspace(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_RESOURCE,
248-
MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE, targetWorkspace);
245+
// copy genscript package in temp folder and write a runner script.
246+
prepareTmpFldr(genScriptLocation, getRunnerScript(
247+
MatlabBuilderConstants.TEST_RUNNER_SCRIPT, envVars.expand(getInputArguments())));
249248

250249
return matlabLauncher.pwd(workspace).join();
251250
} catch (Exception e) {
@@ -260,11 +259,11 @@ private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher
260259
}
261260
}
262261
}
263-
264-
public String constructCommandForTest(String inputArguments) {
265-
final String matlabFunctionName =
266-
FilenameUtils.removeExtension(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE);
267-
final String runCommand = "exit(" + matlabFunctionName + "(" + inputArguments + "))";
262+
263+
public String constructCommandForTest(FilePath scriptPath) {
264+
final String matlabScriptName = getValidMatlabFileName(scriptPath.getBaseName());
265+
final String runCommand = "addpath('" + scriptPath.getRemote().replaceAll("'", "''")
266+
+ "'); " + matlabScriptName;
268267
return runCommand;
269268
}
270269

@@ -278,12 +277,14 @@ private String getInputArguments() {
278277
new ArrayList<Artifact>(Arrays.asList(getPdfReportArtifact(), getTapArtifact(),
279278
getJunitArtifact(), getStmResultsArtifact(), getCoberturaArtifact(),
280279
getModelCoverageArtifact()));
280+
281+
inputArgsList.add("'Test'");
281282

282283
for (Artifact artifact : artifactList) {
283284
artifact.addFilePathArgTo(args);
284285
}
285286

286-
args.forEach((key, val) -> inputArgsList.add("'" + key + "'" + "," + "'" + val + "'"));
287+
args.forEach((key, val) -> inputArgsList.add("'" + key + "'" + "," + "'" + val.replaceAll("'", "''") + "'"));
287288

288289
return String.join(",", inputArgsList);
289290
}
@@ -301,7 +302,7 @@ private String getInputArguments() {
301302
*/
302303
public static class PdfArtifact extends AbstractArtifactImpl {
303304

304-
private static final String PDF_REPORT_PATH = "PDFReportPath";
305+
private static final String PDF_TEST_REPORT = "PDFTestReport";
305306

306307
@DataBoundConstructor
307308
public PdfArtifact(String pdfReportFilePath) {
@@ -310,13 +311,13 @@ public PdfArtifact(String pdfReportFilePath) {
310311

311312
@Override
312313
public void addFilePathArgTo(Map<String, String> inputArgs) {
313-
inputArgs.put(PDF_REPORT_PATH, getFilePath());
314+
inputArgs.put(PDF_TEST_REPORT, getFilePath());
314315
}
315316
}
316317

317318
public static class TapArtifact extends AbstractArtifactImpl {
318319

319-
private static final String TAP_RESULTS_PATH = "TAPResultsPath";
320+
private static final String TAP_TEST_RESULTS = "TAPTestResults";
320321

321322
@DataBoundConstructor
322323
public TapArtifact(String tapReportFilePath) {
@@ -325,13 +326,13 @@ public TapArtifact(String tapReportFilePath) {
325326

326327
@Override
327328
public void addFilePathArgTo(Map<String, String> inputArgs) {
328-
inputArgs.put(TAP_RESULTS_PATH, getFilePath());
329+
inputArgs.put(TAP_TEST_RESULTS, getFilePath());
329330
}
330331
}
331332

332333
public static class JunitArtifact extends AbstractArtifactImpl {
333334

334-
private static final String JUNIT_RESULTS_PATH = "JUnitResultsPath";
335+
private static final String JUNIT_TEST_RESULTS = "JUnitTestResults";
335336

336337
@DataBoundConstructor
337338
public JunitArtifact(String junitReportFilePath) {
@@ -340,13 +341,13 @@ public JunitArtifact(String junitReportFilePath) {
340341

341342
@Override
342343
public void addFilePathArgTo(Map<String, String> inputArgs) {
343-
inputArgs.put(JUNIT_RESULTS_PATH, getFilePath());
344+
inputArgs.put(JUNIT_TEST_RESULTS, getFilePath());
344345
}
345346
}
346347

347348
public static class CoberturaArtifact extends AbstractArtifactImpl {
348349

349-
private static final String COBERTURA_CODE_COVERAGE_PATH = "CoberturaCodeCoveragePath";
350+
private static final String COBERTURA_CODE_COVERAGE = "CoberturaCodeCoverage";
350351

351352
@DataBoundConstructor
352353
public CoberturaArtifact(String coberturaReportFilePath) {
@@ -355,13 +356,13 @@ public CoberturaArtifact(String coberturaReportFilePath) {
355356

356357
@Override
357358
public void addFilePathArgTo(Map<String, String> inputArgs) {
358-
inputArgs.put(COBERTURA_CODE_COVERAGE_PATH, getFilePath());
359+
inputArgs.put(COBERTURA_CODE_COVERAGE, getFilePath());
359360
}
360361
}
361362

362363
public static class StmResultsArtifact extends AbstractArtifactImpl {
363364

364-
private static final String STM_RESULTS_PATH = "SimulinkTestResultsPath";
365+
private static final String STM_RESULTS = "SimulinkTestResults";
365366

366367
@DataBoundConstructor
367368
public StmResultsArtifact(String stmResultsFilePath) {
@@ -370,13 +371,13 @@ public StmResultsArtifact(String stmResultsFilePath) {
370371

371372
@Override
372373
public void addFilePathArgTo(Map<String, String> inputArgs) {
373-
inputArgs.put(STM_RESULTS_PATH, getFilePath());
374+
inputArgs.put(STM_RESULTS, getFilePath());
374375
}
375376
}
376377

377378
public static class ModelCovArtifact extends AbstractArtifactImpl {
378379

379-
private static final String COBERTURA_MODEL_COVERAGE_PATH = "CoberturaModelCoveragePath";
380+
private static final String COBERTURA_MODEL_COVERAGE = "CoberturaModelCoverage";
380381

381382
@DataBoundConstructor
382383
public ModelCovArtifact(String modelCoverageFilePath) {
@@ -385,7 +386,7 @@ public ModelCovArtifact(String modelCoverageFilePath) {
385386

386387
@Override
387388
public void addFilePathArgTo(Map<String, String> inputArgs) {
388-
inputArgs.put(COBERTURA_MODEL_COVERAGE_PATH, getFilePath());
389+
inputArgs.put(COBERTURA_MODEL_COVERAGE, getFilePath());
389390
}
390391
}
391392

0 commit comments

Comments
 (0)