diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 30ae949c..afd10b7a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -19,6 +19,12 @@ trigger: - master steps: + - task: JavaToolInstaller@0 + inputs: + versionSpec: '11' + jdkArchitectureOption: 'x64' + jdkSourceOption: 'PreInstalled' + - task: Maven@4 inputs: mavenPomFile: 'pom.xml' diff --git a/pom.xml b/pom.xml index 12c1b9fb..4c7117bd 100644 --- a/pom.xml +++ b/pom.xml @@ -4,61 +4,74 @@ org.jenkins-ci.plugins plugin - 3.57 + 4.75 + matlab 2.15.1-SNAPSHOT hpi + + MATLAB Plugin + https://github.com/jenkinsci/matlab-plugin + Jenkins plugin for MATLAB + mathworks_ci_team MathWorks - nbhoski@mathworks.com + continuous-integration@mathworks.com - - 2.164.3 - 8 - - MATLAB Plugin - Jenkins plugin for MATLAB - https://github.com/jenkinsci/matlab-plugin + MIT License https://opensource.org/licenses/MIT + repo.jenkins-ci.org https://repo.jenkins-ci.org/public/ + repo.jenkins-ci.org https://repo.jenkins-ci.org/public/ + scm:git:ssh://github.com/jenkinsci/matlab-plugin.git scm:git:ssh://git@github.com/jenkinsci/matlab-plugin.git - http://github.com/jenkinsci/matlab-plugin + https://github.com/jenkinsci/matlab-plugin HEAD + + + + 2.387 + ${jenkins.baseline}.3 + + High + + io.jenkins.tools.bom - bom-2.164.x - 4 - import + bom-${jenkins.baseline}.x + 2543.vfb_1a_5fb_9496d pom + import + @@ -100,16 +113,25 @@ workflow-job test - - - org.mockito - mockito-core - 3.1.0 - test - + + org.mockito + mockito-core + 3.1.0 + test + + + org.eclipse.jetty + jetty-util + 11.0.24 + test + + + org.jenkins-ci.tools + maven-hpi-plugin + diff --git a/src/main/java/com/mathworks/ci/BuildArtifactAction.java b/src/main/java/com/mathworks/ci/BuildArtifactAction.java index cc50f9b7..e5c5b0fb 100644 --- a/src/main/java/com/mathworks/ci/BuildArtifactAction.java +++ b/src/main/java/com/mathworks/ci/BuildArtifactAction.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import hudson.FilePath; @@ -36,16 +35,16 @@ public BuildArtifactAction(Run build, String actionID) { this.actionID = actionID; // Setting the counts of task when Action is created. - try{ + try { setCounts(); } catch (ParseException e) { throw new RuntimeException(e); - } catch (InterruptedException e){ + } catch (InterruptedException e) { throw new RuntimeException(e); } } - public String getActionID(){ + public String getActionID() { return (this.actionID == null) ? "" : this.actionID; } @@ -64,13 +63,13 @@ public String getDisplayName() { @CheckForNull @Override public String getUrlName() { - return (this.actionID == null) ? "buildresults" : "buildresults" + this.actionID ; + return (this.actionID == null) ? "buildresults" : "buildresults" + this.actionID; } public List getBuildArtifact() throws ParseException, InterruptedException, IOException { List artifactData = new ArrayList(); FilePath fl; - if(this.actionID == null){ + if (this.actionID == null) { fl = new FilePath(new File(build.getRootDir().getAbsolutePath() + "/" + MatlabBuilderConstants.BUILD_ARTIFACT + ".json")); } else { @@ -147,7 +146,7 @@ public void setOwner(Run owner) { private void setCounts() throws InterruptedException, ParseException { List artifactData = new ArrayList(); FilePath fl; - if(this.actionID == null){ + if (this.actionID == null) { fl = new FilePath(new File(build.getRootDir().getAbsolutePath() + "/" + MatlabBuilderConstants.BUILD_ARTIFACT + ".json")); } else { @@ -206,11 +205,11 @@ private void setCounts() throws InterruptedException, ParseException { private void iterateAllTaskAttributes(Entry pair, BuildArtifactData data) { // Iterates across all task attributes and updates String key = pair.getKey().toString(); - switch(key){ + switch (key) { case "duration": data.setTaskDuration(pair.getValue().toString()); break; - case "name" : + case "name": data.setTaskName(pair.getValue().toString()); break; case "description": @@ -225,7 +224,7 @@ private void iterateAllTaskAttributes(Entry pair, BuildArtifactData data) { case "skipReason": String skipReasonKey = pair.getValue().toString(); String skipReason; - switch(skipReasonKey){ + switch (skipReasonKey) { case "UpToDate": skipReason = "up-to-date"; break; @@ -242,7 +241,7 @@ private void iterateAllTaskAttributes(Entry pair, BuildArtifactData data) { } data.setSkipReason(skipReason); break; - default : + default: break; } } diff --git a/src/main/java/com/mathworks/ci/BuildArtifactData.java b/src/main/java/com/mathworks/ci/BuildArtifactData.java index eac3bc19..0ecd6926 100644 --- a/src/main/java/com/mathworks/ci/BuildArtifactData.java +++ b/src/main/java/com/mathworks/ci/BuildArtifactData.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ public class BuildArtifactData { diff --git a/src/main/java/com/mathworks/ci/BuildConsoleAnnotator.java b/src/main/java/com/mathworks/ci/BuildConsoleAnnotator.java index 8197b6d8..53a3fda2 100644 --- a/src/main/java/com/mathworks/ci/BuildConsoleAnnotator.java +++ b/src/main/java/com/mathworks/ci/BuildConsoleAnnotator.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import com.google.common.base.Charsets; @@ -39,7 +38,7 @@ private static byte[][] createBuildNotes() { ByteArrayOutputStream targetNote = new ByteArrayOutputStream(); new BuildTargetNote().encodeTo(targetNote); ByteArrayOutputStream outcomeNote = new ByteArrayOutputStream(); - return new byte[][]{targetNote.toByteArray(), outcomeNote.toByteArray()}; + return new byte[][] { targetNote.toByteArray(), outcomeNote.toByteArray() }; } catch (IOException e) { throw new RuntimeException(e); } @@ -71,7 +70,7 @@ private static class ConsoleLogFilterImpl extends ConsoleLogFilter implements Se private static final long serialVersionUID = 1; private byte[][] buildNotes = createBuildNotes(); - //Taking care of old MATLAB build actions. + // Taking care of old MATLAB build actions. private Object readResolve() { if (buildNotes == null) { buildNotes = createBuildNotes(); diff --git a/src/main/java/com/mathworks/ci/BuildTargetNote.java b/src/main/java/com/mathworks/ci/BuildTargetNote.java index b047105c..cf3062c9 100644 --- a/src/main/java/com/mathworks/ci/BuildTargetNote.java +++ b/src/main/java/com/mathworks/ci/BuildTargetNote.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import com.google.common.annotations.VisibleForTesting; @@ -14,7 +13,6 @@ import hudson.console.ConsoleNote; import java.util.regex.Pattern; - public class BuildTargetNote extends ConsoleNote { @VisibleForTesting @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Visible for testing") @@ -26,10 +24,10 @@ public BuildTargetNote() { @Override public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { MarkupText.SubText t = text.findToken(Pattern.compile("MATLAB-Build-")); - String taskName = text.subText(13, text.length()-2).getText(); - taskName = taskName.replace("]","").trim(); + String taskName = text.subText(13, text.length() - 2).getText(); + taskName = taskName.replace("]", "").trim(); if (t != null) - t.addMarkup(0, t.length()-1, "", ""); + t.addMarkup(0, t.length() - 1, "", ""); return null; } diff --git a/src/main/java/com/mathworks/ci/FormValidationUtil.java b/src/main/java/com/mathworks/ci/FormValidationUtil.java index 8ccba320..05f2c8c2 100644 --- a/src/main/java/com/mathworks/ci/FormValidationUtil.java +++ b/src/main/java/com/mathworks/ci/FormValidationUtil.java @@ -1,10 +1,9 @@ package com.mathworks.ci; /** - * Copyright 2019-2020 The MathWorks, Inc. + * Copyright 2019-2024 The MathWorks, Inc. * * This is Utility class which provides commonly used methods for form validations across builders - * */ import java.util.List; diff --git a/src/main/java/com/mathworks/ci/ListenerLogDecorator.java b/src/main/java/com/mathworks/ci/ListenerLogDecorator.java index 454f843e..9ea6af29 100644 --- a/src/main/java/com/mathworks/ci/ListenerLogDecorator.java +++ b/src/main/java/com/mathworks/ci/ListenerLogDecorator.java @@ -1,8 +1,8 @@ package com.mathworks.ci; -/* -* Copyright 2018 The MathWorks, Inc. -*/ +/** + * Copyright 2018-2024 The MathWorks, Inc. + */ import java.io.IOException; import java.io.OutputStream; diff --git a/src/main/java/com/mathworks/ci/MatlabBuildWrapperContent.java b/src/main/java/com/mathworks/ci/MatlabBuildWrapperContent.java index 193a84ab..9ccc7570 100644 --- a/src/main/java/com/mathworks/ci/MatlabBuildWrapperContent.java +++ b/src/main/java/com/mathworks/ci/MatlabBuildWrapperContent.java @@ -1,10 +1,9 @@ package com.mathworks.ci; /** - * Copyright 2020 The MathWorks, Inc. + * Copyright 2020-2024 The MathWorks, Inc. * * Class to parse Stapler request for Use MATLAB Version build wrapper. - * */ import org.kohsuke.stapler.DataBoundConstructor; @@ -15,7 +14,7 @@ public class MatlabBuildWrapperContent { private final String matlabRootFolder; @DataBoundConstructor - public MatlabBuildWrapperContent(String matlabInstallationName, String matlabRootFolder){ + public MatlabBuildWrapperContent(String matlabInstallationName, String matlabRootFolder) { this.matlabInstallationName = matlabInstallationName; this.matlabRootFolder = matlabRootFolder; } diff --git a/src/main/java/com/mathworks/ci/MatlabBuilderConstants.java b/src/main/java/com/mathworks/ci/MatlabBuilderConstants.java index 62b9c130..27a8b593 100644 --- a/src/main/java/com/mathworks/ci/MatlabBuilderConstants.java +++ b/src/main/java/com/mathworks/ci/MatlabBuilderConstants.java @@ -1,7 +1,7 @@ package com.mathworks.ci; /* - * Copyright 2019-2020 The MathWorks, Inc. + * Copyright 2019-2024 The MathWorks, Inc. */ public class MatlabBuilderConstants { @@ -11,27 +11,28 @@ public class MatlabBuilderConstants { public static final double BASE_MATLAB_VERSION_COBERTURA_SUPPORT = 9.3; public static final double BASE_MATLAB_VERSION_MODELCOVERAGE_SUPPORT = 9.5; public static final double BASE_MATLAB_VERSION_EXPORTSTMRESULTS_SUPPORT = 9.6; - + public static final String MATLAB_RUNNER_TARGET_FILE = "Builder.matlab.runner.target.file.name"; public static final String MATLAB_TESTS_RUNNER_TARGET_FILE = "runMatlabTests.m"; public static final String MATLAB_RUNNER_RESOURCE = "com/mathworks/ci/MatlabBuilder/runMatlabTests.m"; public static final String AUTOMATIC_OPTION = "RunTestsAutomaticallyOption"; - - // Input parameter names (Passed to runMatlabTests.m as name-value pair arguments) + + // Input parameter names (Passed to runMatlabTests.m as name-value pair + // arguments) public static final String PDF_REPORT = "'PDFReport'"; public static final String TAP_RESULTS = "'TAPResults'"; public static final String JUNIT_RESULTS = "'JUnitResults'"; public static final String STM_RESULTS = "'SimulinkTestResults'"; public static final String COBERTURA_CODE_COVERAGE = "'CoberturaCodeCoverage'"; public static final String COBERTURA_MODEL_COVERAGE = "'CoberturaModelCoverage'"; - - //Matlab Script generator package + + // Matlab Script generator package public static final String MATLAB_SCRIPT_GENERATOR = "matlab-script-generator.zip"; - - //Test runner file prefix + + // Test runner file prefix public static final String MATLAB_TEST_RUNNER_FILE_PREFIX = "runner_"; - - //Temporary MATLAB folder name in workspace + + // Temporary MATLAB folder name in workspace public static final String TEMP_MATLAB_FOLDER_NAME = ".matlab"; // MATLAB default function/plugin paths @@ -39,15 +40,15 @@ public class MatlabBuilderConstants { public static final String BUILD_REPORT_PLUGIN = "+ciplugins/+jenkins/BuildReportPlugin.m"; public static final String TASK_RUN_PROGRESS_PLUGIN = "+ciplugins/+jenkins/TaskRunProgressPlugin.m"; public static final String BUILD_ARTIFACT = "buildArtifact"; - + public static final String NEW_LINE = System.getProperty("line.separator"); - //MATLAB Runner Script + // MATLAB Runner Script public static final String TEST_RUNNER_SCRIPT = String.join(NEW_LINE, - "addpath('${TEMP_FOLDER}');", - "testScript = genscript(${PARAMS});", - "disp('Running MATLAB script with content:');", - "disp(testScript.Contents);", - "fprintf('___________________________________\\n\\n');", - "run(testScript);"); + "addpath('${TEMP_FOLDER}');", + "testScript = genscript(${PARAMS});", + "disp('Running MATLAB script with content:');", + "disp(testScript.Contents);", + "fprintf('___________________________________\\n\\n');", + "run(testScript);"); } diff --git a/src/main/java/com/mathworks/ci/MatlabExecutionException.java b/src/main/java/com/mathworks/ci/MatlabExecutionException.java index ca7754bc..a0a0aa3b 100644 --- a/src/main/java/com/mathworks/ci/MatlabExecutionException.java +++ b/src/main/java/com/mathworks/ci/MatlabExecutionException.java @@ -1,8 +1,7 @@ package com.mathworks.ci; /** - * Copyright 2021 The MathWorks, Inc. - * + * Copyright 2021-2024 The MathWorks, Inc. */ import java.lang.Exception; diff --git a/src/main/java/com/mathworks/ci/MatlabInstallation.java b/src/main/java/com/mathworks/ci/MatlabInstallation.java index 298fcf6e..5cace624 100644 --- a/src/main/java/com/mathworks/ci/MatlabInstallation.java +++ b/src/main/java/com/mathworks/ci/MatlabInstallation.java @@ -1,24 +1,29 @@ package com.mathworks.ci; /** - * Copyright 2020 The MathWorks, Inc. + * Copyright 2020-2024 The MathWorks, Inc. * * Describable class for adding MATLAB installations in Jenkins Global Tool configuration. - * */ +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.CopyOnWrite; import hudson.EnvVars; import hudson.Extension; +import hudson.FilePath; import hudson.Util; import hudson.model.EnvironmentSpecific; import hudson.model.Node; import hudson.model.TaskListener; +import hudson.remoting.VirtualChannel; import hudson.slaves.NodeSpecific; import hudson.tools.ToolDescriptor; import hudson.tools.ToolInstallation; import hudson.tools.ToolProperty; +import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import javax.annotation.CheckForNull; @@ -30,7 +35,8 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; -public class MatlabInstallation extends ToolInstallation implements EnvironmentSpecific, NodeSpecific { +public class MatlabInstallation extends ToolInstallation + implements EnvironmentSpecific, NodeSpecific { private static final long serialVersionUID = 1L; @DataBoundConstructor @@ -39,14 +45,15 @@ public MatlabInstallation(String name, @CheckForNull String home, List { @CopyOnWrite private volatile MatlabInstallation[] installations = new MatlabInstallation[0]; diff --git a/src/main/java/com/mathworks/ci/MatlabInstallationAxis.java b/src/main/java/com/mathworks/ci/MatlabInstallationAxis.java index 67c33098..d19fbff7 100644 --- a/src/main/java/com/mathworks/ci/MatlabInstallationAxis.java +++ b/src/main/java/com/mathworks/ci/MatlabInstallationAxis.java @@ -1,11 +1,10 @@ package com.mathworks.ci; /** - * Copyright 2020 The MathWorks, Inc. + * Copyright 2020-2024 The MathWorks, Inc. * * Describable class for MATLAB Axis that provides a list of configured MATLAB installation for * generating matrix configurations. - * */ import hudson.Extension; @@ -34,7 +33,7 @@ static private List evaluateValues(List values) { } @Extension - public static class DescriptorImpl extends AxisDescriptor{ + public static class DescriptorImpl extends AxisDescriptor { @Override public String getDisplayName() { @@ -47,10 +46,11 @@ public boolean isInstantiable() { } public boolean checkUseMatlabVersion(Object it) { - return MatlabItemListener.getMatlabBuildWrapperCheckForPrj(((MatrixProject) it).getFullName()) && !isMatlabInstallationEmpty(); + return MatlabItemListener.getMatlabBuildWrapperCheckForPrj(((MatrixProject) it).getFullName()) + && !isMatlabInstallationEmpty(); } - public MatlabInstallation[] getInstallations () { + public MatlabInstallation[] getInstallations() { return MatlabInstallation.getAll(); } diff --git a/src/main/java/com/mathworks/ci/MatlabItemListener.java b/src/main/java/com/mathworks/ci/MatlabItemListener.java index 442d8e15..ea2d3bb5 100644 --- a/src/main/java/com/mathworks/ci/MatlabItemListener.java +++ b/src/main/java/com/mathworks/ci/MatlabItemListener.java @@ -1,11 +1,10 @@ package com.mathworks.ci; /** - * Copyright 2020 The MathWorks, Inc. + * Copyright 2020-2024 The MathWorks, Inc. * * Item listener class to provide functionality to check UI element states for a * Multi-configuration project. - * */ import hudson.Extension; @@ -27,28 +26,27 @@ public final class MatlabItemListener extends ItemListener { private static final Map prjCheckMatlabBuildWrapper = new HashMap<>(); @Override - public void onLoaded(){ + public void onLoaded() { checkItems(Jenkins.get().getItems()); } @Override public void onUpdated(Item item) { - if(!(item instanceof MatrixProject)){ + if (!(item instanceof MatrixProject)) { return; } checkSingleItem(item); } - private void checkItems(List items) { - for(TopLevelItem item : items){ - if(item instanceof MatrixProject){ + for (TopLevelItem item : items) { + if (item instanceof MatrixProject) { check((MatrixProject) item); } } } - private void checkSingleItem(Item item){ + private void checkSingleItem(Item item) { check((MatrixProject) item); } @@ -60,7 +58,7 @@ private void check(MatrixProject prj) { private void checkForAxis(MatrixProject prj) { boolean checkForAxis = false; Collection configurations = prj.getActiveConfigurations(); - for(MatrixConfiguration conf : configurations){ + for (MatrixConfiguration conf : configurations) { String matlabAxisValue = conf.getCombination().get(Message.getValue("Axis.matlab.key")); if (matlabAxisValue != null) { checkForAxis = true; @@ -72,8 +70,8 @@ private void checkForAxis(MatrixProject prj) { private void checkForBuildWrapper(MatrixProject prj) { boolean checkForBuildWrapper = false; - for(Object bWrapper : prj.getBuildWrappersList().toArray()) { - if(bWrapper instanceof UseMatlabVersionBuildWrapper){ + for (Object bWrapper : prj.getBuildWrappersList().toArray()) { + if (bWrapper instanceof UseMatlabVersionBuildWrapper) { checkForBuildWrapper = ((UseMatlabVersionBuildWrapper) bWrapper).getMatlabInstallationName() != null; break; } diff --git a/src/main/java/com/mathworks/ci/MatlabNotFoundError.java b/src/main/java/com/mathworks/ci/MatlabNotFoundError.java index a495f918..f69221bb 100644 --- a/src/main/java/com/mathworks/ci/MatlabNotFoundError.java +++ b/src/main/java/com/mathworks/ci/MatlabNotFoundError.java @@ -1,15 +1,14 @@ package com.mathworks.ci; /** - * Copyright 2020 The MathWorks, Inc. - * + * Copyright 2020-2024 The MathWorks, Inc. */ public class MatlabNotFoundError extends Error { private static final long serialVersionUID = 7918595075502022644L; - MatlabNotFoundError(String errorMessage){ + MatlabNotFoundError(String errorMessage) { super(errorMessage); } diff --git a/src/main/java/com/mathworks/ci/MatlabReleaseInfo.java b/src/main/java/com/mathworks/ci/MatlabReleaseInfo.java index 641a9958..0636ce66 100644 --- a/src/main/java/com/mathworks/ci/MatlabReleaseInfo.java +++ b/src/main/java/com/mathworks/ci/MatlabReleaseInfo.java @@ -1,8 +1,10 @@ package com.mathworks.ci; /* - * Copyright 2019 The MathWorks, Inc. This Class provides MATLAB release information in the form of - * Version numbers. Class constructor requires MATLAB root as input parameter + * Copyright 2019-2024 The MathWorks, Inc. + * + * This Class provides MATLAB release information in the form of Version numbers. Class constructor + * requires MATLAB root as input parameter. */ import java.io.InputStream; @@ -36,9 +38,9 @@ public class MatlabReleaseInfo { private static final String VERSION_TAG = "version"; private static final String DESCRIPTION_TAG = "description"; private static final String DATE_TAG = "date"; - + private Map versionInfoCache = new HashMap(); - + public MatlabReleaseInfo(FilePath matlabRoot) { this.matlabRoot = matlabRoot; } @@ -71,19 +73,20 @@ public boolean verLessThan(double version) throws MatlabVersionNotFoundException return false; } } - - @SuppressFBWarnings(value = {"REC_CATCH_EXCEPTION", "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"}, - justification = "REC_CATCH_EXCEPTION: Irrespective of exception type, intention is to handle it in same way." + + + @SuppressFBWarnings(value = { "REC_CATCH_EXCEPTION", + "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE" }, justification = "REC_CATCH_EXCEPTION: Irrespective of exception type, intention is to handle it in same way." + + " Also, there is no intention to propagate any runtime exception up in the hierarchy." + "RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE: This is a false positive reported by spotbugs for JDK 11 for try-with-resources block.") private Map getVersionInfoFromFile() throws MatlabVersionNotFoundException { if (MapUtils.isEmpty(versionInfoCache)) { try { FilePath versionFile = new FilePath(this.matlabRoot, VERSION_INFO_FILE); - if(versionFile.exists()) { + if (versionFile.exists()) { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); String FEATURE = null; - try{ + try { FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; dbFactory.setFeature(FEATURE, true); dbFactory.setXIncludeAware(false); @@ -93,7 +96,7 @@ private Map getVersionInfoFromFile() throws MatlabVersionNotFoun } DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(versionFile.read()); - + doc.getDocumentElement().normalize(); NodeList nList = doc.getElementsByTagName(VERSION_INFO_ROOT_TAG); @@ -113,35 +116,34 @@ private Map getVersionInfoFromFile() throws MatlabVersionNotFoun eElement.getElementsByTagName(DATE_TAG).item(0).getTextContent()); } } - } - else if(!this.matlabRoot.exists()){ + } else if (!this.matlabRoot.exists()) { throw new NotDirectoryException("Invalid matlabroot path"); - }else { - // Get the version information from Contents.m file when VersionInfo.xml is not - // present. - FilePath contentFile = new FilePath(this.matlabRoot, CONTENTS_FILE); - String actualVersion = null; - try (InputStream in = contentFile.read(); - BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { - - // Skip first line and capture the second line. - br.readLine(); - String versionLine = br.readLine(); - - Pattern p = Pattern.compile(VERSION_PATTERN); - Matcher m = p.matcher(versionLine); - if (m.find()) { - actualVersion = m.group(); - } - } - // Update the versionInfoCache with actual version extracted from Contents.m - versionInfoCache.put(VERSION_TAG, actualVersion); - } + } else { + // Get the version information from Contents.m file when VersionInfo.xml is not + // present. + FilePath contentFile = new FilePath(this.matlabRoot, CONTENTS_FILE); + String actualVersion = null; + try (InputStream in = contentFile.read(); + BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { + + // Skip first line and capture the second line. + br.readLine(); + String versionLine = br.readLine(); + + Pattern p = Pattern.compile(VERSION_PATTERN); + Matcher m = p.matcher(versionLine); + if (m.find()) { + actualVersion = m.group(); + } + } + // Update the versionInfoCache with actual version extracted from Contents.m + versionInfoCache.put(VERSION_TAG, actualVersion); + } } catch (Exception e) { throw new MatlabVersionNotFoundException( Message.getValue("Releaseinfo.matlab.version.not.found.error"), e); - } + } } return versionInfoCache; } - } \ No newline at end of file +} diff --git a/src/main/java/com/mathworks/ci/MatlabVersionNotFoundException.java b/src/main/java/com/mathworks/ci/MatlabVersionNotFoundException.java index 74232867..fe790f69 100644 --- a/src/main/java/com/mathworks/ci/MatlabVersionNotFoundException.java +++ b/src/main/java/com/mathworks/ci/MatlabVersionNotFoundException.java @@ -1,9 +1,10 @@ package com.mathworks.ci; /* - * Copyright 2018 The MathWorks, Inc. This Exception class provides a business exception for all - * Classes/methods which tries to get version information of MATLAB. - * + * Copyright 2018-2024 The MathWorks, Inc. + * + * This Exception class provides a business exception for all Classes/methods which tries to get + * version information of MATLAB. */ public class MatlabVersionNotFoundException extends Exception { diff --git a/src/main/java/com/mathworks/ci/MatrixPatternResolver.java b/src/main/java/com/mathworks/ci/MatrixPatternResolver.java index 77611061..71dfde68 100644 --- a/src/main/java/com/mathworks/ci/MatrixPatternResolver.java +++ b/src/main/java/com/mathworks/ci/MatrixPatternResolver.java @@ -1,9 +1,10 @@ package com.mathworks.ci; /* - * Copyright 2019 The MathWorks, Inc. + * Copyright 2019-2024 The MathWorks, Inc. * - * This is Matrix pattern resolver class which is a utility for identifying variables. Either $xyz, ${xyz} or ${a.b} but not $a.b, while ignoring "$$" + * This is Matrix pattern resolver class which is a utility for identifying variables. Either $xyz, + * ${xyz} or ${a.b} but not $a.b, while ignoring "$$" */ import java.util.regex.Matcher; @@ -12,15 +13,15 @@ public class MatrixPatternResolver { private String inputString; private static Pattern VARIBLE = Pattern.compile("\\$([A-Za-z0-9_]+|\\{[A-Za-z0-9_.]+\\}|\\$)"); - + public MatrixPatternResolver(String inputString) { this.inputString = inputString; } - + public String getInputString() { return this.inputString; } - + public boolean hasVariablePattern() { Matcher m = VARIBLE.matcher(getInputString()); return m.find(0); diff --git a/src/main/java/com/mathworks/ci/Message.java b/src/main/java/com/mathworks/ci/Message.java index 52e4c3e5..3159fe4f 100644 --- a/src/main/java/com/mathworks/ci/Message.java +++ b/src/main/java/com/mathworks/ci/Message.java @@ -1,10 +1,9 @@ package com.mathworks.ci; -/* Copyright 2018 The MathWorks, Inc. +/* Copyright 2018-2024 The MathWorks, Inc. * * This Class is wrapper to access the static configuration values across project. Acts as * Utility class to access key & value pairs from config.properties - * */ import java.util.ResourceBundle; @@ -14,22 +13,17 @@ public class Message { private static String MATLAB_BUILDER_DISPLAY_NAME = "Builder.display.name"; private static String CONFIG_FILE = "config"; - private static ResourceBundle rb = ResourceBundle.getBundle(CONFIG_FILE); - + private static ResourceBundle rb = ResourceBundle.getBundle(CONFIG_FILE); - public static String getBuilderDisplayName(){ + public static String getBuilderDisplayName() { return rb.getString(MATLAB_BUILDER_DISPLAY_NAME); - } - public static String getValue(String key){ + public static String getValue(String key) { return rb.getString(key); } - - - } diff --git a/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java b/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java index eb8f0399..12178b3c 100644 --- a/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java +++ b/src/main/java/com/mathworks/ci/UseMatlabVersionBuildWrapper.java @@ -1,11 +1,10 @@ package com.mathworks.ci; /** - * Copyright 2019-2020 The MathWorks, Inc. + * Copyright 2019-2024 The MathWorks, Inc. * * This class is BuildWrapper which accepts the "matlabroot" from user and updates the PATH varible with it. * which could be later used across build. - * */ import hudson.model.Item; @@ -42,7 +41,8 @@ public class UseMatlabVersionBuildWrapper extends SimpleBuildWrapper { private String matlabInstallationName; @DataBoundConstructor - public UseMatlabVersionBuildWrapper() {} + public UseMatlabVersionBuildWrapper() { + } public String getMatlabRootFolder() { return this.matlabRootFolder; @@ -51,22 +51,23 @@ public String getMatlabRootFolder() { public String getMatlabInstallationHome(Computer cmp, TaskListener listener, EnvVars env) throws IOException, InterruptedException { return Utilities.getNodeSpecificHome(this.matlabInstallationName, - cmp.getNode(), listener, env); + cmp.getNode(), listener, env).getRemote(); } public String getMatlabInstallationName() { - /* For backward compatibility assign installation name to custom + /* + * For backward compatibility assign installation name to custom * if matlabRootFolder is not null. - * */ - if(this.matlabRootFolder!=null && !this.matlabRootFolder.isEmpty()){ + */ + if (this.matlabRootFolder != null && !this.matlabRootFolder.isEmpty()) { this.matlabInstallationName = Message.getValue("matlab.custom.location"); } return matlabInstallationName; } @DataBoundSetter - public void setMatlabBuildWrapperContent(MatlabBuildWrapperContent matlabBuildWrapperContent){ - if (matlabBuildWrapperContent != null){ + public void setMatlabBuildWrapperContent(MatlabBuildWrapperContent matlabBuildWrapperContent) { + if (matlabBuildWrapperContent != null) { this.matlabInstallationName = matlabBuildWrapperContent.getMatlabInstallationName(); this.matlabRootFolder = matlabBuildWrapperContent.getMatlabRootFolder(); } @@ -76,7 +77,7 @@ private String getNodeSpecificMatlab(Computer cmp, TaskListener listener) throws IOException, InterruptedException { String matlabroot = getMatlabRootFolder(); // If matlabroot is null use matlab installation path - if (matlabroot == null || matlabroot.isEmpty()){ + if (matlabroot == null || matlabroot.isEmpty()) { matlabroot = getMatlabInstallationHome(cmp, listener, this.env); } @@ -136,22 +137,24 @@ public String getMatlabAxisWarning() { } /* - * Below methods with 'doCheck' prefix gets called by jenkins when this builder is loaded. - * these methods are used to perform basic validation on UI elements associated with this + * Below methods with 'doCheck' prefix gets called by jenkins when this builder + * is loaded. + * these methods are used to perform basic validation on UI elements associated + * with this * descriptor class. */ @POST - public FormValidation doCheckMatlabRootFolder(@QueryParameter String matlabRootFolder, @AncestorInPath Item item) { + public FormValidation doCheckMatlabRootFolder(@QueryParameter String matlabRootFolder, + @AncestorInPath Item item) { if (item == null) { return FormValidation.ok(); } item.checkPermission(Item.CONFIGURE); - List> listOfCheckMethods = - new ArrayList>(); + List> listOfCheckMethods = new ArrayList>(); listOfCheckMethods.add(chkMatlabEmpty); listOfCheckMethods.add(chkMatlabSupportsRunTests); - return FormValidationUtil.getFirstErrorOrWarning(listOfCheckMethods,matlabRootFolder); + return FormValidationUtil.getFirstErrorOrWarning(listOfCheckMethods, matlabRootFolder); } Function chkMatlabEmpty = (String matlabRootFolder) -> { @@ -188,21 +191,45 @@ public void setUp(Context context, Run build, FilePath workspace, Launcher // Set Environment variable setEnv(initialEnvironment); - FilePath matlabExecutablePath = new FilePath(launcher.getChannel(), - getNodeSpecificMatlab(Computer.currentComputer(), listener) + getNodeSpecificExecutable(launcher)); - + String nodeSpecificMatlab = getNodeSpecificMatlab(Computer.currentComputer(), listener) + + getNodeSpecificExecutable(launcher); + FilePath matlabExecutablePath = new FilePath(launcher.getChannel(), nodeSpecificMatlab); if (!matlabExecutablePath.exists()) { throw new MatlabNotFoundError(Message.getValue("matlab.not.found.error")); } - // Add "matlabroot" without bin as env variable which will be available across the build. - context.env("matlabroot", getNodeSpecificMatlab(Computer.currentComputer(), listener)); + // Add matlab-batch executable in path + FilePath batchExecutable = getNthParentFilePath(matlabExecutablePath, 3); + if (batchExecutable != null && batchExecutable.exists()) { + context.env("PATH+matlab_batch", batchExecutable.getRemote()); + } + + // Add "matlabroot" without bin as env variable which will be available across + // the build. + context.env("matlabroot", nodeSpecificMatlab); // Add matlab bin to path to invoke MATLAB directly on command line. context.env("PATH+matlabroot", matlabExecutablePath.getParent().getRemote()); - // Specify which MATLAB was added to path. - listener.getLogger().println("\n" + String.format(Message.getValue("matlab.added.to.path.from"), matlabExecutablePath.getParent().getRemote()) + "\n"); + ; + listener.getLogger().println("\n" + String.format(Message.getValue("matlab.added.to.path.from"), + matlabExecutablePath.getParent().getRemote()) + "\n"); } private String getNodeSpecificExecutable(Launcher launcher) { return (launcher.isUnix()) ? "/bin/matlab" : "\\bin\\matlab.exe"; } + + public static FilePath getNthParentFilePath(FilePath path, int levels) { + if (path == null || levels < 0) { + return null; + } + + FilePath currentPath = path; + for (int i = 0; i < levels; i++) { + if (currentPath == null) { + return null; + } + currentPath = currentPath.getParent(); + } + return currentPath; + } + } diff --git a/src/main/java/com/mathworks/ci/Utilities.java b/src/main/java/com/mathworks/ci/Utilities.java index 900e3565..999649f0 100644 --- a/src/main/java/com/mathworks/ci/Utilities.java +++ b/src/main/java/com/mathworks/ci/Utilities.java @@ -4,7 +4,6 @@ * Copyright 2020-2024 The MathWorks, Inc. * * Utility class for common methods. - * */ import hudson.EnvVars; @@ -21,7 +20,7 @@ public class Utilities { - public static String getCellArrayFromList(List listOfStr){ + public static String getCellArrayFromList(List listOfStr) { // Ignore empty string values in the list Predicate isEmpty = String::isEmpty; Predicate isNotEmpty = isEmpty.negate(); @@ -37,24 +36,32 @@ public static void addMatlabToEnvPathFromAxis(Computer cmp, TaskListener listene String name = env.get(Message.getValue("Axis.matlab.key")); // If no MATLAB axis is set or if 'Use MATLAB version' is selected, return - if (name == null || name.isEmpty() || env.get("matlabroot") != null){ + if (name == null || name.isEmpty() || env.get("matlabroot") != null) { return; } + FilePath matlabRoot = getNodeSpecificHome(name, + cmp.getNode(), listener, env); + + if (matlabRoot != null && matlabRoot.getParent().exists()) { + env.put("PATH+matlab_batch", matlabRoot.getParent().getRemote()); + } + String matlabExecutablePath = getNodeSpecificHome(name, - cmp.getNode(), listener, env) + ((Boolean.TRUE.equals(cmp.isUnix()))?"/bin" : "\\bin"); + cmp.getNode(), listener, env).getRemote() + ((Boolean.TRUE.equals(cmp.isUnix())) ? "/bin" : "\\bin"); env.put("PATH+matlabroot", matlabExecutablePath); // Specify which MATLAB was added to path. - listener.getLogger().println("\n" + String.format(Message.getValue("matlab.added.to.path.from"), matlabExecutablePath) + "\n"); + listener.getLogger().println( + "\n" + String.format(Message.getValue("matlab.added.to.path.from"), matlabExecutablePath) + "\n"); } - public static String getNodeSpecificHome(String instName,Node node, TaskListener listener, EnvVars env) + public static FilePath getNodeSpecificHome(String instName, Node node, TaskListener listener, EnvVars env) throws IOException, InterruptedException { MatlabInstallation inst = MatlabInstallation.getInstallation(instName); if (inst == null || node == null) { // Following will error out in BuildWrapper - return ""; + throw new MatlabNotFoundError("MATLAB installations could not be found"); } // get installation for node and environment. @@ -63,9 +70,10 @@ public static String getNodeSpecificHome(String instName,Node node, TaskListener FilePath matlabExecutablePath = node.createPath(inst.getHome()); // If no MATLAB version is configured for current node, throw error. if (matlabExecutablePath == null || !matlabExecutablePath.exists()) { - throw new MatlabNotFoundError(String.format(Message.getValue("matlab.not.found.error.for.node"), instName, Objects - .requireNonNull(node).getDisplayName())); + throw new MatlabNotFoundError( + String.format(Message.getValue("matlab.not.found.error.for.node"), instName, Objects + .requireNonNull(node).getDisplayName())); } - return matlabExecutablePath.getRemote(); + return matlabExecutablePath; } } diff --git a/src/main/java/com/mathworks/ci/actions/MatlabAction.java b/src/main/java/com/mathworks/ci/actions/MatlabAction.java index df93b8d0..879817ae 100644 --- a/src/main/java/com/mathworks/ci/actions/MatlabAction.java +++ b/src/main/java/com/mathworks/ci/actions/MatlabAction.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import com.mathworks.ci.BuildArtifactAction; @@ -21,7 +20,7 @@ public class MatlabAction { BuildConsoleAnnotator annotator; String actionID; - public String getActionID(){ + public String getActionID() { return (this.actionID == null) ? "" : this.actionID; } @@ -38,8 +37,10 @@ public MatlabAction(MatlabCommandRunner runner, BuildConsoleAnnotator annotator) public void copyBuildPluginsToTemp() throws IOException, InterruptedException { // Copy plugins and override default plugins function runner.copyFileToTempFolder(MatlabBuilderConstants.DEFAULT_PLUGIN, MatlabBuilderConstants.DEFAULT_PLUGIN); - runner.copyFileToTempFolder(MatlabBuilderConstants.BUILD_REPORT_PLUGIN, MatlabBuilderConstants.BUILD_REPORT_PLUGIN); - runner.copyFileToTempFolder(MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN, MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN); + runner.copyFileToTempFolder(MatlabBuilderConstants.BUILD_REPORT_PLUGIN, + MatlabBuilderConstants.BUILD_REPORT_PLUGIN); + runner.copyFileToTempFolder(MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN, + MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN); } public void setBuildEnvVars() throws IOException, InterruptedException { @@ -47,7 +48,7 @@ public void setBuildEnvVars() throws IOException, InterruptedException { runner.addEnvironmentVariable( "MW_MATLAB_BUILDTOOL_DEFAULT_PLUGINS_FCN_OVERRIDE", "ciplugins.jenkins.getDefaultPlugins"); - runner.addEnvironmentVariable("MW_BUILD_PLUGIN_ACTION_ID",this.getActionID()); + runner.addEnvironmentVariable("MW_BUILD_PLUGIN_ACTION_ID", this.getActionID()); runner.addEnvironmentVariable( "MW_MATLAB_TEMP_FOLDER", runner.getTempFolder().toString()); @@ -55,7 +56,7 @@ public void setBuildEnvVars() throws IOException, InterruptedException { public void teardownAction(Run build) { // Handle build result - if(this.annotator != null) { + if (this.annotator != null) { moveJsonArtifactToBuildRoot(build, MatlabBuilderConstants.BUILD_ARTIFACT); } @@ -66,15 +67,14 @@ public void teardownAction(Run build) { } } - private void moveJsonArtifactToBuildRoot(Run build, String artifactBaseName) { + private void moveJsonArtifactToBuildRoot(Run build, String artifactBaseName) { try { FilePath file = new FilePath(this.runner.getTempFolder(), artifactBaseName + ".json"); if (file.exists()) { FilePath rootLocation = new FilePath( new File( build.getRootDir().getAbsolutePath(), - artifactBaseName + this.getActionID() + ".json") - ); + artifactBaseName + this.getActionID() + ".json")); file.copyTo(rootLocation); file.delete(); build.addAction(new BuildArtifactAction(build, this.getActionID())); diff --git a/src/main/java/com/mathworks/ci/actions/MatlabActionFactory.java b/src/main/java/com/mathworks/ci/actions/MatlabActionFactory.java index d5892789..f020b7dd 100644 --- a/src/main/java/com/mathworks/ci/actions/MatlabActionFactory.java +++ b/src/main/java/com/mathworks/ci/actions/MatlabActionFactory.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.Serializable; @@ -10,7 +9,8 @@ import com.mathworks.ci.parameters.*; public class MatlabActionFactory implements Serializable { - public RunMatlabCommandAction createAction(CommandActionParameters params) throws IOException, InterruptedException { + public RunMatlabCommandAction createAction(CommandActionParameters params) + throws IOException, InterruptedException { return new RunMatlabCommandAction(params); } @@ -18,7 +18,7 @@ public RunMatlabBuildAction createAction(BuildActionParameters params) throws IO return new RunMatlabBuildAction(params); } - public RunMatlabTestsAction createAction(TestActionParameters params) throws IOException, InterruptedException { + public RunMatlabTestsAction createAction(TestActionParameters params) throws IOException, InterruptedException { return new RunMatlabTestsAction(params); } } diff --git a/src/main/java/com/mathworks/ci/actions/RunMatlabBuildAction.java b/src/main/java/com/mathworks/ci/actions/RunMatlabBuildAction.java index c4e48ef6..9083e39d 100644 --- a/src/main/java/com/mathworks/ci/actions/RunMatlabBuildAction.java +++ b/src/main/java/com/mathworks/ci/actions/RunMatlabBuildAction.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -17,16 +16,17 @@ public class RunMatlabBuildAction extends MatlabAction { private BuildActionParameters params; - public RunMatlabBuildAction(MatlabCommandRunner runner, BuildConsoleAnnotator annotator, BuildActionParameters params) { + public RunMatlabBuildAction(MatlabCommandRunner runner, BuildConsoleAnnotator annotator, + BuildActionParameters params) { super(runner, annotator); this.params = params; } public RunMatlabBuildAction(BuildActionParameters params) throws IOException, InterruptedException { - this(new MatlabCommandRunner(params), + this(new MatlabCommandRunner(params), new BuildConsoleAnnotator( - params.getTaskListener().getLogger(), - params.getBuild().getCharset()), + params.getTaskListener().getLogger(), + params.getBuild().getCharset()), params); } @@ -39,10 +39,10 @@ public void run() throws IOException, InterruptedException, MatlabExecutionExcep // Prepare the build tool command // TODO: Devise better solution then prepending the command - // here. - String command = "addpath('" - + runner.getTempFolder().getRemote() - + "'); buildtool"; + // here. + String command = "addpath('" + + runner.getTempFolder().getRemote() + + "'); buildtool"; if (params.getTasks() != null) { command += " " + params.getTasks(); @@ -56,8 +56,8 @@ public void run() throws IOException, InterruptedException, MatlabExecutionExcep runner.runMatlabCommand(command); } catch (Exception e) { this.params.getTaskListener().getLogger() - .println(e.getMessage()); - throw(e); + .println(e.getMessage()); + throw (e); } finally { annotator.forceEol(); @@ -65,4 +65,4 @@ public void run() throws IOException, InterruptedException, MatlabExecutionExcep super.teardownAction(build); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/mathworks/ci/actions/RunMatlabCommandAction.java b/src/main/java/com/mathworks/ci/actions/RunMatlabCommandAction.java index 72e942f8..3a59669a 100644 --- a/src/main/java/com/mathworks/ci/actions/RunMatlabCommandAction.java +++ b/src/main/java/com/mathworks/ci/actions/RunMatlabCommandAction.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -17,16 +16,17 @@ public class RunMatlabCommandAction extends MatlabAction { private CommandActionParameters params; - public RunMatlabCommandAction(MatlabCommandRunner runner, BuildConsoleAnnotator annotator, CommandActionParameters params) { + public RunMatlabCommandAction(MatlabCommandRunner runner, BuildConsoleAnnotator annotator, + CommandActionParameters params) { super(runner, annotator); this.params = params; } public RunMatlabCommandAction(CommandActionParameters params) throws IOException, InterruptedException { - this(new MatlabCommandRunner(params), + this(new MatlabCommandRunner(params), new BuildConsoleAnnotator( - params.getTaskListener().getLogger(), - params.getBuild().getCharset()), + params.getTaskListener().getLogger(), + params.getBuild().getCharset()), params); } @@ -38,16 +38,16 @@ public void run() throws IOException, InterruptedException, MatlabExecutionExcep runner.redirectStdOut(annotator); // Prepare MATLAB command - String command = "addpath('" - + runner.getTempFolder().getRemote() - + "'); " + this.params.getCommand(); + String command = "addpath('" + + runner.getTempFolder().getRemote() + + "'); " + this.params.getCommand(); try { runner.runMatlabCommand(command); } catch (Exception e) { this.params.getTaskListener().getLogger() - .println(e.getMessage()); - throw(e); + .println(e.getMessage()); + throw (e); } finally { annotator.forceEol(); diff --git a/src/main/java/com/mathworks/ci/actions/RunMatlabTestsAction.java b/src/main/java/com/mathworks/ci/actions/RunMatlabTestsAction.java index 0156bbb4..6482fdfe 100644 --- a/src/main/java/com/mathworks/ci/actions/RunMatlabTestsAction.java +++ b/src/main/java/com/mathworks/ci/actions/RunMatlabTestsAction.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -41,19 +40,19 @@ public void run() throws IOException, InterruptedException, MatlabExecutionExcep String command = MatlabBuilderConstants.TEST_RUNNER_SCRIPT; command = command.replace("${TEMP_FOLDER}", runner.getTempFolder().getRemote()); command = command.replace("${PARAMS}", getParameterString()); - + // Run the command try { runner.runMatlabCommand(command); } catch (Exception e) { this.params.getTaskListener() - .getLogger() - .println(e.getMessage()); - throw(e); + .getLogger() + .println(e.getMessage()); + throw (e); } finally { Run build = this.params.getBuild(); super.teardownAction(build); - } + } } private String singleQuotify(String in) { @@ -72,15 +71,15 @@ private String getParameterString() { String sourceFolders = null; if (this.params.getSourceFolder() != null) { sourceFolders = this.params.getSourceFolder().size() == 0 - ? null - : Utilities.getCellArrayFromList(this.params.getSourceFolder()); + ? null + : Utilities.getCellArrayFromList(this.params.getSourceFolder()); } String selectFolders = null; if (this.params.getSelectByFolder() != null) { selectFolders = this.params.getSelectByFolder().size() == 0 - ? null - : Utilities.getCellArrayFromList(this.params.getSelectByFolder()); + ? null + : Utilities.getCellArrayFromList(this.params.getSelectByFolder()); } // All string-based fields @@ -99,7 +98,7 @@ private String getParameterString() { "'SourceFolder'", "'SelectByFolder'" }; - final String[] values = { + final String[] values = { this.params.getTestResultsPDF(), this.params.getTestResultsTAP(), this.params.getTestResultsJUnit(), @@ -119,12 +118,12 @@ private String getParameterString() { if (values[i] != null && !values[i].equals("false")) { inputArgsList.add(names[i]); String arg = values[i].equals("true") || values[i].startsWith("{") - ? values[i] - : singleQuotify(values[i]); + ? values[i] + : singleQuotify(values[i]); inputArgsList.add(arg); } } - + return String.join(",", inputArgsList); } } diff --git a/src/main/java/com/mathworks/ci/freestyle/RunMatlabBuildBuilder.java b/src/main/java/com/mathworks/ci/freestyle/RunMatlabBuildBuilder.java index 89465b89..9b74f813 100644 --- a/src/main/java/com/mathworks/ci/freestyle/RunMatlabBuildBuilder.java +++ b/src/main/java/com/mathworks/ci/freestyle/RunMatlabBuildBuilder.java @@ -2,7 +2,6 @@ /** * Copyright 2022-2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -78,8 +77,8 @@ public StartupOptions getStartupOptions() { public String getStartupOptionsAsString() { return this.startupOptions == null - ? "" - : this.startupOptions.getOptions(); + ? "" + : this.startupOptions.getOptions(); } public BuildOptions getBuildOptions() { @@ -88,10 +87,10 @@ public BuildOptions getBuildOptions() { public String getBuildOptionsAsString() { return this.buildOptions == null - ? null - : this.buildOptions.getOptions(); + ? null + : this.buildOptions.getOptions(); } - + @Extension public static class RunMatlabBuildDescriptor extends BuildStepDescriptor { @@ -113,11 +112,13 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc } /* - * This is to identify which project type in jenkins this should be applicable.(non-Javadoc) + * This is to identify which project type in jenkins this should be + * applicable.(non-Javadoc) * * @see hudson.tasks.BuildStepDescriptor#isApplicable(java.lang.Class) * - * if it returns true then this build step will be applicable for all project type. + * if it returns true then this build step will be applicable for all project + * type. */ @Override public boolean isApplicable( @@ -149,7 +150,7 @@ public void perform(@Nonnull Run build, @Nonnull FilePath workspace, } // Added for backwards compatibility: - // Called when object is loaded from persistent data. + // Called when object is loaded from persistent data. protected Object readResolve() { if (factory == null) { factory = new MatlabActionFactory(); diff --git a/src/main/java/com/mathworks/ci/freestyle/RunMatlabCommandBuilder.java b/src/main/java/com/mathworks/ci/freestyle/RunMatlabCommandBuilder.java index c97cb6f3..3a0c6346 100644 --- a/src/main/java/com/mathworks/ci/freestyle/RunMatlabCommandBuilder.java +++ b/src/main/java/com/mathworks/ci/freestyle/RunMatlabCommandBuilder.java @@ -4,7 +4,6 @@ * Copyright 2019-2024 The MathWorks, Inc. * * Script builder used to run custom MATLAB commands or scripts. - * */ import hudson.util.FormValidation; @@ -78,16 +77,17 @@ public StartupOptions getStartupOptions() { public String getStartupOptionsAsString() { return this.startupOptions == null - ? "" - : this.startupOptions.getOptions(); + ? "" + : this.startupOptions.getOptions(); } - + @Extension public static class RunMatlabCommandDescriptor extends BuildStepDescriptor { @Initializer(before = InitMilestone.PLUGINS_STARTED) public static void addAliases() { - Items.XSTREAM2.addCompatibilityAlias("com.mathworks.ci.RunMatlabCommandBuilder", RunMatlabCommandBuilder.class); + Items.XSTREAM2.addCompatibilityAlias("com.mathworks.ci.RunMatlabCommandBuilder", + RunMatlabCommandBuilder.class); } // Overridden Method used to show the text under build dropdown @@ -103,11 +103,13 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc } /* - * This is to identify which project type in jenkins this should be applicable.(non-Javadoc) + * This is to identify which project type in jenkins this should be + * applicable.(non-Javadoc) * * @see hudson.tasks.BuildStepDescriptor#isApplicable(java.lang.Class) * - * if it returns true then this build step will be applicable for all project type. + * if it returns true then this build step will be applicable for all project + * type. */ @Override public boolean isApplicable( @@ -134,8 +136,8 @@ public void perform(@Nonnull Run build, @Nonnull FilePath workspace, final EnvVars env = build.getEnvironment(listener); CommandActionParameters params = new CommandActionParameters( - build, workspace, env, - launcher, listener, + build, workspace, env, + launcher, listener, getStartupOptionsAsString(), getMatlabCommand()); RunMatlabCommandAction action = factory.createAction(params); @@ -148,7 +150,7 @@ public void perform(@Nonnull Run build, @Nonnull FilePath workspace, } // Added for backwards compatibility: - // Called when object is loaded from persistent data. + // Called when object is loaded from persistent data. protected Object readResolve() { if (factory == null) { factory = new MatlabActionFactory(); diff --git a/src/main/java/com/mathworks/ci/freestyle/RunMatlabTestsBuilder.java b/src/main/java/com/mathworks/ci/freestyle/RunMatlabTestsBuilder.java index 4868d83a..5b4096e3 100644 --- a/src/main/java/com/mathworks/ci/freestyle/RunMatlabTestsBuilder.java +++ b/src/main/java/com/mathworks/ci/freestyle/RunMatlabTestsBuilder.java @@ -5,7 +5,6 @@ * * MATLAB test run builder used to run all MATLAB & Simulink tests automatically and generate * selected test artifacts. - * */ import java.io.IOException; @@ -44,7 +43,6 @@ public class RunMatlabTestsBuilder extends Builder implements SimpleBuildStep { - // Make all old values transient which protects them writing back on disk. private transient int buildResult; private transient boolean tapChkBx; @@ -53,14 +51,14 @@ public class RunMatlabTestsBuilder extends Builder implements SimpleBuildStep { private transient boolean stmResultsChkBx; private transient boolean modelCoverageChkBx; private transient boolean pdfReportChkBx; - + private Artifact tapArtifact = new NullArtifact(); private Artifact junitArtifact = new NullArtifact(); private Artifact coberturaArtifact = new NullArtifact(); private Artifact stmResultsArtifact = new NullArtifact(); private Artifact modelCoverageArtifact = new NullArtifact(); private Artifact pdfReportArtifact = new NullArtifact(); - + private SourceFolder sourceFolder; private SelectByFolder selectByFolder; private SelectByTag selectByTag; @@ -80,57 +78,57 @@ public RunMatlabTestsBuilder(MatlabActionFactory factory) { public RunMatlabTestsBuilder() { this(new MatlabActionFactory()); } - + // Getter and Setters to access local members @DataBoundSetter public void setTapArtifact(TapArtifact tapArtifact) { this.tapArtifact = tapArtifact; - } - + } + @DataBoundSetter public void setJunitArtifact(JunitArtifact junitArtifact) { this.junitArtifact = junitArtifact; } - + @DataBoundSetter public void setCoberturaArtifact(CoberturaArtifact coberturaArtifact) { this.coberturaArtifact = coberturaArtifact; } - + @DataBoundSetter public void setStmResultsArtifact(StmResultsArtifact stmResultsArtifact) { this.stmResultsArtifact = stmResultsArtifact; } - + @DataBoundSetter public void setModelCoverageArtifact(ModelCovArtifact modelCoverageArtifact) { this.modelCoverageArtifact = modelCoverageArtifact; - } + } @DataBoundSetter public void setPdfReportArtifact(PdfArtifact pdfReportArtifact) { this.pdfReportArtifact = pdfReportArtifact; } - + @DataBoundSetter public void setSelectByTag(SelectByTag selectByTag) { this.selectByTag = selectByTag; } - + @DataBoundSetter public void setSourceFolder(SourceFolder sourceFolder) { this.sourceFolder = sourceFolder; } - + @DataBoundSetter public void setSelectByFolder(SelectByFolder selectByFolder) { - this.selectByFolder = selectByFolder; + this.selectByFolder = selectByFolder; } - + @DataBoundSetter public void setStartupOptions(StartupOptions startupOptions) { - this.startupOptions = startupOptions; + this.startupOptions = startupOptions; } @DataBoundSetter @@ -155,59 +153,60 @@ public void setStrict(boolean strict) { public String getTapReportFilePath() { return this.getTapArtifact().getFilePath(); - } - + } + public Artifact getTapArtifact() { return this.tapArtifact; } - + public Artifact getJunitArtifact() { return this.junitArtifact; } - + public String getJunitReportFilePath() { return this.getJunitArtifact().getFilePath(); } - + public Artifact getCoberturaArtifact() { return this.coberturaArtifact; } - + public String getCoberturaReportFilePath() { return this.getCoberturaArtifact().getFilePath(); } - + public Artifact getStmResultsArtifact() { return this.stmResultsArtifact; - } - + } + public String getStmResultsFilePath() { return this.getStmResultsArtifact().getFilePath(); } - + public Artifact getModelCoverageArtifact() { return this.modelCoverageArtifact; } - + public String getModelCoverageFilePath() { return this.getModelCoverageArtifact().getFilePath(); } - + public Artifact getPdfReportArtifact() { return this.pdfReportArtifact; } - + public String getPdfReportFilePath() { return this.getPdfReportArtifact().getFilePath(); } + public SelectByTag getSelectByTag() { - return this.selectByTag; + return this.selectByTag; } public String getSelectByTagAsString() { return this.selectByTag == null - ? null - : selectByTag.getTestTag(); + ? null + : selectByTag.getTestTag(); }; public SourceFolder getSourceFolder() { @@ -216,25 +215,25 @@ public SourceFolder getSourceFolder() { public List getSourceFolderPaths() { return this.sourceFolder == null - ? null - : this.sourceFolder.getSourceFolderStringPaths(); + ? null + : this.sourceFolder.getSourceFolderStringPaths(); } - + public SelectByFolder getSelectByFolder() { - return this.selectByFolder; + return this.selectByFolder; } public List getSelectByFolderPaths() { return this.selectByFolder == null - ? null - : this.selectByFolder.getTestFolderStringPaths(); + ? null + : this.selectByFolder.getTestFolderStringPaths(); } - private Artifact getArtifactObject(boolean isChecked, Artifact returnVal) { + private Artifact getArtifactObject(boolean isChecked, Artifact returnVal) { // If previously checked assign valid artifact object else NullArtifact. return (isChecked) ? returnVal : new NullArtifact(); } - + // Verbosity level public String getLoggingLevel() { @@ -259,40 +258,38 @@ public StartupOptions getStartupOptions() { public String getStartupOptionsAsString() { return this.startupOptions == null - ? "" - : this.startupOptions.getOptions(); + ? "" + : this.startupOptions.getOptions(); } - + // To retain Backward compatibility protected Object readResolve() { /* - * Assign appropriate artifact objects if it was selected in release 2.0.0 or earlier. - * If using a later plugin release, check if artifact objects were previously serialized. - * */ - this.pdfReportArtifact = Optional.ofNullable(this.pdfReportArtifact).orElseGet(() -> - this.getArtifactObject(pdfReportChkBx, new PdfArtifact("matlabTestArtifacts/testreport.pdf")) - ); + * Assign appropriate artifact objects if it was selected in release 2.0.0 or + * earlier. + * If using a later plugin release, check if artifact objects were previously + * serialized. + */ + this.pdfReportArtifact = Optional.ofNullable(this.pdfReportArtifact).orElseGet( + () -> this.getArtifactObject(pdfReportChkBx, new PdfArtifact("matlabTestArtifacts/testreport.pdf"))); - this.tapArtifact = Optional.ofNullable(this.tapArtifact).orElseGet(() -> - this.getArtifactObject(tapChkBx, new TapArtifact("matlabTestArtifacts/taptestresults.tap")) - ); + this.tapArtifact = Optional.ofNullable(this.tapArtifact).orElseGet( + () -> this.getArtifactObject(tapChkBx, new TapArtifact("matlabTestArtifacts/taptestresults.tap"))); - this.junitArtifact = Optional.ofNullable(this.junitArtifact).orElseGet(() -> - this.getArtifactObject(junitChkBx, new JunitArtifact("matlabTestArtifacts/junittestresults.xml")) - ); + this.junitArtifact = Optional.ofNullable(this.junitArtifact).orElseGet(() -> this.getArtifactObject(junitChkBx, + new JunitArtifact("matlabTestArtifacts/junittestresults.xml"))); - this.coberturaArtifact = Optional.ofNullable(this.coberturaArtifact).orElseGet(() -> - this.getArtifactObject(coberturaChkBx, new CoberturaArtifact("matlabTestArtifacts/cobertura.xml")) - ); + this.coberturaArtifact = Optional.ofNullable(this.coberturaArtifact).orElseGet(() -> this + .getArtifactObject(coberturaChkBx, new CoberturaArtifact("matlabTestArtifacts/cobertura.xml"))); - this.stmResultsArtifact = Optional.ofNullable(this.stmResultsArtifact).orElseGet(() -> - this.getArtifactObject(stmResultsChkBx, new StmResultsArtifact("matlabTestArtifacts/simulinktestresults.mldatx")) - ); + this.stmResultsArtifact = Optional.ofNullable(this.stmResultsArtifact) + .orElseGet(() -> this.getArtifactObject(stmResultsChkBx, + new StmResultsArtifact("matlabTestArtifacts/simulinktestresults.mldatx"))); - this.modelCoverageArtifact = Optional.ofNullable(this.modelCoverageArtifact).orElseGet(() -> - this.getArtifactObject(modelCoverageChkBx, new ModelCovArtifact("matlabTestArtifacts/coberturamodelcoverage.xml")) - ); + this.modelCoverageArtifact = Optional.ofNullable(this.modelCoverageArtifact) + .orElseGet(() -> this.getArtifactObject(modelCoverageChkBx, + new ModelCovArtifact("matlabTestArtifacts/coberturamodelcoverage.xml"))); if (factory == null) { factory = new MatlabActionFactory(); @@ -300,9 +297,7 @@ protected Object readResolve() { return this; } - - - + @Extension public static class RunMatlabTestsDescriptor extends BuildStepDescriptor { @@ -313,22 +308,22 @@ public static void addAliases() { Items.XSTREAM2.addCompatibilityAlias("com.mathworks.ci.TestFolders", TestFolders.class); Items.XSTREAM2.addCompatibilityAlias( - "com.mathworks.ci.RunMatlabTestsBuilder$PdfArtifact", + "com.mathworks.ci.RunMatlabTestsBuilder$PdfArtifact", RunMatlabTestsBuilder.PdfArtifact.class); Items.XSTREAM2.addCompatibilityAlias( - "com.mathworks.ci.RunMatlabTestsBuilder$JunitArtifact", + "com.mathworks.ci.RunMatlabTestsBuilder$JunitArtifact", RunMatlabTestsBuilder.JunitArtifact.class); Items.XSTREAM2.addCompatibilityAlias( - "com.mathworks.ci.RunMatlabTestsBuilder$TapArtifact", + "com.mathworks.ci.RunMatlabTestsBuilder$TapArtifact", RunMatlabTestsBuilder.TapArtifact.class); Items.XSTREAM2.addCompatibilityAlias( - "com.mathworks.ci.RunMatlabTestsBuilder$CoberturaArtifact", + "com.mathworks.ci.RunMatlabTestsBuilder$CoberturaArtifact", RunMatlabTestsBuilder.CoberturaArtifact.class); Items.XSTREAM2.addCompatibilityAlias( - "com.mathworks.ci.RunMatlabTestsBuilder$StmResultsArtifact", + "com.mathworks.ci.RunMatlabTestsBuilder$StmResultsArtifact", RunMatlabTestsBuilder.StmResultsArtifact.class); Items.XSTREAM2.addCompatibilityAlias( - "com.mathworks.ci.RunMatlabTestsBuilder$ModelCovArtifact", + "com.mathworks.ci.RunMatlabTestsBuilder$ModelCovArtifact", RunMatlabTestsBuilder.ModelCovArtifact.class); } @@ -343,7 +338,7 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc save(); return super.configure(req, formData); } - + // Verbosity lists public ListBoxModel doFillLoggingLevelItems() { ListBoxModel items = new ListBoxModel(); @@ -370,11 +365,13 @@ public ListBoxModel doFillOutputDetailItems() { } /* - * This is to identify which project type in jenkins this should be applicable.(non-Javadoc) + * This is to identify which project type in jenkins this should be + * applicable.(non-Javadoc) * * @see hudson.tasks.BuildStepDescriptor#isApplicable(java.lang.Class) * - * if it returns true then this build step will be applicable for all project type. + * if it returns true then this build step will be applicable for all project + * type. */ @Override public boolean isApplicable( @@ -415,14 +412,19 @@ public void perform(@Nonnull Run build, @Nonnull FilePath workspace, build.setResult(Result.FAILURE); } } - + /* - * Classes for each optional block in jelly file.This is restriction from Stapler architecture - * when we use as it creates a object for each block in JSON. This could be - * simplified by using inline=true attribute of however it has some abrupt UI - * scrolling issue on click and also some esthetic issue like broken gray side bar appears.Some + * Classes for each optional block in jelly file.This is restriction from + * Stapler architecture + * when we use as it creates a object for each block in JSON. + * This could be + * simplified by using inline=true attribute of however it has + * some abrupt UI + * scrolling issue on click and also some esthetic issue like broken gray side + * bar appears.Some * discussion about this on Jenkins forum - * https://groups.google.com/forum/#!searchin/jenkinsci-dev/OptionalBlock$20action$20class% + * https://groups.google.com/forum/#!searchin/jenkinsci-dev/ + * OptionalBlock$20action$20class% * 7Csort:date/jenkinsci-dev/AFYHSG3NUEI/UsVJIKoE4B8J * */ @@ -557,7 +559,6 @@ public String getFilePath() { } } - public interface Artifact { public void addFilePathArgTo(Map inputArgs); @@ -565,7 +566,7 @@ public interface Artifact { public boolean getSelected(); } - + public static final class SelectByTag extends AbstractDescribableImpl { private String testTag; private static final String SELECT_BY_TAG = "SelectByTag"; diff --git a/src/main/java/com/mathworks/ci/freestyle/options/BuildOptions.java b/src/main/java/com/mathworks/ci/freestyle/options/BuildOptions.java index e68eb968..efac5049 100644 --- a/src/main/java/com/mathworks/ci/freestyle/options/BuildOptions.java +++ b/src/main/java/com/mathworks/ci/freestyle/options/BuildOptions.java @@ -5,7 +5,6 @@ * Copyright 2024 The MathWorks, Inc. * * Describable class for Build Options. - * */ import hudson.Extension; @@ -27,5 +26,7 @@ public String getOptions() { return this.options; } - @Extension public static class DescriptorImpl extends Descriptor {} + @Extension + public static class DescriptorImpl extends Descriptor { + } } diff --git a/src/main/java/com/mathworks/ci/freestyle/options/SelectByFolder.java b/src/main/java/com/mathworks/ci/freestyle/options/SelectByFolder.java index 9482ec7b..64970ced 100644 --- a/src/main/java/com/mathworks/ci/freestyle/options/SelectByFolder.java +++ b/src/main/java/com/mathworks/ci/freestyle/options/SelectByFolder.java @@ -2,7 +2,6 @@ /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import java.util.List; @@ -30,8 +29,7 @@ public List getTestFolderPaths() { public List getTestFolderStringPaths() { return this.testFolderPaths.stream().map( - p -> p.getTestFolders() - ).collect(Collectors.toList()); + p -> p.getTestFolders()).collect(Collectors.toList()); } public void addSourceToInputArgs(List inputArgsList, String cellArraySourceVal) { @@ -39,5 +37,7 @@ public void addSourceToInputArgs(List inputArgsList, String cellArraySou inputArgsList.add("'" + SELECT_BY_FOLDER + "'" + "," + cellArraySourceVal); } - @Extension public static class DescriptorImpl extends Descriptor {} + @Extension + public static class DescriptorImpl extends Descriptor { + } } diff --git a/src/main/java/com/mathworks/ci/freestyle/options/SourceFolder.java b/src/main/java/com/mathworks/ci/freestyle/options/SourceFolder.java index 2f5e4941..984d60b1 100644 --- a/src/main/java/com/mathworks/ci/freestyle/options/SourceFolder.java +++ b/src/main/java/com/mathworks/ci/freestyle/options/SourceFolder.java @@ -1,10 +1,9 @@ package com.mathworks.ci.freestyle.options; /** - * Copyright 2020 The MathWorks, Inc. + * Copyright 2020-2024 The MathWorks, Inc. * * Describable class for Source Folder Option in RunMATLABTest Build step. - * */ import hudson.Extension; @@ -31,16 +30,17 @@ public List getSourceFolderPaths() { public List getSourceFolderStringPaths() { return this.sourceFolderPaths.stream().map( - (SourceFolderPaths p) -> p.getSrcFolderPath() - ) - .collect(Collectors.toList()); + (SourceFolderPaths p) -> p.getSrcFolderPath()) + .collect(Collectors.toList()); } - public void addSourceToInputArgs(List inputArgsList, String cellArraySourceVal) { + public void addSourceToInputArgs(List inputArgsList, String cellArraySourceVal) { // Concatenate all source folders to MATLAB cell array string. inputArgsList.add("'" + SOURCE_FOLDER + "'" + "," + cellArraySourceVal); } - @Extension public static class DescriptorImpl extends Descriptor {} + @Extension + public static class DescriptorImpl extends Descriptor { + } } diff --git a/src/main/java/com/mathworks/ci/freestyle/options/SourceFolderPaths.java b/src/main/java/com/mathworks/ci/freestyle/options/SourceFolderPaths.java index e8728cb9..8d9bfc33 100644 --- a/src/main/java/com/mathworks/ci/freestyle/options/SourceFolderPaths.java +++ b/src/main/java/com/mathworks/ci/freestyle/options/SourceFolderPaths.java @@ -1,11 +1,10 @@ package com.mathworks.ci.freestyle.options; /** - * Copyright 2020 The MathWorks, Inc. + * Copyright 2020-2024 The MathWorks, Inc. * * Describable class for Repeatable Source Folder text boxes in Source Folder option * in RunMATLABTest Build step. - * */ import hudson.Extension; @@ -18,7 +17,7 @@ public class SourceFolderPaths extends AbstractDescribableImpl {} + @Extension + public static final class DescriptorImpl extends Descriptor { + } } diff --git a/src/main/java/com/mathworks/ci/freestyle/options/StartupOptions.java b/src/main/java/com/mathworks/ci/freestyle/options/StartupOptions.java index 631e151b..4febd63e 100644 --- a/src/main/java/com/mathworks/ci/freestyle/options/StartupOptions.java +++ b/src/main/java/com/mathworks/ci/freestyle/options/StartupOptions.java @@ -1,10 +1,9 @@ package com.mathworks.ci.freestyle.options; /** - * Copyright 2023 The MathWorks, Inc. + * Copyright 2023-2024 The MathWorks, Inc. * * Describable class for Startup Options. - * */ import hudson.Extension; @@ -26,5 +25,7 @@ public String getOptions() { return this.options; } - @Extension public static class DescriptorImpl extends Descriptor {} + @Extension + public static class DescriptorImpl extends Descriptor { + } } diff --git a/src/main/java/com/mathworks/ci/freestyle/options/TestFolders.java b/src/main/java/com/mathworks/ci/freestyle/options/TestFolders.java index b47a3da1..4ddc5be8 100644 --- a/src/main/java/com/mathworks/ci/freestyle/options/TestFolders.java +++ b/src/main/java/com/mathworks/ci/freestyle/options/TestFolders.java @@ -2,7 +2,6 @@ /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import org.kohsuke.stapler.DataBoundConstructor; @@ -24,5 +23,7 @@ public String getTestFolders() { return this.testFolders; } - @Extension public static final class DescriptorImpl extends Descriptor {} + @Extension + public static final class DescriptorImpl extends Descriptor { + } } diff --git a/src/main/java/com/mathworks/ci/parameters/BuildActionParameters.java b/src/main/java/com/mathworks/ci/parameters/BuildActionParameters.java index 797e9cf3..437755c1 100644 --- a/src/main/java/com/mathworks/ci/parameters/BuildActionParameters.java +++ b/src/main/java/com/mathworks/ci/parameters/BuildActionParameters.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -17,13 +16,15 @@ public class BuildActionParameters extends MatlabActionParameters { private String tasks; private String buildOptions; - public BuildActionParameters(StepContext context, String startupOpts, String tasks, String buildOpts) throws IOException, InterruptedException { + public BuildActionParameters(StepContext context, String startupOpts, String tasks, String buildOpts) + throws IOException, InterruptedException { super(context, startupOpts); this.tasks = tasks; this.buildOptions = buildOpts; } - public BuildActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, TaskListener listener, String startupOpts, String tasks, String buildOptions) { + public BuildActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, + TaskListener listener, String startupOpts, String tasks, String buildOptions) { super(build, workspace, env, launcher, listener, startupOpts); this.tasks = tasks; this.buildOptions = buildOptions; diff --git a/src/main/java/com/mathworks/ci/parameters/CommandActionParameters.java b/src/main/java/com/mathworks/ci/parameters/CommandActionParameters.java index ec3027a4..d8247a72 100644 --- a/src/main/java/com/mathworks/ci/parameters/CommandActionParameters.java +++ b/src/main/java/com/mathworks/ci/parameters/CommandActionParameters.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -16,12 +15,14 @@ public class CommandActionParameters extends MatlabActionParameters { private String command; - public CommandActionParameters(StepContext context, String startupOpts, String command) throws IOException, InterruptedException { + public CommandActionParameters(StepContext context, String startupOpts, String command) + throws IOException, InterruptedException { super(context, startupOpts); this.command = command; } - public CommandActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, TaskListener listener, String startupOpts, String command) { + public CommandActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, + TaskListener listener, String startupOpts, String command) { super(build, workspace, env, launcher, listener, startupOpts); this.command = command; } diff --git a/src/main/java/com/mathworks/ci/parameters/MatlabActionParameters.java b/src/main/java/com/mathworks/ci/parameters/MatlabActionParameters.java index 9559e801..e62de827 100644 --- a/src/main/java/com/mathworks/ci/parameters/MatlabActionParameters.java +++ b/src/main/java/com/mathworks/ci/parameters/MatlabActionParameters.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -31,7 +30,8 @@ public MatlabActionParameters(StepContext context, String startupOpts) throws IO this.startupOptions = startupOpts; } - public MatlabActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, TaskListener listener, String startupOpts) { + public MatlabActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, TaskListener listener, + String startupOpts) { this.build = build; this.workspace = workspace; this.env = env; diff --git a/src/main/java/com/mathworks/ci/parameters/TestActionParameters.java b/src/main/java/com/mathworks/ci/parameters/TestActionParameters.java index 97343b77..4b041b21 100644 --- a/src/main/java/com/mathworks/ci/parameters/TestActionParameters.java +++ b/src/main/java/com/mathworks/ci/parameters/TestActionParameters.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import java.util.List; @@ -30,7 +29,7 @@ public class TestActionParameters extends MatlabActionParameters { private List sourceFolder = new ArrayList<>(); private List selectByFolder = new ArrayList<>(); - public TestActionParameters(StepContext context, String startupOpts, + public TestActionParameters(StepContext context, String startupOpts, String testResultsPDF, String testResultsTAP, String testResultsJUnit, String codeCoverageCobertura, String testResultsSimulinkTest, String modelCoverageCobertura, String selectByTag, String loggingLevel, String outputDetail, @@ -53,7 +52,8 @@ public TestActionParameters(StepContext context, String startupOpts, this.selectByFolder = selectByFolder; } - public TestActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, TaskListener listener, String startupOpts, + public TestActionParameters(Run build, FilePath workspace, EnvVars env, Launcher launcher, + TaskListener listener, String startupOpts, String testResultsPDF, String testResultsTAP, String testResultsJUnit, String codeCoverageCobertura, String testResultsSimulinkTest, String modelCoverageCobertura, String selectByTag, String loggingLevel, String outputDetail, diff --git a/src/main/java/com/mathworks/ci/pipeline/MatlabBuildStepExecution.java b/src/main/java/com/mathworks/ci/pipeline/MatlabBuildStepExecution.java index a8ab3f64..20616dc2 100644 --- a/src/main/java/com/mathworks/ci/pipeline/MatlabBuildStepExecution.java +++ b/src/main/java/com/mathworks/ci/pipeline/MatlabBuildStepExecution.java @@ -2,7 +2,6 @@ /** * Copyright 2022-2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -16,19 +15,20 @@ import com.mathworks.ci.parameters.BuildActionParameters; public class MatlabBuildStepExecution extends SynchronousNonBlockingStepExecution { - + private static final long serialVersionUID = 4771831219402275744L; private MatlabActionFactory factory; private RunMatlabBuildStep step; - public MatlabBuildStepExecution(MatlabActionFactory factory, StepContext ctx, RunMatlabBuildStep step) throws IOException, InterruptedException { + public MatlabBuildStepExecution(MatlabActionFactory factory, StepContext ctx, RunMatlabBuildStep step) + throws IOException, InterruptedException { super(ctx); this.factory = factory; this.step = step; } - + public MatlabBuildStepExecution(StepContext ctx, RunMatlabBuildStep step) throws IOException, InterruptedException { this(new MatlabActionFactory(), ctx, step); } diff --git a/src/main/java/com/mathworks/ci/pipeline/MatlabCommandStepExecution.java b/src/main/java/com/mathworks/ci/pipeline/MatlabCommandStepExecution.java index 2efaad92..8ba26e63 100644 --- a/src/main/java/com/mathworks/ci/pipeline/MatlabCommandStepExecution.java +++ b/src/main/java/com/mathworks/ci/pipeline/MatlabCommandStepExecution.java @@ -2,7 +2,6 @@ /** * Copyright 2023-2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -15,20 +14,22 @@ import com.mathworks.ci.actions.RunMatlabCommandAction; public class MatlabCommandStepExecution extends SynchronousNonBlockingStepExecution { - + private static final long serialVersionUID = 1957239693658914450L; - + private MatlabActionFactory factory; private RunMatlabCommandStep step; - public MatlabCommandStepExecution(MatlabActionFactory factory, StepContext context, RunMatlabCommandStep step) throws IOException, InterruptedException { + public MatlabCommandStepExecution(MatlabActionFactory factory, StepContext context, RunMatlabCommandStep step) + throws IOException, InterruptedException { super(context); this.factory = factory; this.step = step; } - public MatlabCommandStepExecution(StepContext context, RunMatlabCommandStep step) throws IOException, InterruptedException { + public MatlabCommandStepExecution(StepContext context, RunMatlabCommandStep step) + throws IOException, InterruptedException { this(new MatlabActionFactory(), context, step); } @@ -38,7 +39,7 @@ public Void run() throws Exception { getContext(), step.getStartupOptions(), step.getCommand()); - RunMatlabCommandAction action = factory.createAction(params); + RunMatlabCommandAction action = factory.createAction(params); try { action.run(); diff --git a/src/main/java/com/mathworks/ci/pipeline/MatlabRunTestsStepExecution.java b/src/main/java/com/mathworks/ci/pipeline/MatlabRunTestsStepExecution.java index 2f604fd1..4bc20e84 100644 --- a/src/main/java/com/mathworks/ci/pipeline/MatlabRunTestsStepExecution.java +++ b/src/main/java/com/mathworks/ci/pipeline/MatlabRunTestsStepExecution.java @@ -2,7 +2,6 @@ /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -19,22 +18,23 @@ public class MatlabRunTestsStepExecution extends SynchronousNonBlockingStepExecution { private static final long serialVersionUID = 6704588180717665100L; - + private MatlabActionFactory factory; private RunMatlabTestsStep step; - public MatlabRunTestsStepExecution(MatlabActionFactory factory, StepContext context, RunMatlabTestsStep step) throws IOException, InterruptedException { + public MatlabRunTestsStepExecution(MatlabActionFactory factory, StepContext context, RunMatlabTestsStep step) + throws IOException, InterruptedException { super(context); this.factory = factory; this.step = step; } - public MatlabRunTestsStepExecution(StepContext context, RunMatlabTestsStep step) throws IOException, InterruptedException { + public MatlabRunTestsStepExecution(StepContext context, RunMatlabTestsStep step) + throws IOException, InterruptedException { this(new MatlabActionFactory(), context, step); } - @Override public Void run() throws Exception { TestActionParameters params = new TestActionParameters( diff --git a/src/main/java/com/mathworks/ci/pipeline/RunMatlabBuildStep.java b/src/main/java/com/mathworks/ci/pipeline/RunMatlabBuildStep.java index a978fbe8..7608a356 100644 --- a/src/main/java/com/mathworks/ci/pipeline/RunMatlabBuildStep.java +++ b/src/main/java/com/mathworks/ci/pipeline/RunMatlabBuildStep.java @@ -2,7 +2,6 @@ /** * Copyright 2022-2024 The MathWorks, Inc. - * */ import java.io.Serializable; @@ -34,7 +33,7 @@ public class RunMatlabBuildStep extends Step implements Serializable { @DataBoundConstructor public RunMatlabBuildStep() { - + } public String getTasks() { @@ -60,7 +59,7 @@ public void setStartupOptions(String startupOptions) { } @DataBoundSetter - public void setBuildOptions (String buildOptions) { + public void setBuildOptions(String buildOptions) { this.buildOptions = buildOptions; } @@ -82,12 +81,10 @@ public Set> getRequiredContext() { public String getFunctionName() { return Message.getValue("matlab.build.build.step.name"); } - + @Override public String getDisplayName() { return Message.getValue("matlab.build.step.display.name"); } } } - - diff --git a/src/main/java/com/mathworks/ci/pipeline/RunMatlabCommandStep.java b/src/main/java/com/mathworks/ci/pipeline/RunMatlabCommandStep.java index 470bba23..45469d13 100644 --- a/src/main/java/com/mathworks/ci/pipeline/RunMatlabCommandStep.java +++ b/src/main/java/com/mathworks/ci/pipeline/RunMatlabCommandStep.java @@ -2,7 +2,6 @@ /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import java.io.Serializable; @@ -25,7 +24,7 @@ import com.mathworks.ci.Message; public class RunMatlabCommandStep extends Step implements Serializable { - + private static final long serialVersionUID = 1L; private String command; @@ -67,12 +66,10 @@ public Set> getRequiredContext() { public String getFunctionName() { return Message.getValue("matlab.command.build.step.name"); } - + @Override public String getDisplayName() { return Message.getValue("matlab.command.step.display.name"); } } } - - diff --git a/src/main/java/com/mathworks/ci/pipeline/RunMatlabTestsStep.java b/src/main/java/com/mathworks/ci/pipeline/RunMatlabTestsStep.java index 62375800..960c976a 100644 --- a/src/main/java/com/mathworks/ci/pipeline/RunMatlabTestsStep.java +++ b/src/main/java/com/mathworks/ci/pipeline/RunMatlabTestsStep.java @@ -2,7 +2,6 @@ /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import java.io.Serializable; @@ -28,7 +27,7 @@ public class RunMatlabTestsStep extends Step implements Serializable { private static final long serialVersionUID = 1L; - + private String testResultsPDF; private String testResultsTAP; private String testResultsJUnit; @@ -47,9 +46,9 @@ public class RunMatlabTestsStep extends Step implements Serializable { @DataBoundConstructor public RunMatlabTestsStep() { - + } - + public String getTestResultsTAP() { return testResultsTAP; } @@ -58,7 +57,7 @@ public String getTestResultsTAP() { public void setTestResultsTAP(String testResultsTAP) { this.testResultsTAP = testResultsTAP; } - + public String getTestResultsPDF() { return testResultsPDF; } @@ -98,7 +97,6 @@ public void setTestResultsSimulinkTest(String testResultsSimulinkTest) { public String getModelCoverageCobertura() { return modelCoverageCobertura; } - @DataBoundSetter public void setModelCoverageCobertura(String modelCoverageCobertura) { @@ -113,29 +111,29 @@ public List getSourceFolder() { public void setSourceFolder(List sourceFolder) { this.sourceFolder = sourceFolder; } - + public String getSelectByTag() { return this.selectByTag; } - + @DataBoundSetter public void setSelectByTag(String selectByTag) { this.selectByTag = selectByTag; } - + public List getSelectByFolder() { return this.selectByFolder; } - + @DataBoundSetter public void setSelectByFolder(List selectByFolder) { this.selectByFolder = selectByFolder; } - + public String getLoggingLevel() { return loggingLevel; } - + @DataBoundSetter public void setLoggingLevel(String loggingLevel) { this.loggingLevel = loggingLevel; @@ -144,7 +142,7 @@ public void setLoggingLevel(String loggingLevel) { public String getOutputDetail() { return outputDetail; } - + @DataBoundSetter public void setOutputDetail(String outputDetail) { this.outputDetail = outputDetail; @@ -153,7 +151,7 @@ public void setOutputDetail(String outputDetail) { public boolean getUseParallel() { return useParallel; } - + @DataBoundSetter public void setUseParallel(boolean useParallel) { this.useParallel = useParallel; @@ -162,7 +160,7 @@ public void setUseParallel(boolean useParallel) { public boolean getStrict() { return strict; } - + @DataBoundSetter public void setStrict(boolean strict) { this.strict = strict; @@ -171,7 +169,7 @@ public void setStrict(boolean strict) { public String getStartupOptions() { return Util.fixNull(startupOptions); } - + @DataBoundSetter public void setStartupOptions(String startupOptions) { this.startupOptions = startupOptions; @@ -195,7 +193,7 @@ public Set> getRequiredContext() { public String getFunctionName() { return Message.getValue("matlab.tests.build.step.name"); } - + @Override public String getDisplayName() { return Message.getValue("matlab.tests.step.display.name"); diff --git a/src/main/java/com/mathworks/ci/tools/InstallationFailedException.java b/src/main/java/com/mathworks/ci/tools/InstallationFailedException.java new file mode 100644 index 00000000..0e87c3c0 --- /dev/null +++ b/src/main/java/com/mathworks/ci/tools/InstallationFailedException.java @@ -0,0 +1,16 @@ +package com.mathworks.ci.tools; + +/** + * Copyright 2024, The MathWorks, Inc. + */ + +import java.io.IOException; + +// Extend IOException so we can throw and stop the build if installation fails + +public class InstallationFailedException extends IOException { + + InstallationFailedException(String message) { + super(message); + } +} diff --git a/src/main/java/com/mathworks/ci/tools/MatlabInstaller.java b/src/main/java/com/mathworks/ci/tools/MatlabInstaller.java new file mode 100644 index 00000000..0a9e8bee --- /dev/null +++ b/src/main/java/com/mathworks/ci/tools/MatlabInstaller.java @@ -0,0 +1,267 @@ +package com.mathworks.ci.tools; + +/** + * Copyright 2024, The MathWorks, Inc. + */ + +import com.mathworks.ci.MatlabInstallation; +import com.mathworks.ci.Message; +import com.mathworks.ci.utilities.GetSystemProperties; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +import hudson.Extension; +import hudson.FilePath; +import hudson.Launcher; +import hudson.Launcher.ProcStarter; + +import hudson.model.Node; +import hudson.model.TaskListener; +import hudson.tools.ToolInstaller; +import hudson.tools.ToolInstallation; +import hudson.tools.ToolInstallerDescriptor; + +import hudson.util.ArgumentListBuilder; +import hudson.util.FormValidation; + +import java.io.IOException; +import java.net.URL; + +import java.nio.charset.StandardCharsets; + +import java.util.Locale; + +import jenkins.model.Jenkins; +import org.apache.commons.io.IOUtils; + +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + +public class MatlabInstaller extends ToolInstaller { + + private String release; + private String products; + private static String DEFAULT_PRODUCT = "MATLAB"; + + @DataBoundConstructor + public MatlabInstaller(String id) { + super(id); + } + + public String getRelease() { + return this.release.trim(); + } + + @DataBoundSetter + public void setRelease(String release) { + this.release = release; + } + + public String getProducts() { + return this.products; + } + + @DataBoundSetter + public void setProducts(String products) { + this.products = products; + } + + @Override + public FilePath performInstallation(ToolInstallation tool, Node node, TaskListener log) + throws IOException, InterruptedException { + FilePath destination = preferredLocation(tool, node); + String[] systemProperties = getSystemProperties(node); + FilePath matlabRootPath; + if (systemProperties[0].toLowerCase().contains("os x")) { + matlabRootPath = new FilePath(destination, this.getRelease() + ".app"); + } else { + matlabRootPath = new FilePath(destination, this.getRelease()); + } + String platform = getPlatform(systemProperties[0], systemProperties[1]); + getFreshCopyOfExecutables(platform, destination); + + makeDir(matlabRootPath); + int result = installUsingMpm(node, this.getRelease(), matlabRootPath, this.getProducts(), log); + if (result == 0) { + log.getLogger().println( + "MATLAB installation of version " + this.getRelease() + + " using mpm completed successfully!"); + } + return matlabRootPath; + } + + private int installUsingMpm(Node node, String release, FilePath destination, String products, TaskListener log) + throws IOException, InterruptedException { + + Launcher matlabInstaller = node.createLauncher(log); + ProcStarter installerProc = matlabInstaller.launch(); + + ArgumentListBuilder args = new ArgumentListBuilder(); + args.add(destination.getParent().getRemote() + getNodeSpecificMPMExecutor(node)); + args.add("install"); + appendReleaseToArguments(release, args, log); + args.add("--destination=" + destination.getRemote()); + addMatlabProductsToArgs(args, products); + installerProc.pwd(destination).cmds(args).stdout(log); + int result; + try { + result = installerProc.join(); + } catch (Exception e) { + log.getLogger().println("MATLAB installation failed " + e.getMessage()); + throw new InstallationFailedException(e.getMessage()); + } + return result; + } + + private void makeDir(FilePath path) throws IOException, InterruptedException { + if (!path.exists()) { + path.mkdirs(); + path.chmod(0777); + } + } + + private void appendReleaseToArguments(String release, ArgumentListBuilder args, TaskListener log) { + String trimmedRelease = release.trim(); + String actualRelease = trimmedRelease; + + if (trimmedRelease.equalsIgnoreCase("latest") || trimmedRelease.equalsIgnoreCase( + "latest-including-prerelease")) { + String releaseInfoUrl = Message.getValue("matlab.release.info.url") + trimmedRelease; + String releaseVersion = null; + try { + releaseVersion = IOUtils.toString(new URL(releaseInfoUrl), + StandardCharsets.UTF_8).trim(); + } catch (IOException e) { + log.getLogger().println("Failed to fetch release version: " + e.getMessage()); + } + + if (releaseVersion != null && releaseVersion.contains("prerelease")) { + actualRelease = releaseVersion.replace("prerelease", ""); + args.add("--release-status=Prerelease"); + } else { + actualRelease = releaseVersion; + } + } + args.add("--release=" + actualRelease); + } + + private void getFreshCopyOfExecutables(String platform, FilePath expectedPath) + throws IOException, InterruptedException { + FilePath matlabBatchPath = new FilePath(expectedPath, "matlab-batch"); + FilePath mpmPath = new FilePath(expectedPath, "mpm"); + + URL mpmUrl; + URL matlabBatchUrl; + + switch (platform) { + case "glnxa64": + mpmUrl = new URL(Message.getValue("tools.matlab.mpm.installer.linux")); + matlabBatchUrl = new URL(Message.getValue("tools.matlab.batch.executable.linux")); + break; + case "maci64": + mpmUrl = new URL(Message.getValue("tools.matlab.mpm.installer.maci64")); + matlabBatchUrl = new URL(Message.getValue("tools.matlab.batch.executable.maci64")); + break; + case "maca64": + mpmUrl = new URL(Message.getValue("tools.matlab.mpm.installer.maca64")); + matlabBatchUrl = new URL(Message.getValue("tools.matlab.batch.executable.maca64")); + break; + default: + throw new InstallationFailedException("Unsupported OS"); + } + + // Handle the concurrency issues due to same name. + FilePath tempMatlabBatchPath = new FilePath(expectedPath, "temp-matlab-batch"); + FilePath tempMpmPath = new FilePath(expectedPath, "temp-mpm"); + try { + tempMpmPath.copyFrom(mpmUrl.openStream()); + tempMpmPath.chmod(0777); + tempMatlabBatchPath.copyFrom(matlabBatchUrl.openStream()); + tempMatlabBatchPath.chmod(0777); + + tempMpmPath.renameTo(mpmPath); + tempMatlabBatchPath.renameTo(matlabBatchPath); + + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } finally { + // Clean up temporary files if they exist + tempMatlabBatchPath.delete(); + tempMpmPath.delete(); + } + } + + @SuppressFBWarnings(value = { + "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" }, justification = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE: Its false positive scenario for sport bug which is fixed in later versions " + + "https://github.com/spotbugs/spotbugs/issues/1843") + private String getNodeSpecificMPMExecutor(Node node) { + if (!node.toComputer().isUnix()) { + return "\\mpm.exe"; + } + return "/mpm"; + } + + private void addMatlabProductsToArgs(ArgumentListBuilder args, String products) + throws IOException, InterruptedException { + args.add("--products"); + if (products.isEmpty()) { + args.add(DEFAULT_PRODUCT); + + } else { + if (!products.contains(DEFAULT_PRODUCT)) { + args.add(DEFAULT_PRODUCT); + } + String[] productList = products.split(" "); + for (String prod : productList) { + args.add(prod); + } + } + } + + public String getPlatform(String os, String architecture) throws InstallationFailedException { + String value = os.toLowerCase(Locale.ENGLISH); + if (value.contains("linux")) { + return "glnxa64"; + } else if (value.contains("os x")) { + if (architecture.equalsIgnoreCase("aarch64") || architecture.equalsIgnoreCase( + "arm64")) { + return "maca64"; + } else { + return "maci64"; + } + } else { + throw new InstallationFailedException("Unsupported OS"); + } + } + + @SuppressFBWarnings(value = { + "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" }, justification = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE: Its false positive scenario for sport bug which is fixed in later versions " + + "https://github.com/spotbugs/spotbugs/issues/1843") + private String[] getSystemProperties(Node node) throws IOException, InterruptedException { + String[] properties = node.getChannel() + .call(new GetSystemProperties("os.name", "os.arch", "os.version")); + return properties; + } + + @Extension + public static final class DescriptorImpl extends ToolInstallerDescriptor { + + public String getDisplayName() { + return Message.getValue("matlab.tools.auto.install.display.name"); + } + + @Override + public boolean isApplicable(Class toolType) { + return toolType == MatlabInstallation.class; + } + + public FormValidation doCheckRelease(@QueryParameter String value) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + if (value.isEmpty()) { + return FormValidation.error(Message.getValue("tools.matlab.empty.release.error")); + } + return FormValidation.ok(); + } + } +} diff --git a/src/main/java/com/mathworks/ci/utilities/GetSystemProperties.java b/src/main/java/com/mathworks/ci/utilities/GetSystemProperties.java new file mode 100644 index 00000000..117453d7 --- /dev/null +++ b/src/main/java/com/mathworks/ci/utilities/GetSystemProperties.java @@ -0,0 +1,26 @@ +package com.mathworks.ci.utilities; + +/** + * Copyright 2024, The MathWorks, Inc. + */ + +import jenkins.security.MasterToSlaveCallable; + +public class GetSystemProperties extends MasterToSlaveCallable { + + private static final long serialVersionUID = 1L; + + private final String[] properties; + + public GetSystemProperties(String... properties) { + this.properties = properties; + } + + public String[] call() { + String[] values = new String[properties.length]; + for (int i = 0; i < properties.length; i++) { + values[i] = System.getProperty(properties[i]); + } + return values; + } +} diff --git a/src/main/java/com/mathworks/ci/utilities/MatlabCommandRunner.java b/src/main/java/com/mathworks/ci/utilities/MatlabCommandRunner.java index a69f9559..b756df39 100644 --- a/src/main/java/com/mathworks/ci/utilities/MatlabCommandRunner.java +++ b/src/main/java/com/mathworks/ci/utilities/MatlabCommandRunner.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -29,11 +28,11 @@ public class MatlabCommandRunner { private MatlabActionParameters params; private FilePath tempFolder; private OutputStream stdOut; - private Map additionalEnvVars; + private Map additionalEnvVars; public MatlabCommandRunner(MatlabActionParameters params) throws IOException, InterruptedException { this.params = params; - this.additionalEnvVars = new HashMap(); + this.additionalEnvVars = new HashMap(); FilePath workspace = params.getWorkspace(); @@ -50,14 +49,14 @@ public MatlabCommandRunner(MatlabActionParameters params) throws IOException, In this.tempFolder = tmpRoot.createTempDir("matlab", null); } - /** + /** * Spawns a process to run the specified command. * * @param command The command to run */ public void runMatlabCommand(String command) throws IOException, InterruptedException, MatlabExecutionException { this.params.getTaskListener().getLogger() - .println("\n#################### Starting command output ####################"); + .println("\n#################### Starting command output ####################"); // Prepare the executable FilePath exePath = prepareRunnerExecutable(); @@ -65,9 +64,9 @@ public void runMatlabCommand(String command) throws IOException, InterruptedExce // Create the script file FilePath scriptFile = createFileWithContent(command); String cmd = "setenv('MW_ORIG_WORKING_FOLDER', cd('" - + this.tempFolder.getRemote() - + "'));" - + scriptFile.getBaseName(); + + this.tempFolder.getRemote() + + "'));" + + scriptFile.getBaseName(); // Create command ArgumentListBuilder args = new ArgumentListBuilder(); @@ -78,13 +77,13 @@ public void runMatlabCommand(String command) throws IOException, InterruptedExce // Add custom environment vars EnvVars env = getEnvVars(); Utilities.addMatlabToEnvPathFromAxis( - Computer.currentComputer(), - this.params.getTaskListener(), + Computer.currentComputer(), + this.params.getTaskListener(), env); ProcStarter proc = this.params.getLauncher().launch() - .envs(env) - .cmds(args); + .envs(env) + .cmds(args); if (this.stdOut == null) { proc.stdout(this.params.getTaskListener()); } else { @@ -111,7 +110,7 @@ public void redirectStdOut(OutputStream out) { /** * Adds an environment variable. * - * @param key the environment variable name + * @param key the environment variable name * @param value the environment variable value */ public void addEnvironmentVariable(String key, String value) { @@ -120,7 +119,7 @@ public void addEnvironmentVariable(String key, String value) { public EnvVars getEnvVars() { EnvVars env = new EnvVars(this.params.getEnvVars()); - env.putAll(additionalEnvVars); + env.putAll(additionalEnvVars); return env; } @@ -131,7 +130,8 @@ public EnvVars getEnvVars() { * @param targetFile the name of the file to create in the temp folder. * @return the FilePath to the new location in the temp folder. */ - public FilePath copyFileToTempFolder(String sourceFile, String targetFile) throws IOException, InterruptedException { + public FilePath copyFileToTempFolder(String sourceFile, String targetFile) + throws IOException, InterruptedException { final ClassLoader classLoader = getClass().getClassLoader(); FilePath targetFilePath = new FilePath(this.tempFolder, targetFile); InputStream in = classLoader.getResourceAsStream(sourceFile); @@ -154,7 +154,8 @@ public void removeTempFolder() throws IOException, InterruptedException { /** * Creates a file with the specified content in the temporary folder. * - * Additionally, the file content will be prefixed with a statement returning to the MATLAB starting folder. + * Additionally, the file content will be prefixed with a statement returning to + * the MATLAB starting folder. * * @param content string that represents the content of the file. * @return the FilePath to the script file that is created. @@ -165,10 +166,10 @@ protected FilePath createFileWithContent(String content) throws IOException, Int String expandedContent = getEnvVars().expand(content); String finalContent = "cd(getenv('MW_ORIG_WORKING_FOLDER'));\n" - + expandedContent; + + expandedContent; this.params.getTaskListener().getLogger() - .println("Generating MATLAB script with content:\n" + expandedContent + "\n\n"); + .println("Generating MATLAB script with content:\n" + expandedContent + "\n\n"); scriptFile.write(finalContent, "UTF-8"); @@ -192,17 +193,17 @@ protected FilePath prepareRunnerExecutable() throws IOException, InterruptedExce args.add("-m"); launcher.launch() - .cmds(args) - .masks(true, true, true) - .stdout(kernelStream) - .join(); + .cmds(args) + .masks(true, true, true) + .stdout(kernelStream) + .join(); String runnerSource; String kernelArch = kernelStream.toString("UTF-8"); if (kernelArch.contains("Linux")) { runnerSource = "glnxa64/run-matlab-command"; } else if (kernelArch.contains("arm64")) { - runnerSource = "maca64/run-matlab-command"; + runnerSource = "maca64/run-matlab-command"; } else { runnerSource = "maci64/run-matlab-command"; } @@ -211,7 +212,7 @@ protected FilePath prepareRunnerExecutable() throws IOException, InterruptedExce copyFileToTempFolder(runnerSource, dest); return new FilePath(this.tempFolder, dest); - } + } // Windows String dest = "run-matlab-command.exe"; diff --git a/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/config.jelly b/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/config.jelly new file mode 100644 index 00000000..7b7891db --- /dev/null +++ b/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/config.jelly @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/help-products.html b/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/help-products.html new file mode 100644 index 00000000..d15106e5 --- /dev/null +++ b/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/help-products.html @@ -0,0 +1,13 @@ +
+

