Skip to content

Commit

Permalink
Enhance Build and Test Results Visualization using Service Messages (#39
Browse files Browse the repository at this point in the history
)
  • Loading branch information
tsharmaMW authored Jan 29, 2025
1 parent 63147dd commit 1fb5bde
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -23,6 +24,11 @@

public class MatlabCommandRunner {
private File tempDirectory;
private Map<String,String> additionalEnvVars;

public MatlabCommandRunner() {
this.additionalEnvVars = new HashMap<String,String>();
}

public void setTempDirectory(File dir) {
this.tempDirectory = dir;
Expand All @@ -45,6 +51,14 @@ public ProgramCommandLine createCommand(BuildRunnerContext runnerContext, String
//Add MATLAB to PATH Variable
addToPath(runnerContext, matlabPath);

//Add custom environment variables
for (Map.Entry<String, String> envVar : additionalEnvVars.entrySet()) {
String key = envVar.getKey();
String value = envVar.getValue();

runnerContext.addEnvironmentVariable(key, value);
}

return new SimpleProgramCommandLine(runnerContext, executable, command);
}

Expand Down Expand Up @@ -76,7 +90,7 @@ private void createMatlabScriptByName(BuildRunnerContext runnerContext, String c
final File matlabCommandFile =
new File(this.tempDirectory, uniqueScriptName + ".m");
final String matlabCommandFileContent =
"cd(getenv('MW_ORIG_WORKING_FOLDER'));\n" + command;
"cd(getenv('MW_ORIG_WORKING_FOLDER'));\n" + "addpath('" + this.tempDirectory + "');\n" + command;

FileUtils.writeStringToFile(matlabCommandFile, matlabCommandFileContent);
}
Expand Down Expand Up @@ -120,6 +134,34 @@ public void unzipToTempDir(String zipName) throws IOException {
ZipFile zipFile = new ZipFile(zipFileLocation);
zipFile.extractAll(tempDirectory.toString());
}

public void addEnvironmentVariable(String key, String value) {
additionalEnvVars.put(key, value);
}

public void copyBuildPluginsToTemp() throws IOException{
copyPluginsToTempDir(MatlabConstants.DEFAULT_PLUGIN);
copyPluginsToTempDir(MatlabConstants.BUILD_VISUALIZATION_PLUGIN);
}

public void copyTestPluginsToTemp() throws IOException{
copyPluginsToTempDir(MatlabConstants.TEST_VISUALIZATION_PLUGIN);
copyPluginsToTempDir(MatlabConstants.TEST_VISUALIZATION_PLUGIN_SERVICE);
}

public void copyPluginsToTempDir(String pluginName) throws IOException{
File pluginFileLocation = new File(this.tempDirectory, pluginName);

// Ensure the directory structure exists
File parentDir = pluginFileLocation.getParentFile();
if (!parentDir.exists()) {
if (!parentDir.mkdirs()) {
throw new IOException("Failed to create directories: " + parentDir);
}
}

copyFileToWorkspace(pluginName, pluginFileLocation);
}

public void copyFileToWorkspace(String sourceFile, File targetFile) throws IOException {
InputStream is = MatlabCommandRunner.class.getClassLoader().getResourceAsStream(sourceFile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public ProgramCommandLine makeProgramCommandLine() throws RunBuildException {
if (!getBuildOptions().isEmpty()){
cmd += " " + getBuildOptions();
}
this.runner.copyBuildPluginsToTemp();
this.runner.copyTestPluginsToTemp();
// Set build environment variable
this.runner.addEnvironmentVariable("MW_MATLAB_BUILDTOOL_DEFAULT_PLUGINS_FCN_OVERRIDE","ciplugins.teamcity.getDefaultPlugins");
value = this.runner.createCommand(getContext(), cmd);
} catch (Exception e) {
throw new RunBuildException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public ProgramCommandLine makeProgramCommandLine() throws RunBuildException {

ProgramCommandLine value;
try {
this.runner.copyBuildPluginsToTemp();
this.runner.copyTestPluginsToTemp();
// Set build environment variable
this.runner.addEnvironmentVariable("MW_MATLAB_BUILDTOOL_DEFAULT_PLUGINS_FCN_OVERRIDE","ciplugins.teamcity.getDefaultPlugins");
value = this.runner.createCommand(getContext(), getMatlabCommand());
} catch (Exception e) {
throw new RunBuildException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public ProgramCommandLine makeProgramCommandLine() throws RunBuildException {
ProgramCommandLine value;
try {
this.runner.unzipToTempDir(MatlabConstants.MATLAB_SCRIPT_GENERATOR);
this.runner.copyTestPluginsToTemp();
value = this.runner.createCommand(getContext(), runnerScript);
} catch (Exception e) {
throw new RunBuildException(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
classdef BuildVisualizationPlugin < matlab.buildtool.plugins.BuildRunnerPlugin

% Copyright 2025 The MathWorks, Inc.

methods (Access=protected)

function runTask(plugin, pluginData)
disp("##teamcity[blockOpened name ='" + pluginData.TaskResults.Name + "']");
disp("##teamcity[progressStart 'Running " + pluginData.TaskResults.Name + " Task']");

[email protected](plugin, pluginData);

disp("##teamcity[progressFinish 'Running " + pluginData.TaskResults.Name + " Task']");
disp("##teamcity[blockClosed name ='" + pluginData.TaskResults.Name + "']");
end

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
classdef TestVisualizationPlugin < matlab.unittest.plugins.TestRunnerPlugin

% Copyright 2025 The MathWorks, Inc.

methods (Access=protected)

function runTest(plugin, pluginData)
classAndTestName = strrep(pluginData.Name,"/",".");

fprintf("##teamcity[testStarted name='%s' captureStandardOutput='true']", classAndTestName)

% Invoke super class method to run the test
[email protected](plugin, pluginData);

result = pluginData.TestResult;

if result.Failed
fprintf("##teamcity[testFailed name='%s' status='ERROR']", classAndTestName);
elseif result.Incomplete
fprintf("##teamcity[testIgnored name='%s']", classAndTestName);
end

fprintf("##teamcity[testFinished name='%s' duration='%f']", classAndTestName, result.Duration)
end

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function plugins = getDefaultPlugins(pluginProviderData)

% Copyright 2025 The MathWorks, Inc.

arguments
pluginProviderData (1,1) struct = struct();
end

plugins = [ ...
matlab.buildtool.internal.getFactoryDefaultPlugins(pluginProviderData) ...
ciplugins.teamcity.BuildVisualizationPlugin() ...
];
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
classdef TestVisualizationPluginService < matlab.buildtool.internal.services.ciplugins.CITestRunnerPluginService
% Copyright 2025 The MathWorks, Inc.

methods
function plugins = providePlugins(~, ~)
plugins = ciplugins.teamcity.TestVisualizationPlugin();
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public void verifyScriptCreated() throws IOException, NoSuchMethodException, Ill
expectedCommand.add("setenv('MW_ORIG_WORKING_FOLDER', cd('"
+ currDir.getPath().replaceAll("'", ";;")
+ "'));" + "matlab_" + currDir.getName());

Method generateCommandArgs = getAccessibleMethod("generateCommandArgs", BuildRunnerContext.class, String.class);

Object actualCommand = generateCommandArgs.invoke(runner, context, command);
Expand All @@ -162,7 +162,7 @@ public void verifyScriptCreated() throws IOException, NoSuchMethodException, Ill
Assert.assertTrue(expectedFile.exists());

String contents = FileUtils.readFileToString(expectedFile);
Assert.assertEquals(contents, "cd(getenv('MW_ORIG_WORKING_FOLDER'));\n" + command);
Assert.assertEquals(contents, "cd(getenv('MW_ORIG_WORKING_FOLDER'));\naddpath('" + currDir.getPath() + "');\n" + command);
}

// startup options test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public interface MatlabConstants {
static final String RUN_EXE_MACI = "maci64/run-matlab-command";
static final String RUN_EXE_LINUX = "glnxa64/run-matlab-command";
static final String MATLAB_SCRIPT_GENERATOR = "matlab-script-generator.zip";

// MATLAB default plugin paths
static final String DEFAULT_PLUGIN = "+ciplugins/+teamcity/getDefaultPlugins.m";
static final String BUILD_VISUALIZATION_PLUGIN = "+ciplugins/+teamcity/BuildVisualizationPlugin.m";
static final String TEST_VISUALIZATION_PLUGIN = "+ciplugins/+teamcity/TestVisualizationPlugin.m";
static final String TEST_VISUALIZATION_PLUGIN_SERVICE = "+matlab/+unittest/+internal/+services/+plugins/TestVisualizationPluginService.m";

//Test runner file prefix
static final String MATLAB_TEST_RUNNER_FILE_PREFIX = "runner_";

Expand Down

0 comments on commit 1fb5bde

Please sign in to comment.