Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Enhance Build and Test Results Visualization using Service Messages #39

Merged
merged 5 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
tsharmaMW marked this conversation as resolved.
Show resolved Hide resolved
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,22 @@
classdef BuildVisualizationPlugin < matlab.buildtool.plugins.BuildRunnerPlugin

% Copyright 2025 The MathWorks, Inc.

methods (Access=protected)

function runTaskGraph(plugin, pluginData)
[email protected](plugin, pluginData);
end
tsharmaMW marked this conversation as resolved.
Show resolved Hide resolved

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
tsharmaMW marked this conversation as resolved.
Show resolved Hide resolved

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
Loading