+ Insert a space-separated list of products to install. The plugin installs the specified products in addition to MATLAB. +

+

+ For a list of supported products, open the input file for your preferred release from the mpm-input-files folder on GitHub. + Specify products using the format shown in the input file, excluding the #product. prefix. For example, to install Deep Learning Toolbox in addition to MATLAB, insert Deep_Learning_Toolbox in the Products box. +

+

+ Example: Simulink
+ Example: Simulink Deep_Learning_Toolbox
+

+
\ No newline at end of file diff --git a/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/help-release.html b/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/help-release.html new file mode 100644 index 00000000..804233bf --- /dev/null +++ b/src/main/resources/com/mathworks/ci/tools/MatlabInstaller/help-release.html @@ -0,0 +1,22 @@ +
+

+ Insert the MATLAB version to install. To install the latest release of MATLAB, insert latest in the Release box. +

+

+

    +
  • To install the latest update of a release, specify only the release name, for example, R2023b.
  • +
  • To install a specific update release, specify the release name with an update number suffix, for example, R2023bU4.
  • +
  • To install a release without updates, specify the release name with an update 0 or general release suffix, for example, R2023bU0 or R2023bGR.
  • +
+

+

+ Example: R2024a
+ Example: latest
+ Example: R2023bU4
+

+

