Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Genscript changes #130

Merged
merged 6 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,18 @@
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
</configuration>
</execution>
<execution>
<id>get-matlab-gen-script</id>
<phase>validate</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://ssd.mathworks.com/supportfiles/ci/matlab-script-generator/v0/matlab-script-generator.zip</url>
nbhoski marked this conversation as resolved.
Show resolved Hide resolved
<unpack>false</unpack>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Expand Down Expand Up @@ -186,6 +198,7 @@
<include>**/*.bat</include>
<include>**/*.sh</include>
<include>**/*.txt</include>
<include>**/*.zip</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/mathworks/ci/MatlabBuild.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,16 @@ default String getNodeSpecificTmpFolderPath(FilePath workspace) throws IOExcepti
default String getUniqueNameForRunnerFile() {
return UUID.randomUUID().toString();
}

// This method prepares the temp folder by coping all helper files in it.
default void prepareTmpFldr(FilePath tmpFldr) throws IOException, InterruptedException {
// copy genscript package
copyFileInWorkspace(MatlabBuilderConstants.MATLAB_SCRIPT_GENERATOR,
MatlabBuilderConstants.MATLAB_SCRIPT_GENERATOR, tmpFldr);
FilePath zipFileLocation =
new FilePath(tmpFldr, MatlabBuilderConstants.MATLAB_SCRIPT_GENERATOR);

// Unzip the file in temp folder.
zipFileLocation.unzip(tmpFldr);
}
}
3 changes: 3 additions & 0 deletions src/main/java/com/mathworks/ci/MatlabBuilderConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ public class MatlabBuilderConstants {
// Matlab Runner files
static final String BAT_RUNNER_SCRIPT = "run_matlab_command.bat";
static final String SHELL_RUNNER_SCRIPT = "run_matlab_command.sh";

//Matlab Script generator package
static final String MATLAB_SCRIPT_GENERATOR = "matlab-script-generator.zip";
}
16 changes: 13 additions & 3 deletions src/main/java/com/mathworks/ci/MatlabRunTestsStepExecution.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,20 @@ 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);
FilePath genScriptLocation =
getFilePathForUniqueFolder(launcher, uniqueTmpFldrName, workspace);
final String cmdPrefix = "addpath(genpath('" + genScriptLocation.getRemote() + "')); ";
nbhoski marked this conversation as resolved.
Show resolved Hide resolved
nbhoski marked this conversation as resolved.
Show resolved Hide resolved

ProcStarter matlabLauncher = getProcessToRunMatlabCommand(workspace, launcher, listener,
envVars, cmdPrefix + envVars.expand(getCommand()), uniqueTmpFldrName);

//Copy Scratch file needed to run MATLAB tests in workspace
copyFileInWorkspace(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_RESOURCE,
MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE, workspace);


//prepare temp folder by coping genscript package.
prepareTmpFldr(genScriptLocation);

return matlabLauncher.pwd(workspace).join();
} catch (Exception e) {
listener.getLogger().println(e.getMessage());
Expand Down
20 changes: 13 additions & 7 deletions src/main/java/com/mathworks/ci/RunMatlabTestsBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,19 @@ private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher
final String uniqueTmpFldrName = getUniqueNameForRunnerFile();
ProcStarter matlabLauncher;
try {
FilePath genScriptLocation =
getFilePathForUniqueFolder(launcher, uniqueTmpFldrName, workspace);

matlabLauncher = getProcessToRunMatlabCommand(workspace, launcher, listener, envVars,
constructCommandForTest(getInputArguments()), uniqueTmpFldrName);
constructCommandForTest(getInputArguments(), genScriptLocation.getRemote()),
uniqueTmpFldrName);

// Copy MATLAB scratch file into the workspace.
FilePath targetWorkspace = new FilePath(launcher.getChannel(), workspace.getRemote());
// Copy MATLAB scratch file into the workspace.
copyFileInWorkspace(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_RESOURCE,
MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE, targetWorkspace);
MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE, workspace);
nbhoski marked this conversation as resolved.
Show resolved Hide resolved