+ Note: The plugin does not install dependencies on a Linux platform. If you are using a Linux platform, + verify that the required software is available before installing products using MATLAB Package Manager. For more information, see + Get MATLAB Package Manager. +

+
\ No newline at end of file diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties index e64fa092..9498c373 100644 --- a/src/main/resources/config.properties +++ b/src/main/resources/config.properties @@ -6,21 +6,17 @@ Builder.build.builder.display.name = Run MATLAB Build Builder.script.builder.display.name = Run MATLAB Command Buildwrapper.display.name = Use MATLAB version Builder.matlab.runner.target.file.name = runMatlabTests.m -Builder.matlab.cobertura.support.warning = To generate a Cobertura code coverage report, use MATLAB R2017b or a newer release. + Builder.invalid.matlab.root.warning = Unable to find MATLAB on this machine using the specified location. The specified root folder might contain MATLAB on a different build agent. Builder.matlab.root.empty.error = Full path to the MATLAB root folder is required. Builder.matlab.test.support.error = To run tests with the Jenkins plugin, use MATLAB R2013a or a newer release. -builder.matlab.automatictestoption.display.name = Automatic -builder.matlab.customcommandoption.display.name = Custom + Releaseinfo.matlab.version.not.found.error = Error finding MATLAB release for given MATLAB root. Verify MATLAB root path. matlab.not.found.error = Unable to launch MATLAB from the specified location. Verify the path to MATLAB root folder. matlab.not.found.error.for.node = Unable to launch MATLAB '%s' on the node '%s'. Verify global tool configuration for the specified node. matlab.execution.exception.prefix = Received a nonzero exit code %d while trying to run MATLAB. matlab.empty.command.error = Specify at least one script, function, or statement to execute. -Builder.matlab.modelcoverage.support.warning = To generate a Cobertura model coverage report, use MATLAB R2018b or a newer release. -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 + matlab.build.build.step.name = runMATLABBuild matlab.command.build.step.name = runMATLABCommand matlab.tests.build.step.name = runMATLABTests @@ -33,4 +29,14 @@ Axis.matlab.key = MATLAB Axis.use.matlab.warning = This project specifies MATLAB versions using the added 'MATLAB' axis as well as the 'Use MATLAB version' option. The value specified by 'Use MATLAB version' takes precedence over the values specified by the 'MATLAB' axis. Axis.no.installed.matlab.error = Because no MATLAB versions exist under Jenkins Global Tool Configuration, the plugin will run the default matrix configuration. Use.matlab.version.axis.warning = This project specifies MATLAB versions using the 'Use MATLAB version' option as well as the added 'MATLAB' axis. The value specified by 'Use MATLAB version' takes precedence over the values specified by the 'MATLAB' axis. +matlab.tools.auto.install.display.name = Install Using MATLAB Package Manager + +tools.matlab.mpm.installer.linux = https://www.mathworks.com/mpm/glnxa64/mpm +tools.matlab.batch.executable.linux = https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/matlab-batch +tools.matlab.mpm.installer.maci64 = https://www.mathworks.com/mpm/maci64/mpm +tools.matlab.batch.executable.maci64 = https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/maci64/matlab-batch +tools.matlab.mpm.installer.maca64 = https://www.mathworks.com/mpm/maca64/mpm +tools.matlab.batch.executable.maca64 = https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/maca64/matlab-batch +tools.matlab.empty.release.error = MATLAB release is mandatory field. +matlab.release.info.url = https://ssd.mathworks.com/supportfiles/ci/matlab-release/v0/ diff --git a/src/test/java/integ/com/mathworks/ci/BuildArtifactActionTest.java b/src/test/java/integ/com/mathworks/ci/BuildArtifactActionTest.java index d9aba437..62bc5b9f 100644 --- a/src/test/java/integ/com/mathworks/ci/BuildArtifactActionTest.java +++ b/src/test/java/integ/com/mathworks/ci/BuildArtifactActionTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024 The MathWorks, Inc. - * */ import hudson.FilePath; @@ -33,13 +32,12 @@ public class BuildArtifactActionTest { private static String VERSION_INFO_XML_FILE = "VersionInfo.xml"; - public BuildArtifactActionTest(){ + public BuildArtifactActionTest() { } @Rule public JenkinsRule jenkins = new JenkinsRule(); - @Before public void testSetup() throws IOException { this.project = jenkins.createFreeStyleProject(); @@ -68,211 +66,222 @@ private URL getResource(String resource) { } /** - * Verify if total BuildArtifacts returned from artifact file. - *5 + * Verify if total BuildArtifacts returned from artifact file. + * 5 */ @Test - public void verifyBuildArtifactsReturned() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyBuildArtifactsReturned() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); int expectedSize = ba.size(); - Assert.assertEquals("Incorrect build artifact",3,expectedSize); + Assert.assertEquals("Incorrect build artifact", 3, expectedSize); } /** - * Verify if total Failed count returned from artifact file. + * Verify if total Failed count returned from artifact file. * */ @Test - public void verifyFailedCount() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyFailedCount() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); boolean expectedStatus = ba.get(0).getTaskFailed(); - Assert.assertEquals("The task succeeded",false,expectedStatus); + Assert.assertEquals("The task succeeded", false, expectedStatus); } /** - * Verify if total skipped count returned from artifact file. + * Verify if total skipped count returned from artifact file. * */ @Test - public void verifySkipCount() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifySkipCount() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); - Assert.assertEquals("The task is not skipped",true,ba.get(0).getTaskSkipped()); + Assert.assertEquals("The task is not skipped", true, ba.get(0).getTaskSkipped()); } /** - * Verify if skip reason is returned from artifact file. + * Verify if skip reason is returned from artifact file. * */ @Test - public void verifySkipReasonIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifySkipReasonIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); - Assert.assertEquals("The task is not skipped",true,ba.get(0).getTaskSkipped()); - Assert.assertEquals("The skip reason for skipped task is inaccurate","user requested",ba.get(0).getSkipReason()); + Assert.assertEquals("The task is not skipped", true, ba.get(0).getTaskSkipped()); + Assert.assertEquals("The skip reason for skipped task is inaccurate", "user requested", + ba.get(0).getSkipReason()); } /** - * Verify if duration returned from artifact file. + * Verify if duration returned from artifact file. * */ @Test - public void verifyDurationIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyDurationIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); - Assert.assertEquals("The task duration is not matching","00:02:53",ba.get(0).getTaskDuration()); + Assert.assertEquals("The task duration is not matching", "00:02:53", ba.get(0).getTaskDuration()); } /** - * Verify if Task description returned from artifact file. + * Verify if Task description returned from artifact file. * */ @Test - public void verifyTaskDescriptionIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyTaskDescriptionIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); - Assert.assertEquals("The task description is not matching","Test show",ba.get(0).getTaskDescription()); + Assert.assertEquals("The task description is not matching", "Test show", ba.get(0).getTaskDescription()); } /** - * Verify if Task name returned from artifact file. + * Verify if Task name returned from artifact file. * */ @Test - public void verifyTaskNameIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyTaskNameIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; + final String targetFile = "buildArtifact" + actionID + ".json"; BuildArtifactAction ac = new BuildArtifactAction(build, actionID); FilePath artifactRoot = new FilePath(build.getRootDir()); - copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json",targetFile,artifactRoot); + copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json", targetFile, artifactRoot); List ba = ac.getBuildArtifact(); - Assert.assertEquals("The task name is not matching","show",ba.get(0).getTaskName()); + Assert.assertEquals("The task name is not matching", "show", ba.get(0).getTaskName()); } /** - * Verify if total count returned from artifact file. + * Verify if total count returned from artifact file. * */ @Test - public void verifyTotalTaskCountIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyTotalTaskCountIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); FilePath artifactRoot = new FilePath(build.getRootDir()); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; - copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json",targetFile,artifactRoot); + final String targetFile = "buildArtifact" + actionID + ".json"; + copyFileInWorkspace("buildArtifacts/t2/buildArtifact.json", targetFile, artifactRoot); BuildArtifactAction ac = new BuildArtifactAction(build, actionID); - Assert.assertEquals("Total task count is not correct",1,ac.getTotalCount()); + Assert.assertEquals("Total task count is not correct", 1, ac.getTotalCount()); } /** - * Verify if total count returned from artifact file. + * Verify if total count returned from artifact file. * */ @Test - public void verifyTotalTaskCountIsAccurate2() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyTotalTaskCountIsAccurate2() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); FilePath artifactRoot = new FilePath(build.getRootDir()); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; - copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json",targetFile,artifactRoot); + final String targetFile = "buildArtifact" + actionID + ".json"; + copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json", targetFile, artifactRoot); BuildArtifactAction ac = new BuildArtifactAction(build, actionID); - Assert.assertEquals("Total task count is not correct",3,ac.getTotalCount()); + Assert.assertEquals("Total task count is not correct", 3, ac.getTotalCount()); } /** - * Verify if total failed count returned from artifact file. + * Verify if total failed count returned from artifact file. * */ @Test - public void verifyTotalFailedTaskCountIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyTotalFailedTaskCountIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); FilePath artifactRoot = new FilePath(build.getRootDir()); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; - copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json",targetFile,artifactRoot); + final String targetFile = "buildArtifact" + actionID + ".json"; + copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json", targetFile, artifactRoot); BuildArtifactAction ac = new BuildArtifactAction(build, actionID); - Assert.assertEquals("Total task count is not correct",3,ac.getTotalCount()); - Assert.assertEquals("Total task failed count is not correct",1,ac.getFailCount()); + Assert.assertEquals("Total task count is not correct", 3, ac.getTotalCount()); + Assert.assertEquals("Total task failed count is not correct", 1, ac.getFailCount()); } - + /** - * Verify if total skipped count returned from artifact file. + * Verify if total skipped count returned from artifact file. * */ @Test - public void verifyTotalSkipTaskCountIsAccurate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyTotalSkipTaskCountIsAccurate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); FilePath artifactRoot = new FilePath(build.getRootDir()); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; - copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json",targetFile,artifactRoot); + final String targetFile = "buildArtifact" + actionID + ".json"; + copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json", targetFile, artifactRoot); BuildArtifactAction ac = new BuildArtifactAction(build, actionID); - Assert.assertEquals("Total task count is not correct",3,ac.getTotalCount()); - Assert.assertEquals("Total task skip count is not correct",1,ac.getSkipCount()); + Assert.assertEquals("Total task count is not correct", 3, ac.getTotalCount()); + Assert.assertEquals("Total task skip count is not correct", 1, ac.getSkipCount()); } /** - * Verify if ActionID is set correctly. + * Verify if ActionID is set correctly. * */ @Test - public void verifyActionIDisAppropriate() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { + public void verifyActionIDisAppropriate() + throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException { FreeStyleBuild build = getFreestyleBuild(); FilePath artifactRoot = new FilePath(build.getRootDir()); final String actionID = "abc123"; - final String targetFile = "buildArtifact"+ actionID + ".json"; - copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json",targetFile,artifactRoot); + final String targetFile = "buildArtifact" + actionID + ".json"; + copyFileInWorkspace("buildArtifacts/t1/buildArtifact.json", targetFile, artifactRoot); BuildArtifactAction ac = new BuildArtifactAction(build, actionID); - Assert.assertEquals("Incorrect ActionID",actionID,ac.getActionID()); + Assert.assertEquals("Incorrect ActionID", actionID, ac.getActionID()); } - - private void copyFileInWorkspace(String sourceFile, String targetFile, FilePath targetWorkspace) throws IOException, InterruptedException { final ClassLoader classLoader = getClass().getClassLoader(); @@ -284,7 +293,8 @@ private void copyFileInWorkspace(String sourceFile, String targetFile, FilePath } private FreeStyleBuild getFreestyleBuild() throws ExecutionException, InterruptedException, URISyntaxException { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(this.scriptBuilder); diff --git a/src/test/java/integ/com/mathworks/ci/MatlabInstallationTest.java b/src/test/java/integ/com/mathworks/ci/MatlabInstallationTest.java index 4012c61f..288683e2 100644 --- a/src/test/java/integ/com/mathworks/ci/MatlabInstallationTest.java +++ b/src/test/java/integ/com/mathworks/ci/MatlabInstallationTest.java @@ -1,8 +1,7 @@ package com.mathworks.ci; /** - * Copyright 2020-2021 The MathWorks, Inc. - * + * Copyright 2020-2024 The MathWorks, Inc. */ import hudson.matrix.AxisList; @@ -85,17 +84,18 @@ private MatlabInstallation setMatlabInstallation(String name, String home) { newInst.add(newMatlabInstallation); MatlabInstallation[] setInst = new MatlabInstallation[newInst.size()]; matlabInstDescriptor.setInstallations(newInst.toArray(setInst)); - return newMatlabInstallation; + return newMatlabInstallation; } - private MatlabInstallation[] getMatlabInstallation(){ + private MatlabInstallation[] getMatlabInstallation() { // static method to return all installations return MatlabInstallation.getAll(); } /* - * Test to verify global tool configuration for MATLAB by doing a configuration round trip. - * */ + * Test to verify global tool configuration for MATLAB by doing a configuration + * round trip. + */ @Test public void verifyRoundTripInstallation() throws Exception { MatlabInstallation matlabInst = setMatlabInstallation("R2019b", "C:\\FakePath\\MATLAB\\R2019b"); @@ -112,7 +112,7 @@ public void verifyRoundTripInstallation() throws Exception { /* * Test to verify usage of MATLAB tool installation in pipeline project. - * */ + */ @Test public void verifyInstallationInPipeline() throws Exception { URL url = MatlabInstallationTest.class.getClassLoader().getResource("versioninfo/R2018b"); @@ -120,19 +120,20 @@ public void verifyInstallationInPipeline() throws Exception { jenkins.configRoundtrip(); WorkflowJob project = jenkins.createProject(WorkflowJob.class); project.setDefinition(new CpsFlowDefinition("node { \n" - + " def matlabroot \n" - + " matlabroot = tool 'R2018b' \n" - + " withEnv([\"PATH+MATLAB=$matlabroot/bin\"]) { \n" - + " echo env.PATH \n" - + " runMATLABTests(testResultsPDF:'myresult/result.pdf')}}", true)); + + " def matlabroot \n" + + " matlabroot = tool 'R2018b' \n" + + " withEnv([\"PATH+MATLAB=$matlabroot/bin\"]) { \n" + + " echo env.PATH \n" + + " runMATLABTests(testResultsPDF:'myresult/result.pdf')}}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("versioninfo", build); jenkins.assertLogContains("2018b", build); jenkins.assertLogContains("bin", build); } + /* * Test to verify usage of MATLAB tool installation in freestyle project. - * */ + */ @Test public void verifyInstallationInFreeStyle() throws Exception { URL url = MatlabInstallationTest.class.getClassLoader().getResource("versioninfo" + FileSeperator + "R2018a"); @@ -185,7 +186,8 @@ public void verifyInstallationInMatrixBuild() throws Exception { /* * @Integ Test * Paths should point to MATLAB executable - * Test to verify correct MATLAB installation is added to PATH environment variable + * Test to verify correct MATLAB installation is added to PATH environment + * variable */ public void verifyInstallationPathVarInMatrixBuild() throws Exception { diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTest.java b/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTest.java index 69b6ee44..9810988c 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTest.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTest.java @@ -50,9 +50,9 @@ public class RunMatlabBuildBuilderTest { @Rule public JenkinsRule jenkins = new JenkinsRule(); - + @Rule - public Timeout globalTimeout = Timeout.seconds(500); + public Timeout globalTimeout = Timeout.seconds(500); @BeforeClass public static void classSetup() throws URISyntaxException, IOException { @@ -62,6 +62,7 @@ public static void classSetup() throws URISyntaxException, IOException { url = classLoader.getResource("com/mathworks/ci/linux/bin/matlab.sh"); try { matlabExecutorAbsolutePath = new File(url.toURI()).getAbsolutePath(); + System.out.println("THE EXECUTOR PATH IS" + matlabExecutorAbsolutePath); // Need to do this operation due to bug in maven Resource copy plugin [ // https://issues.apache.org/jira/browse/MRESOURCES-132 ] @@ -124,13 +125,13 @@ public void verifyBuildStepWithRunMatlab() throws Exception { Assert.assertTrue("Build step does not contain Run MATLAB Build option", found); } - /* * Test to verify MATLAB is launched using the default MATLAB runner script. */ @Test public void verifyMATLABlaunchedWithDefaultArguments() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(this.scriptBuilder); @@ -143,7 +144,8 @@ public void verifyMATLABlaunchedWithDefaultArguments() throws Exception { */ @Test public void verifyMATLABlaunchedfromWorkspace() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(this.scriptBuilder); @@ -153,11 +155,13 @@ public void verifyMATLABlaunchedfromWorkspace() throws Exception { } /* - * Test to verify job fails when invalid MATLAB path is provided and Exception is thrown + * Test to verify job fails when invalid MATLAB path is provided and Exception + * is thrown */ @Test public void verifyBuilderFailsForInvalidMATLABPath() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), "/fake/matlabroot/that/does/not/exist")); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), "/fake/matlabroot/that/does/not/exist")); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(this.scriptBuilder); @@ -170,10 +174,11 @@ public void verifyBuilderFailsForInvalidMATLABPath() throws Exception { */ @Test public void verifyBuildFailureWhenMatlabBuildFails() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); - RunMatlabBuildBuilderTester tester = - new RunMatlabBuildBuilderTester(matlabExecutorAbsolutePath, "-positiveFail"); + RunMatlabBuildBuilderTester tester = new RunMatlabBuildBuilderTester(matlabExecutorAbsolutePath, + "-positiveFail"); scriptBuilder.setTasks(""); project.getBuildersList().add(tester); FreeStyleBuild build = project.scheduleBuild2(0).get(); @@ -185,10 +190,10 @@ public void verifyBuildFailureWhenMatlabBuildFails() throws Exception { */ @Test public void verifyBuildPassesWhenMatlabBuildPasses() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); - RunMatlabBuildBuilderTester tester = - new RunMatlabBuildBuilderTester(matlabExecutorAbsolutePath, "-positive"); + RunMatlabBuildBuilderTester tester = new RunMatlabBuildBuilderTester(matlabExecutorAbsolutePath, "-positive"); scriptBuilder.setTasks(""); project.getBuildersList().add(tester); FreeStyleBuild build = project.scheduleBuild2(0).get(); @@ -201,7 +206,8 @@ public void verifyBuildPassesWhenMatlabBuildPasses() throws Exception { */ @Test public void verifyBuildPicksTheCorrectBuildBatch() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks("compile"); project.getBuildersList().add(this.scriptBuilder); @@ -216,7 +222,8 @@ public void verifyBuildPicksTheCorrectBuildBatch() throws Exception { */ @Test public void verifyBuildPicksTheCorrectStartupOptions() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); scriptBuilder.setStartupOptions(new StartupOptions("-nojvm -uniqueoption")); @@ -231,7 +238,8 @@ public void verifyBuildPicksTheCorrectStartupOptions() throws Exception { */ @Test public void verifyBuildPicksTheCorrectBuildOptions() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); scriptBuilder.setBuildOptions(new BuildOptions("-continueOnFailure -skip compile")); @@ -242,11 +250,13 @@ public void verifyBuildPicksTheCorrectBuildOptions() throws Exception { } /* - * Test to verify if MATLAB scratch file is not generated in workspace for this builder. + * Test to verify if MATLAB scratch file is not generated in workspace for this + * builder. */ @Test public void verifyMATLABscratchFileNotGenerated() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(this.scriptBuilder); @@ -254,9 +264,10 @@ public void verifyMATLABscratchFileNotGenerated() throws Exception { File matlabRunner = new File(build.getWorkspace() + File.separator + "runMatlabTests.m"); Assert.assertFalse(matlabRunner.exists()); } - + /* - * Test to verify build supports resolving environment variable (For matrix builds). + * Test to verify build supports resolving environment variable (For matrix + * builds). */ @Test public void verifyBuildSupportsEnvVar() throws Exception { @@ -265,7 +276,8 @@ public void verifyBuildSupportsEnvVar() throws Exception { var.put("TASKS", "compile"); var.put("BUILD_OPTIONS", "-continueOnFailure -skip test"); jenkins.jenkins.getGlobalNodeProperties().add(prop); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks("$TASKS"); scriptBuilder.setBuildOptions(new BuildOptions("$BUILD_OPTIONS")); @@ -274,86 +286,98 @@ public void verifyBuildSupportsEnvVar() throws Exception { jenkins.assertLogContains("compile", build); jenkins.assertLogContains("-continueOnFailure -skip test", build); } - + /* * Test to verify if appropriate MATLAB runner file is copied in workspace. * - * NOTE: This test assumes there is no MATLAB installed and is not on System Path. + * NOTE: This test assumes there is no MATLAB installed and is not on System + * Path. * */ @Test public void verifyMATLABrunnerFileGenerated() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(scriptBuilder); FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("run-matlab-command", build); } - + /* * Verify default MATLAB is not picked if invalid MATLAB path is provided */ @Test public void verifyDefaultMatlabNotPicked() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2020b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2020b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setTasks(""); project.getBuildersList().add(scriptBuilder); FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("MatlabNotFoundError", build); } - - /* - * Test to verify if Matrix build fails when MATLAB is not available. - * - * NOTE: This test assumes there is no MATLAB installed and is not on System Path. + + /* + * Test to verify if Matrix build fails when MATLAB is not available. + * + * NOTE: This test assumes there is no MATLAB installed and is not on System + * Path. * - */ - @Test - public void verifyMatrixBuildFails() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); - Axis axes = new Axis("VERSION", "R2018a", "R2015b"); - matrixProject.setAxes(new AxisList(axes)); - String matlabRoot = getMatlabroot("R2018b"); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); - matrixProject.getBuildWrappersList().add(this.buildWrapper); - - scriptBuilder.setTasks(""); - matrixProject.getBuildersList().add(scriptBuilder); - Map vals = new HashMap(); - vals.put("VERSION", "R2018a"); - Combination c1 = new Combination(vals); - MatrixRun build = matrixProject.scheduleBuild2(0).get().getRun(c1); - jenkins.assertLogContains("buildtool", build); - jenkins.assertBuildStatus(Result.FAILURE, build); - vals.put("VERSION", "R2015b"); - Combination c2 = new Combination(vals); - MatrixRun build2 = matrixProject.scheduleBuild2(0).get().getRun(c2); - jenkins.assertLogContains("MatlabNotFoundError", build2); - jenkins.assertBuildStatus(Result.FAILURE, build2); - } - - /* - * Test to verify if Matrix build passes (mock MATLAB). - */ - @Test - public void verifyMatrixBuildPasses() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); - Axis axes = new Axis("VERSION", "R2018a", "R2018b"); - matrixProject.setAxes(new AxisList(axes)); - String matlabRoot = getMatlabroot("R2018b"); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); - matrixProject.getBuildWrappersList().add(this.buildWrapper); - RunMatlabBuildBuilderTester tester = new RunMatlabBuildBuilderTester(matlabExecutorAbsolutePath, - "-positive"); - - tester.setTasks(""); - matrixProject.getBuildersList().add(tester); - MatrixBuild build = matrixProject.scheduleBuild2(0).get(); - - jenkins.assertLogContains("R2018a completed", build); - jenkins.assertLogContains("R2018b completed", build); - jenkins.assertBuildStatus(Result.SUCCESS, build); - } + */ + @Test + public void verifyMatrixBuildFails() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); + Axis axes = new Axis("VERSION", "R2018a", "R2015b"); + matrixProject.setAxes(new AxisList(axes)); + String matlabRoot = getMatlabroot("R2018b"); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); + matrixProject.getBuildWrappersList().add(this.buildWrapper); + + scriptBuilder.setTasks(""); + matrixProject.getBuildersList().add(scriptBuilder); + + // Check for first matrix combination. + Map vals = new HashMap(); + vals.put("VERSION", "R2018a"); + Combination c1 = new Combination(vals); + MatrixRun build1 = matrixProject.scheduleBuild2(0).get().getRun(c1); + + jenkins.assertLogContains("buildtool", build1); + jenkins.assertBuildStatus(Result.FAILURE, build1); + + // Check for second Matrix combination + vals.put("VERSION", "R2015b"); + Combination c2 = new Combination(vals); + MatrixRun build2 = matrixProject.scheduleBuild2(0).get().getRun(c2); + + jenkins.assertLogContains("MatlabNotFoundError", build2); + jenkins.assertBuildStatus(Result.FAILURE, build2); + } + + /* + * Test to verify if Matrix build passes (mock MATLAB). + */ + @Test + public void verifyMatrixBuildPasses() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); + Axis axes = new Axis("VERSION", "R2018a", "R2018b"); + matrixProject.setAxes(new AxisList(axes)); + String matlabRoot = getMatlabroot("R2018b"); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); + matrixProject.getBuildWrappersList().add(this.buildWrapper); + RunMatlabBuildBuilderTester tester = new RunMatlabBuildBuilderTester(matlabExecutorAbsolutePath, + "-positive"); + + tester.setTasks(""); + matrixProject.getBuildersList().add(tester); + MatrixBuild build = matrixProject.scheduleBuild2(0).get(); + + jenkins.assertLogContains("R2018a completed", build); + jenkins.assertLogContains("R2018b completed", build); + jenkins.assertBuildStatus(Result.SUCCESS, build); + } } diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTester.java b/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTester.java index a52fb244..158daacc 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTester.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabBuildBuilderTester.java @@ -1,8 +1,7 @@ package com.mathworks.ci; /** - * Copyright 2022 The MathWorks, Inc. - * + * Copyright 2022-2024 The MathWorks, Inc. */ import java.io.IOException; @@ -38,14 +37,12 @@ public RunMatlabBuildBuilderTester(String matlabExecutorPath, String customTestP this.matlabExecutorPath = matlabExecutorPath; } - // Getter and Setters to access local members private void setEnv(EnvVars env) { this.env = env; } - @Extension public static class Desriptor extends BuildStepDescriptor { @Override @@ -93,13 +90,7 @@ private int execMatlabCommand(FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException { ProcStarter matlabLauncher; try { - matlabLauncher = launcher.launch().pwd(workspace).envs(this.env); - if (matlabRel.verLessThan(MatlabBuilderConstants.BASE_MATLAB_VERSION_BATCH_SUPPORT)) { - ListenerLogDecorator outStream = new ListenerLogDecorator(listener); - matlabLauncher = matlabLauncher.cmds(testMatlabBuild()).stderr(outStream); - } else { - matlabLauncher = matlabLauncher.cmds(testMatlabBuild()).stdout(listener); - } + matlabLauncher = launcher.launch().pwd(workspace).envs(this.env).cmds(testMatlabBuild()).stdout(listener); } catch (Exception e) { listener.getLogger().println(e.getMessage()); @@ -116,4 +107,3 @@ private List testMatlabBuild() { return matlabDefaultArgs; } } - diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabBuildStepTest.java b/src/test/java/integ/com/mathworks/ci/RunMatlabBuildStepTest.java index 8deb0ca0..fa141756 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabBuildStepTest.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabBuildStepTest.java @@ -32,7 +32,6 @@ public void testSetup() throws IOException { this.project = j.createProject(WorkflowJob.class); } - /* * Verify when MATLAB is not on system path. */ @@ -51,7 +50,7 @@ public void verifyMATLABPathNotSet() throws Exception { public void verifyMATLABstartsInWorkspace() throws Exception { DumbSlave s = j.createOnlineSlave(); project.setDefinition( - new CpsFlowDefinition("node('!master') { runMATLABBuild() }", true)); + new CpsFlowDefinition("node('!built-in') { runMATLABBuild() }", true)); FilePath workspace = s.getWorkspaceFor(project); String workspaceName = workspace.getName(); @@ -65,10 +64,10 @@ public void verifyMATLABstartsInWorkspace() throws Exception { */ // @Test // public void verifyMATLABPathSet() throws Exception { - // project.setDefinition( - // new CpsFlowDefinition("node { runMATLABBuild() }", true)); - // WorkflowRun build = project.scheduleBuild2(0).get(); - // j.assertLogContains("tester_started", build); + // project.setDefinition( + // new CpsFlowDefinition("node { runMATLABBuild() }", true)); + // WorkflowRun build = project.scheduleBuild2(0).get(); + // j.assertLogContains("tester_started", build); // } /* @@ -78,7 +77,7 @@ public void verifyMATLABstartsInWorkspace() throws Exception { public void verifyPipelineOnSlave() throws Exception { DumbSlave s = j.createOnlineSlave(); project.setDefinition(new CpsFlowDefinition( - "node('!master') { runMATLABBuild() }", true)); + "node('!built-in') { runMATLABBuild() }", true)); s.getWorkspaceFor(project); WorkflowRun build = project.scheduleBuild2(0).get(); @@ -128,7 +127,8 @@ public void verifyStartupOptionsSameAsScript() throws Exception { @Test public void verifyBuildOptionsSameAsScript() throws Exception { project.setDefinition( - new CpsFlowDefinition("node { runMATLABBuild(buildOptions: '-continueOnFailure -skip compile') }", true)); + new CpsFlowDefinition("node { runMATLABBuild(buildOptions: '-continueOnFailure -skip compile') }", + true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("-continueOnFailure -skip compile", build); @@ -150,8 +150,8 @@ public void verifyMatrixBuild() throws Exception { } /* - * Test for verifying Run Matlab Build raises exception for non-zero exit code. - * */ + * Test for verifying Run Matlab Build raises exception for non-zero exit code. + */ @Test public void verifyExceptionForNonZeroExitCode() throws Exception { // exitMatlab is a mock build for run_matlab_build script to exit with 1. diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTest.java b/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTest.java index cf28cbed..8b7bbc56 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTest.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTest.java @@ -7,9 +7,9 @@ * */ -import com.gargoylesoftware.htmlunit.WebAssert; -import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput; -import com.gargoylesoftware.htmlunit.html.HtmlPage; +import org.htmlunit.WebAssert; +import org.htmlunit.html.HtmlCheckBoxInput; +import org.htmlunit.html.HtmlPage; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; @@ -54,9 +54,9 @@ public class RunMatlabCommandBuilderTest { @Rule public JenkinsRule jenkins = new JenkinsRule(); - + @Rule - public Timeout globalTimeout = Timeout.seconds(500); + public Timeout globalTimeout = Timeout.seconds(500); @BeforeClass public static void classSetup() throws URISyntaxException, IOException { @@ -130,7 +130,6 @@ public void verifyBuildStepWithRunMatlab() throws Exception { Assert.assertTrue("Build step does not contain Run MATLAB Command option", found); } - /* * Test To verify MATLAB is launched using the default matlab runner binary. * @@ -138,7 +137,8 @@ public void verifyBuildStepWithRunMatlab() throws Exception { @Test public void verifyMATLABlaunchedWithDefaultArguments() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(this.scriptBuilder); @@ -153,7 +153,8 @@ public void verifyMATLABlaunchedWithDefaultArguments() throws Exception { @Test public void verifyMATLABlaunchedfromWorkspace() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(this.scriptBuilder); @@ -163,12 +164,14 @@ public void verifyMATLABlaunchedfromWorkspace() throws Exception { } /* - * Test to verify if job fails when invalid MATLAB path is provided and Exception is thrown + * Test to verify if job fails when invalid MATLAB path is provided and + * Exception is thrown */ @Test public void verifyBuilderFailsForInvalidMATLABPath() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), "/fake/matlabroot/that/does/not/exist")); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), "/fake/matlabroot/that/does/not/exist")); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(this.scriptBuilder); @@ -182,10 +185,11 @@ public void verifyBuilderFailsForInvalidMATLABPath() throws Exception { @Test public void verifyBuildFailureWhenMatlabCommandFails() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); - RunMatlabCommandBuilderTester tester = - new RunMatlabCommandBuilderTester(matlabExecutorAbsolutePath, "-positiveFail"); + RunMatlabCommandBuilderTester tester = new RunMatlabCommandBuilderTester(matlabExecutorAbsolutePath, + "-positiveFail"); tester.setMatlabCommand("pp"); project.getBuildersList().add(tester); FreeStyleBuild build = project.scheduleBuild2(0).get(); @@ -198,10 +202,11 @@ public void verifyBuildFailureWhenMatlabCommandFails() throws Exception { @Test public void verifyBuildPassesWhenMatlabCommandPasses() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); - RunMatlabCommandBuilderTester tester = - new RunMatlabCommandBuilderTester(matlabExecutorAbsolutePath, "-positive"); + RunMatlabCommandBuilderTester tester = new RunMatlabCommandBuilderTester(matlabExecutorAbsolutePath, + "-positive"); tester.setMatlabCommand("pwd"); project.getBuildersList().add(tester); FreeStyleBuild build = project.scheduleBuild2(0).get(); @@ -216,7 +221,8 @@ public void verifyBuildPassesWhenMatlabCommandPasses() throws Exception { @Test public void verifyBuildPicksTheCorretCommandBatch() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(this.scriptBuilder); @@ -233,7 +239,8 @@ public void verifyBuildPicksTheCorretCommandBatch() throws Exception { @Test public void verifyBuildPicksTheCorrectStartupOptions() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); scriptBuilder.setStartupOptions(new StartupOptions("-nojvm -uniqueoption")); @@ -246,11 +253,13 @@ public void verifyBuildPicksTheCorrectStartupOptions() throws Exception { } /* - * Test to verify if MATALB scratch file is not generated in workspace for this builder. + * Test to verify if MATALB scratch file is not generated in workspace for this + * builder. */ @Test public void verifyMATLABscratchFileNotGenerated() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(this.scriptBuilder); @@ -258,9 +267,10 @@ public void verifyMATLABscratchFileNotGenerated() throws Exception { File matlabRunner = new File(build.getWorkspace() + File.separator + "runMatlabTests.m"); Assert.assertFalse(matlabRunner.exists()); } - + /* - * Test to verify command supports resolving environment variable (For MATRIX builds). + * Test to verify command supports resolving environment variable (For MATRIX + * builds). * */ @Test @@ -269,108 +279,112 @@ public void verifyCommandSupportsEnvVar() throws Exception { EnvVars var = prop.getEnvVars(); var.put("PWDCMD", "pwd"); jenkins.jenkins.getGlobalNodeProperties().add(prop); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("$PWDCMD"); project.getBuildersList().add(scriptBuilder); FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("pwd", build); } - + /* * Test to verify if appropriate MATALB runner file is copied in workspace. * - * NOTE: This test assumes there is no MATLAB installed and is not on System Path. + * NOTE: This test assumes there is no MATLAB installed and is not on System + * Path. * */ @Test public void verifyMATLABrunnerFileGenerated() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(scriptBuilder); FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("run-matlab-command", build); } - + /* * Verify default MATLAB is not picked if invalid MATLAB path is provided */ @Test public void verifyDefaultMatlabNotPicked() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2020b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2020b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("pwd"); project.getBuildersList().add(scriptBuilder); FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("MatlabNotFoundError", build); } - - /* - * Test to verify if Matrix build fails when MATLAB is not available. + + /* + * Test to verify if Matrix build fails when MATLAB is not available. * - * NOTE: This test assumes there is no MATLAB installed and is not on System Path. + * NOTE: This test assumes there is no MATLAB installed and is not on System + * Path. * - */ - @Test - public void verifyMatrixBuildFails() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); - Axis axes = new Axis("VERSION", "R2018a", "R2015b"); - matrixProject.setAxes(new AxisList(axes)); - String matlabRoot = getMatlabroot("R2018b"); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); - matrixProject.getBuildWrappersList().add(this.buildWrapper); - - scriptBuilder.setMatlabCommand("pwd"); - matrixProject.getBuildersList().add(scriptBuilder); - Map vals = new HashMap(); - vals.put("VERSION", "R2018a"); - Combination c1 = new Combination(vals); - MatrixRun build = matrixProject.scheduleBuild2(0).get().getRun(c1); - jenkins.assertLogContains("run-matlab-command", build); - jenkins.assertBuildStatus(Result.FAILURE, build); - vals.put("VERSION", "R2015b"); - Combination c2 = new Combination(vals); - MatrixRun build2 = matrixProject.scheduleBuild2(0).get().getRun(c2); - jenkins.assertLogContains("MatlabNotFoundError", build2); - jenkins.assertBuildStatus(Result.FAILURE, build2); - } - - /* - * Test to verify if Matrix build passes (mock MATLAB). - */ - @Test - public void verifyMatrixBuildPasses() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); - Axis axes = new Axis("VERSION", "R2018a", "R2018b"); - matrixProject.setAxes(new AxisList(axes)); - String matlabRoot = getMatlabroot("R2018b"); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); - matrixProject.getBuildWrappersList().add(this.buildWrapper); - RunMatlabCommandBuilderTester tester = new RunMatlabCommandBuilderTester(matlabExecutorAbsolutePath, - "-positive"); - - tester.setMatlabCommand("pwd"); - matrixProject.getBuildersList().add(tester); - MatrixBuild build = matrixProject.scheduleBuild2(0).get(); - - jenkins.assertLogContains("R2018a completed", build); - jenkins.assertLogContains("R2018b completed", build); - jenkins.assertBuildStatus(Result.SUCCESS, build); - } - - /* - * Test to verify if command parses succesfully when multiple combinations of - * characters are passed. (candidate for integ-tests once integrated) */ + @Test + public void verifyMatrixBuildFails() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); + Axis axes = new Axis("VERSION", "R2018a", "R2015b"); + matrixProject.setAxes(new AxisList(axes)); + String matlabRoot = getMatlabroot("R2018b"); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); + matrixProject.getBuildWrappersList().add(this.buildWrapper); + + scriptBuilder.setMatlabCommand("pwd"); + matrixProject.getBuildersList().add(scriptBuilder); + Map vals = new HashMap(); + vals.put("VERSION", "R2018a"); + Combination c1 = new Combination(vals); + MatrixRun build = matrixProject.scheduleBuild2(0).get().getRun(c1); + jenkins.assertLogContains("run-matlab-command", build); + jenkins.assertBuildStatus(Result.FAILURE, build); + vals.put("VERSION", "R2015b"); + Combination c2 = new Combination(vals); + MatrixRun build2 = matrixProject.scheduleBuild2(0).get().getRun(c2); + jenkins.assertLogContains("MatlabNotFoundError", build2); + jenkins.assertBuildStatus(Result.FAILURE, build2); + } - + /* + * Test to verify if Matrix build passes (mock MATLAB). + */ + @Test + public void verifyMatrixBuildPasses() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); + Axis axes = new Axis("VERSION", "R2018a", "R2018b"); + matrixProject.setAxes(new AxisList(axes)); + String matlabRoot = getMatlabroot("R2018b"); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); + matrixProject.getBuildWrappersList().add(this.buildWrapper); + RunMatlabCommandBuilderTester tester = new RunMatlabCommandBuilderTester(matlabExecutorAbsolutePath, + "-positive"); + + tester.setMatlabCommand("pwd"); + matrixProject.getBuildersList().add(tester); + MatrixBuild build = matrixProject.scheduleBuild2(0).get(); + + jenkins.assertLogContains("R2018a completed", build); + jenkins.assertLogContains("R2018b completed", build); + jenkins.assertBuildStatus(Result.SUCCESS, build); + } + + /* + * Test to verify if command parses succesfully when multiple combinations of + * characters are passed. (candidate for integ-tests once integrated) + */ public void verifyMultispecialChar() throws Exception { - final String actualCommand = - "!\"\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; - final String expectedCommand = - "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + final String actualCommand = "!\"\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; + final String expectedCommand = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); scriptBuilder.setMatlabCommand("disp(" + actualCommand + ")"); @@ -384,15 +398,15 @@ public void verifyMultispecialChar() throws Exception { /* * Test to verify error message when command is empty. */ - @Test public void verifyErrorMessageOnEmptyCommand() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); project.getBuildersList().add(this.scriptBuilder); HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - WebAssert.assertTextPresent(page,"Specify at least one script, function, or statement to execute."); + WebAssert.assertTextPresent(page, "Specify at least one script, function, or statement to execute."); } /* @@ -401,13 +415,14 @@ public void verifyErrorMessageOnEmptyCommand() throws Exception { @Test public void verifyWhenCommandNonEmpty() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2017a"))); project.getBuildWrappersList().add(this.buildWrapper); this.scriptBuilder.setMatlabCommand("NONEMPTY"); project.getBuildersList().add(this.scriptBuilder); HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - WebAssert.assertTextNotPresent(page,"Specify at least one script, function, or statement to execute."); + WebAssert.assertTextNotPresent(page, "Specify at least one script, function, or statement to execute."); } } diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTester.java b/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTester.java index 8236c85d..f67fa0ec 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTester.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabCommandBuilderTester.java @@ -39,14 +39,12 @@ public RunMatlabCommandBuilderTester(String matlabExecutorPath, String customTes this.matlabExecutorPath = matlabExecutorPath; } - // Getter and Setters to access local members private void setEnv(EnvVars env) { this.env = env; } - @Extension public static class Desriptor extends BuildStepDescriptor { @Override @@ -94,13 +92,7 @@ private int execMatlabCommand(FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException { ProcStarter matlabLauncher; try { - matlabLauncher = launcher.launch().pwd(workspace).envs(this.env); - if (matlabRel.verLessThan(MatlabBuilderConstants.BASE_MATLAB_VERSION_BATCH_SUPPORT)) { - ListenerLogDecorator outStream = new ListenerLogDecorator(listener); - matlabLauncher = matlabLauncher.cmds(testMatlabCommand()).stderr(outStream); - } else { - matlabLauncher = matlabLauncher.cmds(testMatlabCommand()).stdout(listener); - } + matlabLauncher = launcher.launch().pwd(workspace).envs(this.env).cmds(testMatlabCommand()).stdout(listener); } catch (Exception e) { listener.getLogger().println(e.getMessage()); @@ -117,4 +109,3 @@ private List testMatlabCommand() { return matlabDefaultArgs; } } - diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabCommandStepTest.java b/src/test/java/integ/com/mathworks/ci/RunMatlabCommandStepTest.java index 66c8e834..47181cea 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabCommandStepTest.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabCommandStepTest.java @@ -1,7 +1,7 @@ package com.mathworks.ci.pipeline; + /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -50,7 +50,7 @@ public void verifyMATLABPathNotSet() throws Exception { public void verifyMATLABstartsInWorkspace() throws Exception { DumbSlave s = j.createOnlineSlave(); project.setDefinition( - new CpsFlowDefinition("node('!master') { runMATLABCommand(command: 'pwd')}", true)); + new CpsFlowDefinition("node('!built-in') { runMATLABCommand(command: 'pwd')}", true)); FilePath workspace = s.getWorkspaceFor(project); String workspaceName = workspace.getName(); @@ -66,10 +66,10 @@ public void verifyMATLABstartsInWorkspace() throws Exception { // @Test // public void verifyMATLABPathSet() throws Exception { - // project.setDefinition( - // new CpsFlowDefinition("node { runMATLABCommand(command: 'pwd')}", true)); - // WorkflowRun build = project.scheduleBuild2(0).get(); - // j.assertLogContains("tester_started", build); + // project.setDefinition( + // new CpsFlowDefinition("node { runMATLABCommand(command: 'pwd')}", true)); + // WorkflowRun build = project.scheduleBuild2(0).get(); + // j.assertLogContains("tester_started", build); // } /* @@ -81,7 +81,7 @@ public void verifyMATLABstartsInWorkspace() throws Exception { public void verifyPipelineOnSlave() throws Exception { DumbSlave s = j.createOnlineSlave(); project.setDefinition(new CpsFlowDefinition( - "node('!master') { runMATLABCommand(command: 'pwd')}", true)); + "node('!built-in') { runMATLABCommand(command: 'pwd')}", true)); s.getWorkspaceFor(project); WorkflowRun build = project.scheduleBuild2(0).get(); @@ -112,7 +112,8 @@ public void verifyCommandSameAsScript() throws Exception { @Test public void verifyStartupOptionsSameAsScript() throws Exception { project.setDefinition( - new CpsFlowDefinition("node { runMATLABCommand(command: 'pwd', startupOptions: '-nojvm -uniqueoption')}", true)); + new CpsFlowDefinition( + "node { runMATLABCommand(command: 'pwd', startupOptions: '-nojvm -uniqueoption')}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("-nojvm -uniqueoption", build); @@ -136,13 +137,16 @@ public void verifyMatrixBuild() throws Exception { } /* - * Test for verifying Run Matlab Command raises exception for non-zero exit code. - * */ + * Test for verifying Run Matlab Command raises exception for non-zero exit + * code. + */ @Test public void verifyExceptionForNonZeroExitCode() throws Exception { // exitMatlab is a mock command for run_matlab_command script to exit with 1. project.setDefinition( - new CpsFlowDefinition("node { try {runMATLABCommand(command: 'exitMatlab')}catch(exc){echo exc.getMessage()}}", true)); + new CpsFlowDefinition( + "node { try {runMATLABCommand(command: 'exitMatlab')}catch(exc){echo exc.getMessage()}}", + true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains(String.format(Message.getValue("matlab.execution.exception.prefix"), 1), build); diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabTestBuilderPersistenceTest.java b/src/test/java/integ/com/mathworks/ci/RunMatlabTestBuilderPersistenceTest.java index 4ed50ce3..bb0eb6ef 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabTestBuilderPersistenceTest.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabTestBuilderPersistenceTest.java @@ -4,7 +4,6 @@ * Copyright 2020-2024 The MathWorks, Inc. * * Test class for RunMatlabTestsBuilder Persistence - * */ import hudson.model.FreeStyleProject; @@ -42,8 +41,8 @@ private boolean areSourcePathsEqual(List listA, List vals = new HashMap(); - vals.put("VERSION", "R2018a"); - Combination c1 = new Combination(vals); - MatrixRun build1 = matrixProject.scheduleBuild2(0).get().getRun(c1); - - jenkins.assertLogContains("run-matlab-command", build1); - jenkins.assertBuildStatus(Result.FAILURE, build1); - - // Check for second Matrix combination - - vals.put("VERSION", "R2015b"); - Combination c2 = new Combination(vals); - MatrixRun build2 = matrixProject.scheduleBuild2(0).get().getRun(c2); - - jenkins.assertLogContains("MatlabNotFoundError", build2); - jenkins.assertBuildStatus(Result.FAILURE, build2); - } - - /* - * Test to verify if Matrix build passes (mock MATLAB). - */ - @Test - public void verifyMatrixBuildPasses() throws Exception { - MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); - Axis axes = new Axis("VERSION", "R2018a", "R2018b"); - matrixProject.setAxes(new AxisList(axes)); - String matlabRoot = getMatlabroot("R2018b"); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); - matrixProject.getBuildWrappersList().add(this.buildWrapper); - RunMatlabTestsBuilderTester tester = new RunMatlabTestsBuilderTester(matlabExecutorAbsolutePath, "-positive"); - - matrixProject.getBuildersList().add(tester); - MatrixBuild build = matrixProject.scheduleBuild2(0).get(); - - jenkins.assertLogContains("Triggering", build); - jenkins.assertLogContains("R2018a completed", build); - jenkins.assertLogContains("R2018b completed", build); - jenkins.assertBuildStatus(Result.SUCCESS, build); - } - - /* + */ + @Test + public void verifyMatrixBuildFails() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); + Axis axes = new Axis("VERSION", "R2018a", "R2015b"); + matrixProject.setAxes(new AxisList(axes)); + String matlabRoot = getMatlabroot("R2018b"); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); + matrixProject.getBuildWrappersList().add(this.buildWrapper); + + matrixProject.getBuildersList().add(testBuilder); + + // Check for first matrix combination. + + Map vals = new HashMap(); + vals.put("VERSION", "R2018a"); + Combination c1 = new Combination(vals); + MatrixRun build1 = matrixProject.scheduleBuild2(0).get().getRun(c1); + + jenkins.assertLogContains("run-matlab-command", build1); + jenkins.assertBuildStatus(Result.FAILURE, build1); + + // Check for second Matrix combination + vals.put("VERSION", "R2015b"); + Combination c2 = new Combination(vals); + MatrixRun build2 = matrixProject.scheduleBuild2(0).get().getRun(c2); + + jenkins.assertLogContains("MatlabNotFoundError", build2); + jenkins.assertBuildStatus(Result.FAILURE, build2); + } + + /* + * Test to verify if Matrix build passes (mock MATLAB). + */ + @Test + public void verifyMatrixBuildPasses() throws Exception { + MatrixProject matrixProject = jenkins.createProject(MatrixProject.class); + Axis axes = new Axis("VERSION", "R2018a", "R2018b"); + matrixProject.setAxes(new AxisList(axes)); + String matlabRoot = getMatlabroot("R2018b"); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), matlabRoot.replace("R2018b", "$VERSION"))); + matrixProject.getBuildWrappersList().add(this.buildWrapper); + RunMatlabTestsBuilderTester tester = new RunMatlabTestsBuilderTester(matlabExecutorAbsolutePath, "-positive"); + + matrixProject.getBuildersList().add(tester); + MatrixBuild build = matrixProject.scheduleBuild2(0).get(); + + jenkins.assertLogContains("Triggering", build); + jenkins.assertLogContains("R2018a completed", build); + jenkins.assertLogContains("R2018b completed", build); + jenkins.assertBuildStatus(Result.SUCCESS, build); + } + + /* * Test to verify if MATALB scratch file is not in workspace. */ @Test public void verifyMATLABscratchFileGenerated() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); project.getBuildWrappersList().add(this.buildWrapper); project.getBuildersList().add(testBuilder); FreeStyleBuild build = project.scheduleBuild2(0).get(); File matlabRunner = new File(build.getWorkspace() + File.separator + "runnerScript.m"); Assert.assertFalse(matlabRunner.exists()); } - + /* * Test to verify Use Parallel check box present. */ - @Test - public void verifyUseParallelPresent() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); - project.getBuildWrappersList().add(this.buildWrapper); - project.getBuildersList().add(this.testBuilder); - HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - WebAssert.assertElementPresentByXPath(page, "//input[@name=\"_.useParallel\"]"); - } - - /* - * Test to verify Strict check box present. - */ - - @Test - public void verifyStrictPresent() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); - project.getBuildWrappersList().add(this.buildWrapper); - project.getBuildersList().add(this.testBuilder); - HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - WebAssert.assertElementPresentByXPath(page, "//input[@name=\"_.strict\"]"); - } - - /* - * Test to verify Logging Level is present. - */ - - @Test - public void verifyLoggingLevelPresent() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); - project.getBuildWrappersList().add(this.buildWrapper); - project.getBuildersList().add(this.testBuilder); - HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - WebAssert.assertElementPresentByXPath(page, "//select[@name=\"_.loggingLevel\"]"); - } - - /* - * Test to verify Output Detail is present. - */ - - @Test - public void verifyOutputDetailPresent() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); - project.getBuildWrappersList().add(this.buildWrapper); - project.getBuildersList().add(this.testBuilder); - HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - WebAssert.assertElementPresentByXPath(page, "//select[@name=\"_.outputDetail\"]"); - } - - /* - * Test to verify Logging Level set to default - */ - - @Test - public void verifyLoggingLevelSetToDefault() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); - project.getBuildWrappersList().add(this.buildWrapper); - project.getBuildersList().add(this.testBuilder); - HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - HtmlSelect loggingLevel = page.getElementByName("_.loggingLevel"); - assertEquals("default", loggingLevel.getAttribute("value")); - } - - /* - * Test to verify Output Detail set to default - */ - - @Test - public void verifyOutputDetailSetToDefault() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); - project.getBuildWrappersList().add(this.buildWrapper); - project.getBuildersList().add(this.testBuilder); - HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); - HtmlSelect outputDetail = page.getElementByName("_.outputDetail"); - assertEquals("default", outputDetail.getAttribute("value")); - } - - + @Test + public void verifyUseParallelPresent() throws Exception { + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + project.getBuildWrappersList().add(this.buildWrapper); + project.getBuildersList().add(this.testBuilder); + HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); + WebAssert.assertElementPresentByXPath(page, "//input[@name=\"_.useParallel\"]"); + } + + /* + * Test to verify Strict check box present. + */ + + @Test + public void verifyStrictPresent() throws Exception { + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + project.getBuildWrappersList().add(this.buildWrapper); + project.getBuildersList().add(this.testBuilder); + HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); + WebAssert.assertElementPresentByXPath(page, "//input[@name=\"_.strict\"]"); + } + + /* + * Test to verify Logging Level is present. + */ + + @Test + public void verifyLoggingLevelPresent() throws Exception { + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + project.getBuildWrappersList().add(this.buildWrapper); + project.getBuildersList().add(this.testBuilder); + HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); + WebAssert.assertElementPresentByXPath(page, "//select[@name=\"_.loggingLevel\"]"); + } + + /* + * Test to verify Output Detail is present. + */ + + @Test + public void verifyOutputDetailPresent() throws Exception { + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + project.getBuildWrappersList().add(this.buildWrapper); + project.getBuildersList().add(this.testBuilder); + HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); + WebAssert.assertElementPresentByXPath(page, "//select[@name=\"_.outputDetail\"]"); + } + + /* + * Test to verify Logging Level set to default + */ + + @Test + public void verifyLoggingLevelSetToDefault() throws Exception { + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + project.getBuildWrappersList().add(this.buildWrapper); + project.getBuildersList().add(this.testBuilder); + HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); + HtmlSelect loggingLevel = page.getElementByName("_.loggingLevel"); + assertEquals("default", loggingLevel.getAttribute("value")); + } + + /* + * Test to verify Output Detail set to default + */ + + @Test + public void verifyOutputDetailSetToDefault() throws Exception { + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + project.getBuildWrappersList().add(this.buildWrapper); + project.getBuildersList().add(this.testBuilder); + HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); + HtmlSelect outputDetail = page.getElementByName("_.outputDetail"); + assertEquals("default", outputDetail.getAttribute("value")); + } + /* * @Integ - * Test To verify if Logging level is set correctly + * Test To verify if Logging level is set correctly * */ - public void verifyLoggingLevelSet() throws Exception { this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); @@ -592,13 +609,13 @@ public void verifyLoggingLevelSet() throws Exception { } }); } - - /*@Integ - * Test To verify if Output Detail is set correctly + + /* + * @Integ + * Test To verify if Output Detail is set correctly * */ - public void verifyOutputDetailSet() throws Exception { this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); @@ -624,12 +641,12 @@ public void verifyOutputDetailSet() throws Exception { }); } - /*@Integ + /* + * @Integ * Test To verify when Strict option set * */ - public void verifyStrictSet() throws Exception { this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); @@ -642,12 +659,12 @@ public void verifyStrictSet() throws Exception { } - /*@Integ + /* + * @Integ * Test To verify when Strict option not set * */ - public void verifyStrictNotSet() throws Exception { this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); @@ -659,13 +676,13 @@ public void verifyStrictNotSet() throws Exception { jenkins.assertLogNotContains("FailOnWarningsPlugin", build); } - - /*@Integ - * Test To verify when Run in Parallel option is set + + /* + * @Integ + * Test To verify when Run in Parallel option is set * */ - public void verifyRunParallelSet() throws Exception { this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); @@ -676,13 +693,13 @@ public void verifyRunParallelSet() throws Exception { FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("runInParallel", build); } - - /*@Integ - * Test To verify when Run in Parallel option is set + + /* + * @Integ + * Test To verify when Run in Parallel option is set * */ - public void verifyRunParallelNotSet() throws Exception { this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabTestsBuilderTester.java b/src/test/java/integ/com/mathworks/ci/RunMatlabTestsBuilderTester.java index cac180ba..0c38793b 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabTestsBuilderTester.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabTestsBuilderTester.java @@ -1,9 +1,9 @@ package com.mathworks.ci; + /** * Copyright 2019-2024 The MathWorks, Inc. * * Tester builder for RunMatlabTestsBuilder. - * */ import java.io.IOException; @@ -43,8 +43,6 @@ public class RunMatlabTestsBuilderTester extends RunMatlabTestsBuilder { private String matlabExecutorPath; private String matlabVerName; - - public RunMatlabTestsBuilderTester(String matlabExecutorPath, String customTestPointArgument) { super(); this.commandParameter = customTestPointArgument; @@ -58,7 +56,6 @@ public RunMatlabTestsBuilderTester(String customTestPointArgument) { // Getter and Setters to access local members - @DataBoundSetter public void setTapChkBx(TapArtifact tapArtifact) { this.tapArtifact = tapArtifact; @@ -139,11 +136,13 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc } /* - * This is to identify which project type in jenkins this should be applicable.(non-Javadoc) + * This is to identify which project type in jenkins this should be + * applicable.(non-Javadoc) * * @see hudson.tasks.BuildStepDescriptor#isApplicable(java.lang.Class) * - * if it returns true then this build step will be applicable for all project type. + * if it returns true then this build step will be applicable for all project + * type. */ @Override public boolean isApplicable( @@ -179,14 +178,7 @@ public int execCommand(FilePath workspace, Launcher launcher, TaskListener liste } ProcStarter matlabLauncher; try { - matlabLauncher = launcher.launch().pwd(workspace).envs(this.env); - if (this.matlabroot != null && matlabRel.verLessThan(MatlabBuilderConstants.BASE_MATLAB_VERSION_BATCH_SUPPORT)) { - ListenerLogDecorator outStream = new ListenerLogDecorator(listener); - matlabLauncher = matlabLauncher.cmds(testMatlabCommand()).stderr(outStream); - } else { - matlabLauncher = matlabLauncher.cmds(testMatlabCommand()).stdout(listener); - } - + matlabLauncher = launcher.launch().pwd(workspace).envs(this.env).cmds(testMatlabCommand()).stdout(listener); } catch (Exception e) { listener.getLogger().println(e.getMessage()); return 1; @@ -201,5 +193,4 @@ private List testMatlabCommand() { return matlabDefaultArgs; } - } diff --git a/src/test/java/integ/com/mathworks/ci/RunMatlabTestsStepTest.java b/src/test/java/integ/com/mathworks/ci/RunMatlabTestsStepTest.java index 0c49d86f..be30c713 100644 --- a/src/test/java/integ/com/mathworks/ci/RunMatlabTestsStepTest.java +++ b/src/test/java/integ/com/mathworks/ci/RunMatlabTestsStepTest.java @@ -2,7 +2,6 @@ /** * Copyright 2020-2024 The MathWorks, Inc. - * */ import java.io.IOException; @@ -33,7 +32,6 @@ public void testSetup() throws IOException { this.project = j.createProject(WorkflowJob.class); } - /* * Verify when MATLAB Path is not set */ @@ -45,9 +43,8 @@ public void verifyMATLABPathNotSet() throws Exception { j.assertLogContains("system path", build); } - /* - * VErify when MATLAB PATH is set. + * Verify when MATLAB PATH is set. */ @Test @@ -66,7 +63,7 @@ public void verifyMATLABPathSet() throws Exception { public void verifyOnslave() throws Exception { DumbSlave s = j.createOnlineSlave(); project.setDefinition(new CpsFlowDefinition( - "node('!master') {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true)); + "node('!built-in') {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true)); s.getWorkspaceFor(project); WorkflowRun build = project.scheduleBuild2(0).get(); @@ -77,7 +74,6 @@ public void verifyOnslave() throws Exception { * Verify artifact path is correct. Need to move this to integration test. */ - public void verifyArtifactPath() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true)); @@ -93,24 +89,26 @@ public void verifyArtifactPath() throws Exception { @Test public void verifyStartupOptionsSameAsScript() throws Exception { project.setDefinition( - new CpsFlowDefinition("node {runMATLABTests(testResultsPDF:'myresult/result.pdf', startupOptions: '-nojvm -uniqueoption')}", true)); + new CpsFlowDefinition( + "node {runMATLABTests(testResultsPDF:'myresult/result.pdf', startupOptions: '-nojvm -uniqueoption')}", + true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("-nojvm -uniqueoption", build); } - + /* - * Verify default command options for test run. - */ - - @Test - public void verifyCmdOptions() throws Exception { - project.setDefinition(new CpsFlowDefinition( - "node {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true)); - WorkflowRun build = project.scheduleBuild2(0).get(); - j.assertLogContains("setenv('MW_ORIG_WORKING_FOLDER',", build); - j.assertLogContains("run-matlab-command", build); - } + * Verify default command options for test run. + */ + + @Test + public void verifyCmdOptions() throws Exception { + project.setDefinition(new CpsFlowDefinition( + "node {runMATLABTests(testResultsPDF:'myresult/result.pdf')}", true)); + WorkflowRun build = project.scheduleBuild2(0).get(); + j.assertLogContains("setenv('MW_ORIG_WORKING_FOLDER',", build); + j.assertLogContains("run-matlab-command", build); + } /* * Verify Artifact is not sent as parameter. @@ -128,9 +126,9 @@ public void verifyArtifactParameters() throws Exception { j.assertLogNotContains("SimulinkTestResults", build); j.assertLogNotContains("CoberturaModelCoverage", build); } - + /* - * Verify runMatlabTests runs with empty parameters when nothing no artifact selected + * Verify runMatlabTests runs with empty parameters when nothing no artifact selected */ @Test @@ -155,34 +153,37 @@ public void verifyExceptionForNonZeroExitCode() throws Exception { j.assertBuildStatus(Result.FAILURE, build); j.assertLogContains(String.format(Message.getValue("matlab.execution.exception.prefix"), 1), build); } - - /*@Integ Test - * Verify default command options for test Filter using selectByFolder option + + /* + * @Integ Test + * Verify default command options for test Filter using selectByFolder option */ - public void verifyTestSelectByFolder () throws Exception { + public void verifyTestSelectByFolder() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(selectByFolder:['mytest1','mytest2'])}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("mytest1", build); j.assertLogContains("mytest2", build); } - - /*@Integ Test - * Verify default command options for test Filter using selectByTag option + + /* + * @Integ Test + * Verify default command options for test Filter using selectByTag option */ - public void verifyTestSelectByTag () throws Exception { + public void verifyTestSelectByTag() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(selectByTag: 'myTestTag')}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("myTestTag", build); } - - /*@Integ + + /* + * @Integ * Verify outputDetail set */ - + public void verifyOutputDetailSet() { Map outputDetail = new HashMap(); outputDetail.put("none", "'OutputDetail', 0"); @@ -204,12 +205,12 @@ public void verifyOutputDetailSet() { } }); } - - /*@Integ - * Verify loggingLevel set + + /* + * @Integ + * Verify loggingLevel set */ - - + public void verifyLoggingLevelSet() { Map outputDetail = new HashMap(); outputDetail.put("none", "'LoggingLevel', 0"); @@ -232,45 +233,49 @@ public void verifyLoggingLevelSet() { } }); } - - /*@Integ - * Verify when useParallel Set + + /* + * @Integ + * Verify when useParallel Set */ - - public void verifyUseParallelSet () throws Exception { + + public void verifyUseParallelSet() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(useParallel: true)}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("runInParallel", build); } - - /*@Integ - * Verify when useParallel Not Set + + /* + * @Integ + * Verify when useParallel Not Set */ - - public void verifyUseParallelNotSet () throws Exception { + + public void verifyUseParallelNotSet() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(useParallel: false)}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogNotContains("runInParallel", build); } - - /*@Integ - * Verify when strict Set + + /* + * @Integ + * Verify when strict Set */ - - public void verifyStrictSet () throws Exception { + + public void verifyStrictSet() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(strict: true)}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); j.assertLogContains("FailOnWarningsPlugin", build); } - - /*@Integ - * Verify when strict is not Set + + /* + * @Integ + * Verify when strict is not Set */ - - public void verifyStrictNotSet () throws Exception { + + public void verifyStrictNotSet() throws Exception { project.setDefinition(new CpsFlowDefinition( "node {runMATLABTests(strict: false)}", true)); WorkflowRun build = project.scheduleBuild2(0).get(); diff --git a/src/test/java/integ/com/mathworks/ci/TestMessage.java b/src/test/java/integ/com/mathworks/ci/TestMessage.java index 60846be0..061bb5e1 100644 --- a/src/test/java/integ/com/mathworks/ci/TestMessage.java +++ b/src/test/java/integ/com/mathworks/ci/TestMessage.java @@ -1,7 +1,7 @@ package com.mathworks.ci; /* - * Copyright 2018 The MathWorks, Inc. + * Copyright 2018-2024 The MathWorks, Inc. * * This Class is wrapper to access the static configuration values used across test classes. Acts as * Utility class to access key & value pairs from testconfig.properties diff --git a/src/test/java/integ/com/mathworks/ci/UseMatlabVersionBuildWrapperTest.java b/src/test/java/integ/com/mathworks/ci/UseMatlabVersionBuildWrapperTest.java index 4c2a73d1..bddad7c7 100644 --- a/src/test/java/integ/com/mathworks/ci/UseMatlabVersionBuildWrapperTest.java +++ b/src/test/java/integ/com/mathworks/ci/UseMatlabVersionBuildWrapperTest.java @@ -1,10 +1,9 @@ package com.mathworks.ci; /** - * Copyright 2019-2020 The MathWorks, Inc. + * Copyright 2019-2024 The MathWorks, Inc. * * Test class for AddMatlabToPathBuildWrapper - * */ import java.io.File; @@ -20,33 +19,31 @@ import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; -import com.gargoylesoftware.htmlunit.WebAssert; -import com.gargoylesoftware.htmlunit.html.HtmlPage; +import org.htmlunit.WebAssert; +import org.htmlunit.html.HtmlPage; import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; import hudson.tasks.BuildWrapper; public class UseMatlabVersionBuildWrapperTest { - + private FreeStyleProject project; private UseMatlabVersionBuildWrapper buildWrapper; private static String FileSeperator; private static String VERSION_INFO_XML_FILE = "VersionInfo.xml"; - + @BeforeClass public static void classSetup() { if (!System.getProperty("os.name").startsWith("Win")) { FileSeperator = "/"; - }else { + } else { FileSeperator = "\\"; } } - - @Rule public JenkinsRule jenkins = new JenkinsRule(); - + @Before public void testSetup() throws IOException { this.project = jenkins.createFreeStyleProject(); @@ -57,29 +54,32 @@ public void testSetup() throws IOException { public void testTearDown() { this.project = null; } - - //Private Method to get the valid MATLAB roots + + // Private Method to get the valid MATLAB roots private String getMatlabroot(String version) throws URISyntaxException { String defaultVersionInfo = "versioninfo/R2017a/" + VERSION_INFO_XML_FILE; - String userVersionInfo = "versioninfo/"+version+"/" + VERSION_INFO_XML_FILE; - URL matlabRootURL = Optional.ofNullable(getResource(userVersionInfo)).orElseGet(() -> getResource(defaultVersionInfo)); + String userVersionInfo = "versioninfo/" + version + "/" + VERSION_INFO_XML_FILE; + URL matlabRootURL = Optional.ofNullable(getResource(userVersionInfo)) + .orElseGet(() -> getResource(defaultVersionInfo)); File matlabRoot = new File(matlabRootURL.toURI()); - return matlabRoot.getAbsolutePath().replace(FileSeperator + VERSION_INFO_XML_FILE,"").replace("R2017a",version); + return matlabRoot.getAbsolutePath().replace(FileSeperator + VERSION_INFO_XML_FILE, "").replace("R2017a", + version); } - + private URL getResource(String resource) { - return UseMatlabVersionBuildWrapperTest.class.getClassLoader().getResource(resource); + return UseMatlabVersionBuildWrapperTest.class.getClassLoader().getResource(resource); } - + /* * Test Case to verify if job contains MATLAB build environment section. */ @Test public void verifyBuildEnvForMatlab() throws Exception { boolean found = false; - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), "")); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), "")); project.getBuildWrappersList().add(this.buildWrapper); - List bw = project.getBuildWrappersList(); + List bw = project.getBuildWrappersList(); for (BuildWrapper b : bw) { if (b.getDescriptor().getDisplayName() .equalsIgnoreCase(Message.getValue("Buildwrapper.display.name"))) { @@ -88,37 +88,40 @@ public void verifyBuildEnvForMatlab() throws Exception { } Assert.assertTrue("Build does not have MATLAB build environment", found); } - + /* * Verify if given MATLAB root is added in the PATH. * Should be added to integration test. */ - + public void verifyPATHupdated() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("/test/MATLAB/R2019a"))); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), getMatlabroot("/test/MATLAB/R2019a"))); project.getBuildWrappersList().add(this.buildWrapper); - RunMatlabTestsBuilderTester buildTester = new RunMatlabTestsBuilderTester("",""); + RunMatlabTestsBuilderTester buildTester = new RunMatlabTestsBuilderTester("", ""); project.getBuildersList().add(buildTester); FreeStyleBuild build = project.scheduleBuild2(0).get(); - Assert.assertTrue("Build does not have MATLAB build environment", this.buildWrapper.getMatlabRootFolder().equalsIgnoreCase(buildTester.getMatlabRoot())); + Assert.assertTrue("Build does not have MATLAB build environment", + this.buildWrapper.getMatlabRootFolder().equalsIgnoreCase(buildTester.getMatlabRoot())); } - + /* * Verify if invalid MATLAB path throes error on console. */ @Test public void verifyInvalidPATHError() throws Exception { - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("/test/MATLAB/R2019a"))); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), getMatlabroot("/test/MATLAB/R2019a"))); project.getBuildWrappersList().add(this.buildWrapper); - RunMatlabTestsBuilderTester buildTester = new RunMatlabTestsBuilderTester("",""); + RunMatlabTestsBuilderTester buildTester = new RunMatlabTestsBuilderTester("", ""); project.getBuildersList().add(buildTester); project.scheduleBuild2(0).get(); FreeStyleBuild build = project.scheduleBuild2(0).get(); jenkins.assertLogContains("MatlabNotFoundError", build); } - + /* - * Test To verify if UI throws an error when MATLAB root is empty. + * Test To verify if UI throws an error when MATLAB root is empty. * */ @@ -128,7 +131,7 @@ public void verifyEmptyMatlabRootError() throws Exception { HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); WebAssert.assertTextPresent(page, TestMessage.getValue("Builder.matlab.root.empty.error")); } - + /* * Test To verify UI does throw error when in-valid MATLAB root entered * @@ -137,12 +140,12 @@ public void verifyEmptyMatlabRootError() throws Exception { @Test public void verifyInvalidMatlabRootDisplaysWarnning() throws Exception { project.getBuildWrappersList().add(this.buildWrapper); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("/fake/MATLAB/path"))); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), getMatlabroot("/fake/MATLAB/path"))); HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); WebAssert.assertTextPresent(page, TestMessage.getValue("Builder.invalid.matlab.root.warning")); } - - + /* * Test To verify UI does not throw error when matrix variables are use * @@ -151,11 +154,12 @@ public void verifyInvalidMatlabRootDisplaysWarnning() throws Exception { @Test public void verifyMatriVariableNoErrorOrWarnning() throws Exception { project.getBuildWrappersList().add(this.buildWrapper); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("/test/MATLAB/$VERSION"))); + this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent( + Message.getValue("matlab.custom.location"), getMatlabroot("/test/MATLAB/$VERSION"))); HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); WebAssert.assertTextNotPresent(page, TestMessage.getValue("Builder.invalid.matlab.root.warning")); } - + /* * Test To verify UI does not throw warning when valid Matlab root is entered. * @@ -164,11 +168,10 @@ public void verifyMatriVariableNoErrorOrWarnning() throws Exception { @Test public void verifyValidMatlabNoWarning() throws Exception { project.getBuildWrappersList().add(this.buildWrapper); - this.buildWrapper.setMatlabBuildWrapperContent(new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); + this.buildWrapper.setMatlabBuildWrapperContent( + new MatlabBuildWrapperContent(Message.getValue("matlab.custom.location"), getMatlabroot("R2018b"))); HtmlPage page = jenkins.createWebClient().goTo("job/test0/configure"); WebAssert.assertTextNotPresent(page, TestMessage.getValue("Builder.invalid.matlab.root.warning")); } - - } diff --git a/src/test/java/unit/com/mathworks/ci/actions/MatlabActionTest.java b/src/test/java/unit/com/mathworks/ci/actions/MatlabActionTest.java index 44dadae0..795475d4 100644 --- a/src/test/java/unit/com/mathworks/ci/actions/MatlabActionTest.java +++ b/src/test/java/unit/com/mathworks/ci/actions/MatlabActionTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.File; @@ -36,14 +35,21 @@ @RunWith(MockitoJUnitRunner.Silent.class) public class MatlabActionTest { - @Mock CommandActionParameters params; - @Mock BuildConsoleAnnotator annotator; - @Mock MatlabCommandRunner runner; - @Mock PrintStream out; - @Mock TaskListener listener; - @Mock Run build; - - @Mock FilePath tempFolder; + @Mock + CommandActionParameters params; + @Mock + BuildConsoleAnnotator annotator; + @Mock + MatlabCommandRunner runner; + @Mock + PrintStream out; + @Mock + TaskListener listener; + @Mock + Run build; + + @Mock + FilePath tempFolder; private boolean setup = false; private RunMatlabCommandAction action; @@ -74,13 +80,16 @@ public void shouldCopyPluginsToTempDirectory() throws IOException, InterruptedEx inOrder.verify(runner) .copyFileToTempFolder(MatlabBuilderConstants.DEFAULT_PLUGIN, MatlabBuilderConstants.DEFAULT_PLUGIN); inOrder.verify(runner) - .copyFileToTempFolder(MatlabBuilderConstants.BUILD_REPORT_PLUGIN, MatlabBuilderConstants.BUILD_REPORT_PLUGIN); + .copyFileToTempFolder(MatlabBuilderConstants.BUILD_REPORT_PLUGIN, + MatlabBuilderConstants.BUILD_REPORT_PLUGIN); inOrder.verify(runner) - .copyFileToTempFolder(MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN, MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN); + .copyFileToTempFolder(MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN, + MatlabBuilderConstants.TASK_RUN_PROGRESS_PLUGIN); } @Test - public void shouldOverrideDefaultBuildtoolPlugin() throws IOException, InterruptedException, MatlabExecutionException { + public void shouldOverrideDefaultBuildtoolPlugin() + throws IOException, InterruptedException, MatlabExecutionException { action.run(); verify(runner).addEnvironmentVariable( @@ -89,7 +98,8 @@ public void shouldOverrideDefaultBuildtoolPlugin() throws IOException, Interrupt } @Test - public void shouldCopyBuildResultsToRootAndAddAction() throws IOException, InterruptedException, MatlabExecutionException { + public void shouldCopyBuildResultsToRootAndAddAction() + throws IOException, InterruptedException, MatlabExecutionException { File tmp = Files.createTempDirectory("temp").toFile(); tmp.deleteOnExit(); @@ -107,7 +117,7 @@ public void shouldCopyBuildResultsToRootAndAddAction() throws IOException, Inter // Should have deleted original file assertFalse(json.exists()); // Should have copied file to root dir - assertTrue(new File(dest, "buildArtifact"+ action.getActionID() + ".json").exists()); + assertTrue(new File(dest, "buildArtifact" + action.getActionID() + ".json").exists()); } @Test diff --git a/src/test/java/unit/com/mathworks/ci/actions/RunMatlabBuildActionTest.java b/src/test/java/unit/com/mathworks/ci/actions/RunMatlabBuildActionTest.java index bfd66117..d4ce810e 100644 --- a/src/test/java/unit/com/mathworks/ci/actions/RunMatlabBuildActionTest.java +++ b/src/test/java/unit/com/mathworks/ci/actions/RunMatlabBuildActionTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -30,14 +29,21 @@ @RunWith(MockitoJUnitRunner.class) public class RunMatlabBuildActionTest { - @Mock BuildActionParameters params; - @Mock BuildConsoleAnnotator annotator; - @Mock MatlabCommandRunner runner; - @Mock TaskListener listener; - @Mock PrintStream out; - @Mock Run build; - - @Mock FilePath tempFolder; + @Mock + BuildActionParameters params; + @Mock + BuildConsoleAnnotator annotator; + @Mock + MatlabCommandRunner runner; + @Mock + TaskListener listener; + @Mock + PrintStream out; + @Mock + Run build; + + @Mock + FilePath tempFolder; private boolean setup = false; private RunMatlabBuildAction action; @@ -74,17 +80,18 @@ public void shouldRunCorrectCommand() throws IOException, InterruptedException, } @Test - public void shouldRunCommandWithTasksAndBuildOptions() throws IOException, InterruptedException, MatlabExecutionException { + public void shouldRunCommandWithTasksAndBuildOptions() + throws IOException, InterruptedException, MatlabExecutionException { doReturn("dishes groceries").when(params).getTasks(); doReturn("-continueOnFailure -skip dishes").when(params) - .getBuildOptions(); + .getBuildOptions(); action.run(); verify(runner).runMatlabCommand( "addpath('/path/less/traveled'); " - + "buildtool dishes groceries " - + "-continueOnFailure -skip dishes"); + + "buildtool dishes groceries " + + "-continueOnFailure -skip dishes"); } @Test @@ -96,6 +103,7 @@ public void shouldPrintAndRethrowMessage() throws IOException, InterruptedExcept } catch (MatlabExecutionException e) { verify(out).println(e.getMessage()); assertEquals(12, e.getExitCode()); - }; + } + ; } } diff --git a/src/test/java/unit/com/mathworks/ci/actions/RunMatlabCommandActionTest.java b/src/test/java/unit/com/mathworks/ci/actions/RunMatlabCommandActionTest.java index 0456c292..5f4cee96 100644 --- a/src/test/java/unit/com/mathworks/ci/actions/RunMatlabCommandActionTest.java +++ b/src/test/java/unit/com/mathworks/ci/actions/RunMatlabCommandActionTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -30,14 +29,21 @@ @RunWith(MockitoJUnitRunner.Silent.class) public class RunMatlabCommandActionTest { - @Mock CommandActionParameters params; - @Mock BuildConsoleAnnotator annotator; - @Mock MatlabCommandRunner runner; - @Mock PrintStream out; - @Mock TaskListener listener; - @Mock Run build; - - @Mock FilePath tempFolder; + @Mock + CommandActionParameters params; + @Mock + BuildConsoleAnnotator annotator; + @Mock + MatlabCommandRunner runner; + @Mock + PrintStream out; + @Mock + TaskListener listener; + @Mock + Run build; + + @Mock + FilePath tempFolder; private boolean setup = false; private RunMatlabCommandAction action; @@ -91,6 +97,7 @@ public void printsAndRethrowsMessage() throws IOException, InterruptedException, } catch (MatlabExecutionException e) { verify(out).println(e.getMessage()); assertEquals(12, e.getExitCode()); - }; + } + ; } } diff --git a/src/test/java/unit/com/mathworks/ci/actions/RunMatlabTestsActionTest.java b/src/test/java/unit/com/mathworks/ci/actions/RunMatlabTestsActionTest.java index 85de29e9..6519c08b 100644 --- a/src/test/java/unit/com/mathworks/ci/actions/RunMatlabTestsActionTest.java +++ b/src/test/java/unit/com/mathworks/ci/actions/RunMatlabTestsActionTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -31,11 +30,16 @@ @RunWith(MockitoJUnitRunner.class) public class RunMatlabTestsActionTest { - @Mock TestActionParameters params; - @Mock MatlabCommandRunner runner; - @Mock PrintStream out; - @Mock TaskListener listener; - @Mock FilePath tempFolder; + @Mock + TestActionParameters params; + @Mock + MatlabCommandRunner runner; + @Mock + PrintStream out; + @Mock + TaskListener listener; + @Mock + FilePath tempFolder; private boolean setup = false; private RunMatlabTestsAction action; @@ -50,7 +54,7 @@ public void init() throws IOException, InterruptedException { when(runner.getTempFolder()).thenReturn(tempFolder); when(tempFolder.getRemote()).thenReturn("/gravel/path"); when(runner.copyFileToTempFolder(anyString(), anyString())) - .thenReturn(tempFolder); + .thenReturn(tempFolder); } } @@ -75,7 +79,8 @@ public void shouldAddTempFolderToPath() throws IOException, InterruptedException } @Test - public void shouldReplaceParamsCorrectlyWhenAllNull() throws IOException, InterruptedException, MatlabExecutionException { + public void shouldReplaceParamsCorrectlyWhenAllNull() + throws IOException, InterruptedException, MatlabExecutionException { // Keep parameters as null action.run(); @@ -86,7 +91,8 @@ public void shouldReplaceParamsCorrectlyWhenAllNull() throws IOException, Interr } @Test - public void shouldReplaceParamsCorrectlyWithFewNull() throws IOException, InterruptedException, MatlabExecutionException { + public void shouldReplaceParamsCorrectlyWithFewNull() + throws IOException, InterruptedException, MatlabExecutionException { // Set some params doReturn("results.xml").when(params).getTestResultsJUnit(); doReturn("cov.xml").when(params).getCodeCoverageCobertura(); @@ -104,17 +110,17 @@ public void shouldReplaceParamsCorrectlyWithFewNull() throws IOException, Interr ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); verify(runner).runMatlabCommand(captor.capture()); assertThat(captor.getValue(), containsString( - "genscript('Test','JUnitTestResults','results.xml'," - + "'CoberturaCodeCoverage','cov.xml'," - + "'Strict',true," - + "'LoggingLevel','Default'," - + "'OutputDetail','Concise'," - + "'SourceFolder',{'src','toolbox'})" - )); + "genscript('Test','JUnitTestResults','results.xml'," + + "'CoberturaCodeCoverage','cov.xml'," + + "'Strict',true," + + "'LoggingLevel','Default'," + + "'OutputDetail','Concise'," + + "'SourceFolder',{'src','toolbox'})")); } @Test - public void shouldReplaceParamsCorrectlyWithNoneNull() throws IOException, InterruptedException, MatlabExecutionException { + public void shouldReplaceParamsCorrectlyWithNoneNull() + throws IOException, InterruptedException, MatlabExecutionException { // Set all params doReturn("results.pdf").when(params).getTestResultsPDF(); doReturn("results.tap").when(params).getTestResultsTAP(); @@ -139,21 +145,20 @@ public void shouldReplaceParamsCorrectlyWithNoneNull() throws IOException, Inter ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); verify(runner).runMatlabCommand(captor.capture()); assertThat(captor.getValue(), containsString( - "genscript('Test'," - + "'PDFTestReport','results.pdf'," - + "'TAPTestResults','results.tap'," - + "'JUnitTestResults','results.xml'," - + "'CoberturaCodeCoverage','cov.xml'," - + "'SimulinkTestResults','results.sltest'," - + "'CoberturaModelCoverage','cov.model'," - + "'SelectByTag','MyTag'," - + "'UseParallel',true," - + "'Strict',true," - + "'LoggingLevel','Default'," - + "'OutputDetail','Concise'," - + "'SourceFolder',{'src','toolbox'}," - + "'SelectByFolder',{'src','toolbox'})" - )); + "genscript('Test'," + + "'PDFTestReport','results.pdf'," + + "'TAPTestResults','results.tap'," + + "'JUnitTestResults','results.xml'," + + "'CoberturaCodeCoverage','cov.xml'," + + "'SimulinkTestResults','results.sltest'," + + "'CoberturaModelCoverage','cov.model'," + + "'SelectByTag','MyTag'," + + "'UseParallel',true," + + "'Strict',true," + + "'LoggingLevel','Default'," + + "'OutputDetail','Concise'," + + "'SourceFolder',{'src','toolbox'}," + + "'SelectByFolder',{'src','toolbox'})")); } @Test @@ -168,6 +173,7 @@ public void printsAndRethrowsMessage() throws IOException, InterruptedException, } catch (MatlabExecutionException e) { verify(out).println(e.getMessage()); assertEquals(12, e.getExitCode()); - }; + } + ; } } diff --git a/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabBuildBuilderUnitTest.java b/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabBuildBuilderUnitTest.java index 02e38116..e4ca91f0 100644 --- a/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabBuildBuilderUnitTest.java +++ b/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabBuildBuilderUnitTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -48,7 +47,7 @@ public class RunMatlabBuildBuilderUnitTest { TaskListener listener; @Mock - FilePath workspace; + FilePath workspace; @Before public void setup() throws IOException, InterruptedException { @@ -60,12 +59,12 @@ public void shouldHandleNullCases() throws IOException, InterruptedException, Ma RunMatlabBuildBuilder builder = new RunMatlabBuildBuilder(factory); builder.perform(build, workspace, launcher, listener); - + ArgumentCaptor captor = ArgumentCaptor.forClass(BuildActionParameters.class); verify(factory).createAction(captor.capture()); BuildActionParameters actual = captor.getValue(); - + assertEquals("", actual.getStartupOptions()); assertEquals(null, actual.getTasks()); assertEquals(null, actual.getBuildOptions()); @@ -80,12 +79,12 @@ public void shouldHandleMaximalCases() throws IOException, InterruptedException, builder.setStartupOptions(new StartupOptions("-nojvm -logfile mylog")); builder.perform(build, workspace, launcher, listener); - + ArgumentCaptor captor = ArgumentCaptor.forClass(BuildActionParameters.class); verify(factory).createAction(captor.capture()); BuildActionParameters actual = captor.getValue(); - + assertEquals("-nojvm -logfile mylog", actual.getStartupOptions()); assertEquals("laundry sweeping", actual.getTasks()); assertEquals("-continueOnFailure -skip laundry", actual.getBuildOptions()); @@ -95,7 +94,7 @@ public void shouldHandleMaximalCases() throws IOException, InterruptedException, @Test public void shouldMarkFailureWhenActionFails() throws IOException, InterruptedException, MatlabExecutionException { RunMatlabBuildBuilder builder = new RunMatlabBuildBuilder(factory); - + doThrow(new MatlabExecutionException(12)).when(action).run(); builder.perform(build, workspace, launcher, listener); @@ -103,4 +102,3 @@ public void shouldMarkFailureWhenActionFails() throws IOException, InterruptedEx verify(build).setResult(Result.FAILURE); } } - diff --git a/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabCommandBuilderUnitTest.java b/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabCommandBuilderUnitTest.java index 3cc2e830..b93fdacd 100644 --- a/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabCommandBuilderUnitTest.java +++ b/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabCommandBuilderUnitTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -47,7 +46,7 @@ public class RunMatlabCommandBuilderUnitTest { TaskListener listener; @Mock - FilePath workspace; + FilePath workspace; @Before public void setup() throws IOException, InterruptedException { @@ -59,12 +58,12 @@ public void shouldHandleNullCases() throws IOException, InterruptedException, Ma RunMatlabCommandBuilder builder = new RunMatlabCommandBuilder(factory); builder.perform(build, workspace, launcher, listener); - + ArgumentCaptor captor = ArgumentCaptor.forClass(CommandActionParameters.class); verify(factory).createAction(captor.capture()); CommandActionParameters actual = captor.getValue(); - + assertEquals("", actual.getStartupOptions()); assertEquals(null, actual.getCommand()); verify(action).run(); @@ -77,12 +76,12 @@ public void shouldHandleMaximalCases() throws IOException, InterruptedException, builder.setStartupOptions(new StartupOptions("-nojvm -logfile mylog")); builder.perform(build, workspace, launcher, listener); - + ArgumentCaptor captor = ArgumentCaptor.forClass(CommandActionParameters.class); verify(factory).createAction(captor.capture()); CommandActionParameters actual = captor.getValue(); - + assertEquals("-nojvm -logfile mylog", actual.getStartupOptions()); assertEquals("SHAKE", actual.getCommand()); verify(action).run(); @@ -91,7 +90,7 @@ public void shouldHandleMaximalCases() throws IOException, InterruptedException, @Test public void shouldMarkFailureWhenActionFails() throws IOException, InterruptedException, MatlabExecutionException { RunMatlabCommandBuilder builder = new RunMatlabCommandBuilder(factory); - + doThrow(new MatlabExecutionException(12)).when(action).run(); builder.perform(build, workspace, launcher, listener); @@ -99,4 +98,3 @@ public void shouldMarkFailureWhenActionFails() throws IOException, InterruptedEx verify(build).setResult(Result.FAILURE); } } - diff --git a/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabTestsBuilderUnitTest.java b/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabTestsBuilderUnitTest.java index d8393374..b492607e 100644 --- a/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabTestsBuilderUnitTest.java +++ b/src/test/java/unit/com/mathworks/ci/freestyle/RunMatlabTestsBuilderUnitTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -32,126 +31,126 @@ @RunWith(MockitoJUnitRunner.class) public class RunMatlabTestsBuilderUnitTest { - @Mock - MatlabActionFactory factory; - - @Mock - RunMatlabTestsAction action; - - @Mock - Run build; - - @Mock - Launcher launcher; - - @Mock - TaskListener listener; - - @Mock - FilePath workspace; - - @Before - public void setup() throws IOException, InterruptedException { - doReturn(action).when(factory).createAction(any(TestActionParameters.class)); - } - - @Test - public void shouldHandleNullCases() throws IOException, InterruptedException, MatlabExecutionException { - RunMatlabTestsBuilder builder = new RunMatlabTestsBuilder(factory); - - builder.perform(build, workspace, launcher, listener); - - ArgumentCaptor captor = ArgumentCaptor.forClass(TestActionParameters.class); - verify(factory).createAction(captor.capture()); - - TestActionParameters actual = captor.getValue(); - - assertEquals("", actual.getStartupOptions()); - assertEquals(null, actual.getTestResultsPDF()); - assertEquals(null, actual.getTestResultsTAP()); - assertEquals(null, actual.getTestResultsJUnit()); - assertEquals(null, actual.getCodeCoverageCobertura()); - assertEquals(null, actual.getTestResultsSimulinkTest()); - assertEquals(null, actual.getModelCoverageCobertura()); - assertEquals(null, actual.getSelectByTag()); - assertEquals(null, actual.getLoggingLevel()); - assertEquals(null, actual.getOutputDetail()); - assertEquals("false", actual.getUseParallel()); - assertEquals("false", actual.getStrict()); - assertEquals(null, actual.getSourceFolder()); - assertEquals(null, actual.getSelectByFolder()); - verify(action).run(); - } - - @Test - public void shouldHandleMaximalCases() throws IOException, InterruptedException, MatlabExecutionException { - RunMatlabTestsBuilder builder = new RunMatlabTestsBuilder(factory); - - ArrayList source = new ArrayList(); - source.add(new SourceFolderPaths("toolbox")); - source.add(new SourceFolderPaths("src")); - - ArrayList select = new ArrayList(); - select.add(new TestFolders("toolbox")); - select.add(new TestFolders("src")); - - builder.setStartupOptions(new StartupOptions("-nojvm -logfile mylog")); - builder.setPdfReportArtifact( - new RunMatlabTestsBuilder.PdfArtifact("pdf.pdf")); - builder.setTapArtifact( - new RunMatlabTestsBuilder.TapArtifact("tap.tap")); - builder.setJunitArtifact( - new RunMatlabTestsBuilder.JunitArtifact("results.xml")); - builder.setCoberturaArtifact( - new RunMatlabTestsBuilder.CoberturaArtifact("cov.xml")); - builder.setStmResultsArtifact( - new RunMatlabTestsBuilder.StmResultsArtifact("res.sltest")); - builder.setModelCoverageArtifact( - new RunMatlabTestsBuilder.ModelCovArtifact("cov.model")); - builder.setSelectByTag( - new RunMatlabTestsBuilder.SelectByTag("MyTag")); - builder.setSourceFolder( - new SourceFolder(source)); - builder.setSelectByFolder( - new SelectByFolder(select)); - builder.setLoggingLevel("Concise"); - builder.setOutputDetail("Concise"); - builder.setUseParallel(true); - builder.setStrict(true); - - builder.perform(build, workspace, launcher, listener); - - ArgumentCaptor captor = ArgumentCaptor.forClass(TestActionParameters.class); - verify(factory).createAction(captor.capture()); - - TestActionParameters actual = captor.getValue(); - - assertEquals("-nojvm -logfile mylog", actual.getStartupOptions()); - assertEquals("pdf.pdf", actual.getTestResultsPDF()); - assertEquals("tap.tap", actual.getTestResultsTAP()); - assertEquals("results.xml", actual.getTestResultsJUnit()); - assertEquals("cov.xml", actual.getCodeCoverageCobertura()); - assertEquals("res.sltest", actual.getTestResultsSimulinkTest()); - assertEquals("cov.model", actual.getModelCoverageCobertura()); - assertEquals("MyTag", actual.getSelectByTag()); - assertEquals("Concise", actual.getLoggingLevel()); - assertEquals("Concise", actual.getOutputDetail()); - assertEquals("true", actual.getUseParallel()); - assertEquals("true", actual.getStrict()); - assertEquals(2, actual.getSourceFolder().size()); - assertEquals(2, actual.getSelectByFolder().size()); - verify(action).run(); - } - - @Test - public void shouldMarkFailureWhenActionFails() throws IOException, InterruptedException, MatlabExecutionException { - RunMatlabTestsBuilder builder = new RunMatlabTestsBuilder(factory); - - doThrow(new MatlabExecutionException(12)).when(action).run(); - - builder.perform(build, workspace, launcher, listener); - - verify(build).setResult(Result.FAILURE); - } + @Mock + MatlabActionFactory factory; + + @Mock + RunMatlabTestsAction action; + + @Mock + Run build; + + @Mock + Launcher launcher; + + @Mock + TaskListener listener; + + @Mock + FilePath workspace; + + @Before + public void setup() throws IOException, InterruptedException { + doReturn(action).when(factory).createAction(any(TestActionParameters.class)); + } + + @Test + public void shouldHandleNullCases() throws IOException, InterruptedException, MatlabExecutionException { + RunMatlabTestsBuilder builder = new RunMatlabTestsBuilder(factory); + + builder.perform(build, workspace, launcher, listener); + + ArgumentCaptor captor = ArgumentCaptor.forClass(TestActionParameters.class); + verify(factory).createAction(captor.capture()); + + TestActionParameters actual = captor.getValue(); + + assertEquals("", actual.getStartupOptions()); + assertEquals(null, actual.getTestResultsPDF()); + assertEquals(null, actual.getTestResultsTAP()); + assertEquals(null, actual.getTestResultsJUnit()); + assertEquals(null, actual.getCodeCoverageCobertura()); + assertEquals(null, actual.getTestResultsSimulinkTest()); + assertEquals(null, actual.getModelCoverageCobertura()); + assertEquals(null, actual.getSelectByTag()); + assertEquals(null, actual.getLoggingLevel()); + assertEquals(null, actual.getOutputDetail()); + assertEquals("false", actual.getUseParallel()); + assertEquals("false", actual.getStrict()); + assertEquals(null, actual.getSourceFolder()); + assertEquals(null, actual.getSelectByFolder()); + verify(action).run(); + } + + @Test + public void shouldHandleMaximalCases() throws IOException, InterruptedException, MatlabExecutionException { + RunMatlabTestsBuilder builder = new RunMatlabTestsBuilder(factory); + + ArrayList source = new ArrayList(); + source.add(new SourceFolderPaths("toolbox")); + source.add(new SourceFolderPaths("src")); + + ArrayList select = new ArrayList(); + select.add(new TestFolders("toolbox")); + select.add(new TestFolders("src")); + + builder.setStartupOptions(new StartupOptions("-nojvm -logfile mylog")); + builder.setPdfReportArtifact( + new RunMatlabTestsBuilder.PdfArtifact("pdf.pdf")); + builder.setTapArtifact( + new RunMatlabTestsBuilder.TapArtifact("tap.tap")); + builder.setJunitArtifact( + new RunMatlabTestsBuilder.JunitArtifact("results.xml")); + builder.setCoberturaArtifact( + new RunMatlabTestsBuilder.CoberturaArtifact("cov.xml")); + builder.setStmResultsArtifact( + new RunMatlabTestsBuilder.StmResultsArtifact("res.sltest")); + builder.setModelCoverageArtifact( + new RunMatlabTestsBuilder.ModelCovArtifact("cov.model")); + builder.setSelectByTag( + new RunMatlabTestsBuilder.SelectByTag("MyTag")); + builder.setSourceFolder( + new SourceFolder(source)); + builder.setSelectByFolder( + new SelectByFolder(select)); + builder.setLoggingLevel("Concise"); + builder.setOutputDetail("Concise"); + builder.setUseParallel(true); + builder.setStrict(true); + + builder.perform(build, workspace, launcher, listener); + + ArgumentCaptor captor = ArgumentCaptor.forClass(TestActionParameters.class); + verify(factory).createAction(captor.capture()); + + TestActionParameters actual = captor.getValue(); + + assertEquals("-nojvm -logfile mylog", actual.getStartupOptions()); + assertEquals("pdf.pdf", actual.getTestResultsPDF()); + assertEquals("tap.tap", actual.getTestResultsTAP()); + assertEquals("results.xml", actual.getTestResultsJUnit()); + assertEquals("cov.xml", actual.getCodeCoverageCobertura()); + assertEquals("res.sltest", actual.getTestResultsSimulinkTest()); + assertEquals("cov.model", actual.getModelCoverageCobertura()); + assertEquals("MyTag", actual.getSelectByTag()); + assertEquals("Concise", actual.getLoggingLevel()); + assertEquals("Concise", actual.getOutputDetail()); + assertEquals("true", actual.getUseParallel()); + assertEquals("true", actual.getStrict()); + assertEquals(2, actual.getSourceFolder().size()); + assertEquals(2, actual.getSelectByFolder().size()); + verify(action).run(); + } + + @Test + public void shouldMarkFailureWhenActionFails() + throws IOException, InterruptedException, MatlabExecutionException { + RunMatlabTestsBuilder builder = new RunMatlabTestsBuilder(factory); + + doThrow(new MatlabExecutionException(12)).when(action).run(); + + builder.perform(build, workspace, launcher, listener); + + verify(build).setResult(Result.FAILURE); + } } - diff --git a/src/test/java/unit/com/mathworks/ci/pipeline/MatlabBuildStepExecutionUnitTest.java b/src/test/java/unit/com/mathworks/ci/pipeline/MatlabBuildStepExecutionUnitTest.java index 5699646d..2729138a 100644 --- a/src/test/java/unit/com/mathworks/ci/pipeline/MatlabBuildStepExecutionUnitTest.java +++ b/src/test/java/unit/com/mathworks/ci/pipeline/MatlabBuildStepExecutionUnitTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -26,10 +25,13 @@ @RunWith(MockitoJUnitRunner.class) public class MatlabBuildStepExecutionUnitTest { - @Mock StepContext context; - @Mock MatlabActionFactory factory; - @Mock RunMatlabBuildAction action; - + @Mock + StepContext context; + @Mock + MatlabActionFactory factory; + @Mock + RunMatlabBuildAction action; + @Before public void setup() throws IOException, InterruptedException { when(factory.createAction(any(BuildActionParameters.class))).thenReturn(action); @@ -54,7 +56,8 @@ public void shouldHandleNullCases() throws Exception, IOException, InterruptedEx } @Test - public void shouldHandleMaximalCases() throws Exception, IOException, InterruptedException, MatlabExecutionException { + public void shouldHandleMaximalCases() + throws Exception, IOException, InterruptedException, MatlabExecutionException { RunMatlabBuildStep step = new RunMatlabBuildStep(); step.setStartupOptions("-nojvm -logfile file"); step.setTasks("vacuum bills"); @@ -77,7 +80,8 @@ public void shouldHandleMaximalCases() throws Exception, IOException, Interrupte } @Test - public void shouldHandleActionThrowing() throws Exception, IOException, InterruptedException, MatlabExecutionException { + public void shouldHandleActionThrowing() + throws Exception, IOException, InterruptedException, MatlabExecutionException { MatlabBuildStepExecution ex = new MatlabBuildStepExecution(factory, context, new RunMatlabBuildStep()); doThrow(new MatlabExecutionException(12)).when(action).run(); diff --git a/src/test/java/unit/com/mathworks/ci/pipeline/MatlabCommandStepExecutionUnitTest.java b/src/test/java/unit/com/mathworks/ci/pipeline/MatlabCommandStepExecutionUnitTest.java index f4e5ed9b..50c54dfb 100644 --- a/src/test/java/unit/com/mathworks/ci/pipeline/MatlabCommandStepExecutionUnitTest.java +++ b/src/test/java/unit/com/mathworks/ci/pipeline/MatlabCommandStepExecutionUnitTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -26,10 +25,13 @@ @RunWith(MockitoJUnitRunner.class) public class MatlabCommandStepExecutionUnitTest { - @Mock StepContext context; - @Mock MatlabActionFactory factory; - @Mock RunMatlabCommandAction action; - + @Mock + StepContext context; + @Mock + MatlabActionFactory factory; + @Mock + RunMatlabCommandAction action; + @Before public void setup() throws IOException, InterruptedException { when(factory.createAction(any(CommandActionParameters.class))).thenReturn(action); @@ -38,8 +40,8 @@ public void setup() throws IOException, InterruptedException { @Test public void shouldHandleNullCases() throws Exception, IOException, InterruptedException, MatlabExecutionException { MatlabCommandStepExecution ex = new MatlabCommandStepExecution( - factory, - context, + factory, + context, new RunMatlabCommandStep(null)); ex.run(); @@ -55,7 +57,8 @@ public void shouldHandleNullCases() throws Exception, IOException, InterruptedEx } @Test - public void shouldHandleMaximalCases() throws Exception, IOException, InterruptedException, MatlabExecutionException { + public void shouldHandleMaximalCases() + throws Exception, IOException, InterruptedException, MatlabExecutionException { RunMatlabCommandStep step = new RunMatlabCommandStep("mycommand"); step.setStartupOptions("-nojvm -logfile file"); @@ -74,10 +77,11 @@ public void shouldHandleMaximalCases() throws Exception, IOException, Interrupte } @Test - public void shouldHandleActionThrowing() throws Exception, IOException, InterruptedException, MatlabExecutionException { + public void shouldHandleActionThrowing() + throws Exception, IOException, InterruptedException, MatlabExecutionException { MatlabCommandStepExecution ex = new MatlabCommandStepExecution( - factory, - context, + factory, + context, new RunMatlabCommandStep(null)); doThrow(new MatlabExecutionException(12)).when(action).run(); diff --git a/src/test/java/unit/com/mathworks/ci/pipeline/MatlabRunTestsStepExecutionUnitTest.java b/src/test/java/unit/com/mathworks/ci/pipeline/MatlabRunTestsStepExecutionUnitTest.java index fe9d18fd..54e82a71 100644 --- a/src/test/java/unit/com/mathworks/ci/pipeline/MatlabRunTestsStepExecutionUnitTest.java +++ b/src/test/java/unit/com/mathworks/ci/pipeline/MatlabRunTestsStepExecutionUnitTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -27,10 +26,13 @@ @RunWith(MockitoJUnitRunner.class) public class MatlabRunTestsStepExecutionUnitTest { - @Mock StepContext context; - @Mock MatlabActionFactory factory; - @Mock RunMatlabTestsAction action; - + @Mock + StepContext context; + @Mock + MatlabActionFactory factory; + @Mock + RunMatlabTestsAction action; + @Before public void setup() throws IOException, InterruptedException { when(factory.createAction(any(TestActionParameters.class))).thenReturn(action); @@ -66,7 +68,8 @@ public void shouldHandleNullCase() throws Exception, IOException, InterruptedExc } @Test - public void shouldHandleMaximalCase() throws Exception, IOException, InterruptedException, MatlabExecutionException { + public void shouldHandleMaximalCase() + throws Exception, IOException, InterruptedException, MatlabExecutionException { RunMatlabTestsStep step = new RunMatlabTestsStep(); step.setStartupOptions("-nojvm -logfile file"); step.setTestResultsPDF("res.pdf"); @@ -89,7 +92,7 @@ public void shouldHandleMaximalCase() throws Exception, IOException, Interrupted step.setSelectByFolder(folders); MatlabRunTestsStepExecution ex = new MatlabRunTestsStepExecution(factory, context, step); - + ex.run(); ArgumentCaptor captor = ArgumentCaptor.forClass(TestActionParameters.class); @@ -115,7 +118,8 @@ public void shouldHandleMaximalCase() throws Exception, IOException, Interrupted } @Test - public void shouldHandleActionThrowing() throws Exception, IOException, InterruptedException, MatlabExecutionException { + public void shouldHandleActionThrowing() + throws Exception, IOException, InterruptedException, MatlabExecutionException { MatlabRunTestsStepExecution ex = new MatlabRunTestsStepExecution(factory, context, new RunMatlabTestsStep()); doThrow(new MatlabExecutionException(12)).when(action).run(); diff --git a/src/test/java/unit/com/mathworks/ci/tools/MatlabInstallerUnitTest.java b/src/test/java/unit/com/mathworks/ci/tools/MatlabInstallerUnitTest.java new file mode 100644 index 00000000..8900cd0e --- /dev/null +++ b/src/test/java/unit/com/mathworks/ci/tools/MatlabInstallerUnitTest.java @@ -0,0 +1,84 @@ +package com.mathworks.ci.tools; + +/** + * Copyright 2024, The MathWorks, Inc. + */ + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.junit.Rule; +import org.junit.rules.ExpectedException; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.mathworks.ci.tools.InstallationFailedException; +import com.mathworks.ci.tools.MatlabInstaller; + +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.Node; +import hudson.model.TaskListener; +import hudson.tools.ToolInstallation; + +import org.junit.Before; +import org.junit.Test; + +public class MatlabInstallerUnitTest { + + private MatlabInstaller installer; + + @Mock + private Node mockNode; + + @Mock + private TaskListener mockListener; + + @Mock + private ToolInstallation mockTool; + + @Mock + private FilePath mockFilePath; + + @Mock + private Launcher mockLauncher; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + installer = spy(new MatlabInstaller("test-id")); + installer.setRelease("R2021a"); + installer.setProducts("MATLAB"); + } + + @Test + public void testGetRelease() { + assertEquals("R2021a", installer.getRelease()); + } + + @Test + public void testGetProducts() { + assertEquals("MATLAB", installer.getProducts()); + } + + @Test + public void testPerformInstallation() throws Exception { + doReturn(mockFilePath).when(installer) + .performInstallation(mockTool, mockNode, mockListener); + + FilePath result = installer.performInstallation(mockTool, mockNode, mockListener); + assertNotNull(result); + } + + @Test(expected = InstallationFailedException.class) + public void testUnsupportedOS() throws Exception { + installer.getPlatform("unsupportedOS", "unsupportedArch"); + } + + @Test + public void testGetPlatform() throws InstallationFailedException { + assertEquals("glnxa64", installer.getPlatform("Linux", "i686")); + assertEquals("maci64", installer.getPlatform("Mac OS X", "amd64")); + assertEquals("maca64", installer.getPlatform("Mac OS X", "arm64")); + } +} diff --git a/src/test/java/unit/com/mathworks/ci/utilities/GetSystemPropertiesUnitTest.java b/src/test/java/unit/com/mathworks/ci/utilities/GetSystemPropertiesUnitTest.java new file mode 100644 index 00000000..3edc63df --- /dev/null +++ b/src/test/java/unit/com/mathworks/ci/utilities/GetSystemPropertiesUnitTest.java @@ -0,0 +1,32 @@ +package com.mathworks.ci.utilities; + +/** + * Copyright 2024, The MathWorks, Inc. + */ + +import static org.junit.Assert.assertArrayEquals; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +public class GetSystemPropertiesUnitTest { + + @Mock + private GetSystemProperties getSystemProperties; + + @Before + public void setUp() { + getSystemProperties = new GetSystemProperties("os.name", "os.arch", "os.version"); + } + + @Test + public void testCall() { + String[] expected = { System.getProperty("os.name"), System.getProperty("os.arch"), + System.getProperty("os.version") }; + String[] result = getSystemProperties.call(); + assertArrayEquals(expected, result); + } +} diff --git a/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTest.java b/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTest.java index 4c0087b2..48403d5e 100644 --- a/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTest.java +++ b/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTest.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.File; @@ -40,13 +39,18 @@ @RunWith(MockitoJUnitRunner.class) public class MatlabCommandRunnerTest { - - @Mock private Launcher launcher; - @Mock private ProcStarter procStarter; + + @Mock + private Launcher launcher; + @Mock + private ProcStarter procStarter; private EnvVars env; - @Mock private TaskListener listener; - @Mock private PrintStream logger; - @Mock private MatlabActionParameters params; + @Mock + private TaskListener listener; + @Mock + private PrintStream logger; + @Mock + private MatlabActionParameters params; @Rule public TemporaryFolder tempDir = new TemporaryFolder(); @@ -55,25 +59,25 @@ public class MatlabCommandRunnerTest { @Before public void initialize() throws IOException, InterruptedException { - env = new EnvVars(); - - doReturn(new FilePath(tempDir.getRoot())).when(params).getWorkspace(); - when(params.getLauncher()).thenReturn(launcher); - when(params.getEnvVars()).thenReturn(env); - when(params.getTaskListener()).thenReturn(listener); - when(params.getStartupOptions()).thenReturn(""); - - when(listener.getLogger()).thenReturn(logger); - - doReturn(false).when(launcher).isUnix(); - when(launcher.launch()).thenReturn(procStarter); - when(procStarter.cmds(any(ArgumentListBuilder.class))).thenReturn(procStarter); - when(procStarter.masks(anyBoolean(), anyBoolean(), anyBoolean())) - .thenReturn(procStarter); - when(procStarter.envs(any(EnvVars.class))).thenReturn(procStarter); - doReturn(procStarter).when(procStarter) - .stdout(any(OutputStream.class)); - when(procStarter.join()).thenReturn(0); + env = new EnvVars(); + + doReturn(new FilePath(tempDir.getRoot())).when(params).getWorkspace(); + when(params.getLauncher()).thenReturn(launcher); + when(params.getEnvVars()).thenReturn(env); + when(params.getTaskListener()).thenReturn(listener); + when(params.getStartupOptions()).thenReturn(""); + + when(listener.getLogger()).thenReturn(logger); + + doReturn(false).when(launcher).isUnix(); + when(launcher.launch()).thenReturn(procStarter); + when(procStarter.cmds(any(ArgumentListBuilder.class))).thenReturn(procStarter); + when(procStarter.masks(anyBoolean(), anyBoolean(), anyBoolean())) + .thenReturn(procStarter); + when(procStarter.envs(any(EnvVars.class))).thenReturn(procStarter); + doReturn(procStarter).when(procStarter) + .stdout(any(OutputStream.class)); + when(procStarter.join()).thenReturn(0); } @Test @@ -88,13 +92,13 @@ public void constructorUsesParamsForTempFolder() throws IOException, Interrupted verify(params, times(1)).getWorkspace(); } - @Test + @Test public void correctTempFolderLocation() throws IOException, InterruptedException { runner = new MatlabCommandRunner(params); FilePath tmp = runner.getTempFolder(); FilePath expected = WorkspaceList.tempDir(new FilePath(tempDir.getRoot())); - + Assert.assertTrue(tmp.exists()); Assert.assertThat( tmp.getRemote(), @@ -127,9 +131,9 @@ public void prepareRunnerExecutableMaci() throws IOException, InterruptedExcepti Assert.assertTrue(f.exists()); Assert.assertEquals( - runner.getTempFolder().getRemote() - + File.separator - + "run-matlab-command", + runner.getTempFolder().getRemote() + + File.separator + + "run-matlab-command", f.getRemote()); } @@ -137,26 +141,26 @@ public void prepareRunnerExecutableMaci() throws IOException, InterruptedExcepti public void prepareRunnerExecutableMaca() throws IOException, InterruptedException { runner = new MatlabCommandRunner(params); - doReturn(true).when(launcher).isUnix(); + doReturn(true).when(launcher).isUnix(); when(procStarter.stdout(any(OutputStream.class))).thenAnswer( - new Answer() { - public Object answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - OutputStream s = (OutputStream)args[0]; + new Answer() { + public Object answer(InvocationOnMock invocation) throws IOException { + Object[] args = invocation.getArguments(); + OutputStream s = (OutputStream) args[0]; - String tag = "arm64"; - s.write(tag.getBytes()); - return procStarter; - } - }); + String tag = "arm64"; + s.write(tag.getBytes()); + return procStarter; + } + }); FilePath f = runner.prepareRunnerExecutable(); Assert.assertTrue(f.exists()); Assert.assertEquals( - runner.getTempFolder().getRemote() - + File.separator - + "run-matlab-command", + runner.getTempFolder().getRemote() + + File.separator + + "run-matlab-command", f.getRemote()); } @@ -164,26 +168,26 @@ public Object answer(InvocationOnMock invocation) throws IOException { public void prepareRunnerExecutableLinux() throws IOException, InterruptedException { runner = new MatlabCommandRunner(params); - doReturn(true).when(launcher).isUnix(); + doReturn(true).when(launcher).isUnix(); when(procStarter.stdout(any(OutputStream.class))).thenAnswer( - new Answer() { - public Object answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - OutputStream s = (OutputStream)args[0]; + new Answer() { + public Object answer(InvocationOnMock invocation) throws IOException { + Object[] args = invocation.getArguments(); + OutputStream s = (OutputStream) args[0]; - String tag = "Linux"; - s.write(tag.getBytes()); - return procStarter; - } - }); + String tag = "Linux"; + s.write(tag.getBytes()); + return procStarter; + } + }); FilePath f = runner.prepareRunnerExecutable(); Assert.assertTrue(f.exists()); Assert.assertEquals( - runner.getTempFolder().getRemote() - + File.separator - + "run-matlab-command", + runner.getTempFolder().getRemote() + + File.separator + + "run-matlab-command", f.getRemote()); } @@ -196,8 +200,8 @@ public void prepareRunnerExecutableWindows() throws IOException, InterruptedExce Assert.assertTrue(f.exists()); Assert.assertEquals( runner.getTempFolder().getRemote() - + File.separator - + "run-matlab-command.exe", + + File.separator + + "run-matlab-command.exe", f.getRemote()); } @@ -209,7 +213,7 @@ public void createFileWithContentWorks() throws IOException, InterruptedExceptio FilePath f = runner.createFileWithContent(content); String expected = "cd(getenv('MW_ORIG_WORKING_FOLDER'));\n" - + content; + + content; Assert.assertTrue(f.exists()); Assert.assertThat(f.getRemote(), @@ -220,11 +224,11 @@ public void createFileWithContentWorks() throws IOException, InterruptedExceptio @Test public void copyFileFromResourcePathWorks() throws IOException, InterruptedException { runner = new MatlabCommandRunner(params); - + FilePath f = runner.copyFileToTempFolder("testcontent.txt", "target.txt"); Assert.assertTrue(f.exists()); - Assert.assertThat(f.readToString(), startsWith("This has text!")); + Assert.assertThat(f.readToString(), startsWith("This has text!")); } @Test @@ -235,11 +239,11 @@ public void runWorksInBasicCase() throws IOException, InterruptedException, Matl runner.runMatlabCommand(myCommand); String exe = runner.getTempFolder().getRemote() - + File.separator - + "run-matlab-command.exe"; + + File.separator + + "run-matlab-command.exe"; String cmd = "setenv('MW_ORIG_WORKING_FOLDER', cd('" - + runner.getTempFolder().getRemote() - + "'));script_"; + + runner.getTempFolder().getRemote() + + "'));script_"; ArgumentCaptor captor = ArgumentCaptor.forClass(ArgumentListBuilder.class); verify(procStarter).cmds(captor.capture()); @@ -253,7 +257,7 @@ public void runWorksInBasicCase() throws IOException, InterruptedException, Matl @Test public void runUsesWorkspaceLocationAsWD() throws IOException, InterruptedException, MatlabExecutionException { runner = new MatlabCommandRunner(params); - + runner.runMatlabCommand("COMMAND"); verify(procStarter).pwd(new FilePath(tempDir.getRoot())); @@ -266,7 +270,7 @@ public void runWorksWithAddedEnvVars() throws IOException, InterruptedException, String myCommand = "OBEY"; runner.addEnvironmentVariable("MYVAR", "MYVALUE"); runner.runMatlabCommand(myCommand); - + ArgumentCaptor captor = ArgumentCaptor.forClass(EnvVars.class); verify(procStarter).envs(captor.capture()); @@ -285,16 +289,16 @@ public void runShouldExpandAddedEnvVars() throws IOException, InterruptedExcepti Assert.assertThat(f.readToString(), containsString(myCommand)); } - @Test + @Test public void runWorksWithStartupOptions() throws IOException, InterruptedException, MatlabExecutionException { runner = new MatlabCommandRunner(params); doReturn("-nojvm -logfile mylog.log") - .when(params).getStartupOptions(); + .when(params).getStartupOptions(); String myCommand = "OBEY"; runner.runMatlabCommand(myCommand); - + ArgumentCaptor captor = ArgumentCaptor.forClass(ArgumentListBuilder.class); verify(procStarter).cmds(captor.capture()); @@ -305,7 +309,7 @@ public void runWorksWithStartupOptions() throws IOException, InterruptedExceptio Assert.assertEquals("mylog.log", cmds.get(4)); } - @Test + @Test public void runWorksWithRedirectedOutput() throws IOException, InterruptedException, MatlabExecutionException { OutputStream out = mock(OutputStream.class); diff --git a/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTester.java b/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTester.java index d8502b8e..799e81ea 100644 --- a/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTester.java +++ b/src/test/java/unit/com/mathworks/ci/utilities/MatlabCommandRunnerTester.java @@ -2,7 +2,6 @@ /** * Copyright 2024, The MathWorks Inc. - * */ import java.io.IOException; @@ -10,17 +9,17 @@ import com.mathworks.ci.parameters.MatlabActionParameters; public class MatlabCommandRunnerTester extends MatlabCommandRunner { - public MatlabCommandRunnerTester(MatlabActionParameters params) throws IOException, InterruptedException { - super(params); - } + public MatlabCommandRunnerTester(MatlabActionParameters params) throws IOException, InterruptedException { + super(params); + } - @Override - public FilePath prepareRunnerExecutable() throws IOException, InterruptedException { - return super.prepareRunnerExecutable(); - } + @Override + public FilePath prepareRunnerExecutable() throws IOException, InterruptedException { + return super.prepareRunnerExecutable(); + } - @Override - public FilePath createFileWithContent(String content) throws IOException, InterruptedException { + @Override + public FilePath createFileWithContent(String content) throws IOException, InterruptedException { return super.createFileWithContent(content); - } + } } diff --git a/src/test/resources/testconfig.properties b/src/test/resources/testconfig.properties index 9a075b9e..d01de454 100644 --- a/src/test/resources/testconfig.properties +++ b/src/test/resources/testconfig.properties @@ -10,4 +10,11 @@ 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. Buildwrapper.display.name = Add MATLAB to PATH Builder.matlab.script.builder.display.name = Run MATLAB Command -Builder.build.builder.display.name = Run MATLAB Build \ No newline at end of file +Builder.build.builder.display.name = Run MATLAB Build + +tools.matlab.mpm.installer.win = https://www.mathworks.com/mpm/win64/mpm +tools.matlab.batch.executable.win = https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/win64/matlab-batch.exe +tools.matlab.mpm.installer.linux = https://www.mathworks.com/mpm/glnxa64/mpm +tools.matlab.batch.executable.linux = https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/glnxa64/matlab-batch +tools.matlab.mpm.installer.mac = https://www.mathworks.com/mpm/maci64/mpm +tools.matlab.batch.executable.mac = https://ssd.mathworks.com/supportfiles/ci/matlab-batch/v1/maci64/matlab-batch \ No newline at end of file