// copy genscript package in temp folder
prepareTmpFldr(genScriptLocation);

return matlabLauncher.pwd(workspace).join();
} catch (Exception e) {
Expand All @@ -259,11 +265,11 @@ private synchronized int execMatlabCommand(FilePath workspace, Launcher launcher
}
}
}

public String constructCommandForTest(String inputArguments) {
public String constructCommandForTest(String inputArguments, String scriptPath) {
final String matlabFunctionName =
FilenameUtils.removeExtension(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE);
final String runCommand = "exit(" + matlabFunctionName + "(" + inputArguments + "))";
final String runCommand = "addpath(genpath('"+scriptPath+"')); " + matlabFunctionName + "(" + inputArguments + ")";
return runCommand;
}

Expand Down
33 changes: 3 additions & 30 deletions src/main/java/com/mathworks/ci/RunMatlabTestsStep.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
package com.mathworks.ci;
/**
* Copyright 2020 The MathWorks, Inc.
*
*/
import java.io.IOException;
import java.io.InputStream;

/**
* Copyright 2020 The MathWorks, Inc.
*
Expand Down Expand Up @@ -104,16 +97,9 @@ public void setModelCoverageCobertura(String 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 MatlabRunTestsStepExecution(context,constructCommandForTest(getInputArgs()));
return new MatlabRunTestsStepExecution(context, constructCommandForTest(getInputArgs()));
}

@Extension
public static class RunTestsStepDescriptor extends StepDescriptor {

Expand All @@ -137,7 +123,7 @@ public String getDisplayName() {
public String constructCommandForTest(String inputArguments) {
final String matlabFunctionName =
FilenameUtils.removeExtension(MatlabBuilderConstants.MATLAB_TESTS_RUNNER_TARGET_FILE);
final String runCommand = "exit(" + matlabFunctionName + "(" + inputArguments + "))";
final String runCommand = matlabFunctionName + "(" + inputArguments + ")";
return runCommand;
}

Expand Down Expand Up @@ -169,17 +155,4 @@ private Map<String, String> getMatlabArgs() {
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);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%Copyright 2019-2020 The MathWorks, Inc.
%Copyright 2020 The MathWorks, Inc.

function failed = runMatlabTests(varargin)
function runMatlabTests(varargin)
nbhoski marked this conversation as resolved.
Show resolved Hide resolved

p = inputParser;
validationFcn = @(c)ischar(c) && (isempty(c) || isrow(c));
Expand All @@ -14,175 +14,16 @@

p.parse(varargin{:});


pdfReportPath = p.Results.PDFReportPath;
tapReportPath = p.Results.TAPResultsPath;
junitReportPath = p.Results.JUnitResultsPath;
stmReportPath = p.Results.SimulinkTestResultsPath;
coberturaReportPath = p.Results.CoberturaCodeCoveragePath;
modelCoveragePath = p.Results.CoberturaModelCoveragePath;

BASE_VERSION_MATLABUNIT_SUPPORT = '8.1';

if verLessThan('matlab',BASE_VERSION_MATLABUNIT_SUPPORT)
error('MATLAB:unitTest:testFrameWorkNotSupported','Running tests automatically is not supported in this relase.');
end

%Create test suite for tests folder
suite = getTestSuite();

% Create and configure the runner
import('matlab.unittest.TestRunner');
runner = TestRunner.withTextOutput;



% Produce JUnit report
if ~isempty(junitReportPath)
BASE_VERSION_JUNIT_SUPPORT = '8.6';
if verLessThan('matlab',BASE_VERSION_JUNIT_SUPPORT)
warning('MATLAB:testArtifact:junitReportNotSupported', 'Producing JUnit xml results is not supported in this release.');
else
import('matlab.unittest.plugins.XMLPlugin');
preparePath(junitReportPath);
runner.addPlugin(XMLPlugin.producingJUnitFormat(junitReportPath));
end
end

% Produce TAP report
if ~isempty(tapReportPath)
BASE_VERSION_TAPORIGINALFORMAT_SUPPORT = '8.3';
BASE_VERSION_TAP13_SUPPORT = '9.1';
if verLessThan('matlab',BASE_VERSION_TAPORIGINALFORMAT_SUPPORT)
warning('MATLAB:testArtifact:tapReportNotSupported', 'Producing TAP results is not supported in this release.');
elseif verLessThan('matlab',BASE_VERSION_TAP13_SUPPORT)
tapFile = getTapResultFile(tapReportPath);
import('matlab.unittest.plugins.TAPPlugin');
tapPlugin = TAPPlugin.producingOriginalFormat(tapFile);
runner.addPlugin(tapPlugin);
else
tapFile = getTapResultFile(tapReportPath);
import('matlab.unittest.plugins.TAPPlugin');
tapPlugin = TAPPlugin.producingVersion13(tapFile);
runner.addPlugin(tapPlugin);
end

end

% Produce Cobertura report (Cobertura report generation is not supported
% below R17a)
if ~isempty(coberturaReportPath)
BASE_VERSION_COBERTURA_SUPPORT = '9.3';

if verLessThan('matlab',BASE_VERSION_COBERTURA_SUPPORT)
warning('MATLAB:testArtifact:coberturaReportNotSupported', 'Producing Cobertura code coverage results is not supported in this release.');
else
import('matlab.unittest.plugins.CodeCoveragePlugin');
preparePath(coberturaReportPath);
workSpace = fullfile(pwd);
runner.addPlugin(CodeCoveragePlugin.forFolder(workSpace,'IncludingSubfolders',true,...
'Producing', CoberturaFormat(coberturaReportPath)));
end
end

% Produce Cobertura model coverage report (Not supported below R2018b)
if ~isempty(modelCoveragePath)
if ~exist('sltest.plugins.ModelCoveragePlugin', 'class') || ~coberturaModelCoverageSupported
warning('MATLAB:testArtifact:cannotGenerateModelCoverageReport', ...
'Unable to generate Cobertura model coverage report. To generate the report, use a Simulink Coverage license with MATLAB R2018b or a newer release.');
else
import('sltest.plugins.ModelCoveragePlugin');

preparePath(modelCoveragePath);
runner.addPlugin(ModelCoveragePlugin('Producing',CoberturaFormat(modelCoveragePath)));
end
end

stmResultsPluginAddedToRunner = false;

% Save Simulink Test Manager results in MLDATX format (Not supported below R2019a)
if ~isempty(stmReportPath)
if ~stmResultsPluginPresent || ~exportSTMResultsSupported
issueExportSTMResultsUnsupportedWarning;
else
preparePath(stmReportPath);
runner.addPlugin(TestManagerResultsPlugin('ExportToFile', stmReportPath));
stmResultsPluginAddedToRunner = true;
end
end

% Produce PDF test report (Not supported on MacOS platforms and below R2017a)
if ~isempty(pdfReportPath)
if ismac
warning('MATLAB:testArtifact:unSupportedPlatform', ...
'Producing a PDF test report is not currently supported on MacOS platforms.');
elseif ~testReportPluginPresent
issuePDFReportUnsupportedWarning;
else
preparePath(pdfReportPath);
import('matlab.unittest.plugins.TestReportPlugin');
runner.addPlugin(TestReportPlugin.producingPDF(pdfReportPath));

if ~stmResultsPluginAddedToRunner && stmResultsPluginPresent
runner.addPlugin(TestManagerResultsPlugin);
end
end
end

results = runner.run(suite);
failed = any([results.Failed]);

function preparePath(path)
dir = fileparts(path);
dirExists = isempty(dir) || exist(dir,'dir') == 7;
if ~dirExists
mkdir(dir);
end

function tapFile = getTapResultFile(resultsDir)
import('matlab.unittest.plugins.ToFile');
preparePath(resultsDir);
fclose(fopen(resultsDir,'w'));
tapFile = matlab.unittest.plugins.ToFile(resultsDir);

function suite = getTestSuite()
import('matlab.unittest.TestSuite');
BASE_VERSION_TESTSUITE_SUPPORT = '9.0';
if verLessThan('matlab',BASE_VERSION_TESTSUITE_SUPPORT)
suite = matlab.unittest.TestSuite.fromFolder(pwd,'IncludingSubfolders',true);
else
suite = testsuite(pwd,'IncludeSubfolders',true);
end

function plugin = CoberturaFormat(varargin)
plugin = matlab.unittest.plugins.codecoverage.CoberturaFormat(varargin{:});

function plugin = TestManagerResultsPlugin(varargin)
plugin = sltest.plugins.TestManagerResultsPlugin(varargin{:});

function tf = testReportPluginPresent
BASE_VERSION_REPORTPLUGIN_SUPPORT = '9.2'; % R2017a

tf = ~verLessThan('matlab',BASE_VERSION_REPORTPLUGIN_SUPPORT);

function tf = stmResultsPluginPresent
tf = logical(exist('sltest.plugins.TestManagerResultsPlugin', 'class'));

function tf = coberturaModelCoverageSupported
BASE_VERSION_MODELCOVERAGE_SUPPORT = '9.5'; % R2018b

tf = ~verLessThan('matlab',BASE_VERSION_MODELCOVERAGE_SUPPORT);

function tf = exportSTMResultsSupported
BASE_VERSION_EXPORTSTMRESULTS_SUPPORT = '9.6'; % R2019a

tf = ~verLessThan('matlab',BASE_VERSION_EXPORTSTMRESULTS_SUPPORT);

function issuePDFReportUnsupportedWarning
warning('MATLAB:testArtifact:pdfReportNotSupported', ...
'Producing a test report in PDF format is not supported in the current MATLAB release.');
testScript = genscript('Test','PDFTestReport',pdfReportPath,'TAPTestResults',tapReportPath,'JUnitTestResults',junitReportPath,'SimulinkTestResults',stmReportPath,'CoberturaCodeCoverage',coberturaReportPath,'CoberturaModelCoverage',modelCoveragePath);

function issueExportSTMResultsUnsupportedWarning
warning('MATLAB:testArtifact:cannotExportSimulinkTestManagerResults', ...
['Unable to export Simulink Test Manager results. This feature ', ...
'requires a Simulink Test license and is supported only in MATLAB R2019a or a newer release.']);
disp('Running MATLAB script with content:\n');
disp(strtrim(testScript.writeToText()));
fprintf('___________________________________\n\n');
run(testScript);
7 changes: 4 additions & 3 deletions src/test/java/com/mathworks/ci/RunMatlabTestsBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ public void verifyMATLABlaunchedWithDefaultArgumentsBatch() throws Exception {
project.getBuildersList().add(this.testBuilder);
FreeStyleBuild build = project.scheduleBuild2(0).get();
jenkins.assertLogContains("run_matlab_command", build);
jenkins.assertLogContains("exit(runMatlabTests", build);
jenkins.assertLogContains("runMatlabTests", build);
jenkins.assertLogContains("addpath(genpath", build);
}

/*
Expand All @@ -157,7 +158,7 @@ public void verifyMATLABlaunchedWithDefaultArgumentsRWindows() throws Exception
project.getBuildersList().add(testBuilder);
FreeStyleBuild build = project.scheduleBuild2(0).get();
jenkins.assertLogContains("run_matlab_command", build);
jenkins.assertLogContains("exit(runMatlabTests", build);
jenkins.assertLogContains("runMatlabTests", build);
}

/*
Expand Down Expand Up @@ -328,7 +329,7 @@ public void veriyEmptyParameters() throws Exception {
project.getBuildersList().add(this.testBuilder);
FreeStyleBuild build = project.scheduleBuild2(0).get();
jenkins.assertLogContains("run_matlab_command", build);
jenkins.assertLogContains("exit(runMatlabTests())", build);
jenkins.assertLogContains("runMatlabTests()", build);
}


Expand Down
Loading