-
Notifications
You must be signed in to change notification settings - Fork 6
Add CircleCI Test Split Feature #75
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
Changes from all commits
7610ecb
526f157
febb8e2
7dbbdef
d682469
39cd967
3a6a396
e08d1cd
4758dd1
99c76cd
c52ff68
510f9e9
75de0ac
ac727d0
c393864
d50d5ff
52254ba
0654224
a8356cf
de8a044
aab59fb
5056ebf
f141947
96a529b
5a5b638
4f338f0
ec429bf
f8047e5
54ea8cd
c378673
ae4eb36
613ec1b
d2ba42e
ecdb3e3
be290bb
ab1c2fb
02c2c68
ed5ebb2
c0456ba
f9617e8
d5bcfcb
8f4e5c7
3fa1db8
58c3b56
8f7cd07
c3b21b5
b768b73
6a3b3d5
ccbf09e
f09ab1d
f765f7f
6b53445
ca9df3b
8578bdd
36ec8b0
91d1337
cd2effa
c63baa4
d2f9c5c
b5f4abe
a48de06
8171ad6
b794f1d
ff7c1e6
060aa26
373e739
0cb199f
5f8e467
c323a93
b478eae
80d072b
3f29020
a05055e
73cea78
97ac3a2
9708584
bac7f78
80bbfa3
4c82a26
a18ace5
28bb8bc
64a7b7c
33fb55f
5346737
edfb986
14d1254
6c60d20
00fd6e4
1ee91ac
f0fbe5d
4270495
adebee2
8ee933c
558184b
f4f7714
9fad01b
96e7ff1
d6c556b
ceb2d23
cf1a349
cf45473
624f509
aefeaaf
1d4e1f0
fdab687
3dbf876
06d3fcc
b5dbfa4
7a9146b
5f2f74b
dc798bd
0b33024
637adf0
078938a
21b3fbf
8614c43
af26bfa
60ae038
a227e1b
a58a74e
4c42169
a510779
56e83a3
5eaf3d4
f76d8e7
6ac2d94
cf6f515
3dae86f
1132032
5bd7a85
427e09c
3c7eb25
2efc5f9
3c02b20
46c0314
de4ea03
5b79532
57f155a
7760e50
300e623
9dd2203
68dfb3f
b2f3ac4
cb0eab2
881182a
8029554
449219e
fd08133
b2f4674
7c2ddd4
1f32b3a
568f635
c126d10
034673f
7d8854f
5f63500
cfb676a
f4074dc
1dfbf50
0201068
4394233
674c64c
f7397aa
8d5b821
9d6d1e6
9116c26
d65d677
0e3d909
4c19030
173dec6
d33f3a5
17b4066
e7c3ec4
46bfa92
126ee59
7d1d298
9348bf5
60676d3
9c1fc0b
dc9853e
d45dbe4
ae90128
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
version: 2.1 | ||
version: 2.1 | ||
vanditaMW marked this conversation as resolved.
Show resolved
Hide resolved
|
||
orbs: | ||
matlab: mathworks/matlab@dev:<<pipeline.git.revision>> | ||
orb-tools: circleci/[email protected] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
function finalStatement= generateFolderSelectionStatement(statement) | ||
vanditaMW marked this conversation as resolved.
Show resolved
Hide resolved
vanditaMW marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import scriptgen.internal.unquoteText; | ||
import scriptgen.internal.isAbsolutePath; | ||
|
||
statement = strtrim(strsplit(statement, {';', ':'})); | ||
statement = cellfun(@(t) ['''' t ''''], strrep(statement, '''', ''''''), 'UniformOutput', false); | ||
|
||
constraints = {}; | ||
|
||
for i = 1:numel(statement) | ||
folder = statement{i}; | ||
|
||
if ~strcmp(folder, unquoteText(folder)) && ~isAbsolutePath(unquoteText(folder)) | ||
constraint = sprintf('StartsWithSubstring(fullfile(pwd, %s))', folder); | ||
else | ||
constraint = sprintf('StartsWithSubstring(%s)', folder); | ||
end | ||
|
||
constraints{end+1} = constraint; %#ok<AGROW> | ||
end | ||
|
||
statement = sprintf('HasBaseFolder(%s)', strjoin(constraints, ' | ')); | ||
finalStatement = sprintf('suite = suite.selectIf(%s);', statement); | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
function stdout = getCircleCISplitFiles(paramSplitType, paramSelectByTag, paramSelectByFolder, paramSourceFolder) | ||
% getCircleCISplitFiles - splits test files using CircleCI split command. | ||
% | ||
% The getCircleCISplitFiles function provides a convenient way to | ||
% split test files based on specified parameters. | ||
% | ||
% STDOUT = getCircleCISplitFiles(PARAMSPLITTYPE, PARAMSELECTBYTAG, | ||
% PARAMSELECTBYFOLDER, PARAMSOURCEFOLDER) generates and returns a list of | ||
% split test files. The parameters are as follows: | ||
% - PARAMSPLITTYPE: The type of split (e.g., 'timings', 'filename' or 'filesize'). | ||
% - PARAMSELECTBYTAG: A tag to filter tests by. | ||
% - PARAMSELECTBYFOLDER: folder(s) to filter tests by. | ||
% - PARAMSOURCEFOLDER: The source folder(s) to add to the path. | ||
% | ||
% These parameters are used to update the test suite and extract the list | ||
% of MATLAB test files to be passed to the CircleCI test split command. | ||
% | ||
% Examples: | ||
% | ||
% resultFiles = getCircleCISplitFiles('timings', 'MyTag', 'MyFolder', 'src'); | ||
% disp(resultFiles); | ||
|
||
|
||
import matlab.unittest.selectors.HasTag; | ||
import matlab.unittest.constraints.StartsWithSubstring; | ||
import matlab.unittest.plugins.XMLPlugin; | ||
import matlab.unittest.selectors.HasBaseFolder; | ||
|
||
if ~isempty(paramSourceFolder) | ||
dirs = strtrim(strsplit(paramSourceFolder, {';', ':'})); | ||
for i = numel(dirs):-1:1 | ||
statement{i} = sprintf('addpath(genpath(''%s''));', strrep(dirs{i}, '''', '''''')); | ||
eval(statement{i}); | ||
end | ||
end | ||
|
||
suite = testsuite(pwd, 'IncludingSubfolders', true); | ||
|
||
if ~isempty(paramSelectByTag) | ||
Statement = sprintf('suite = suite.selectIf(HasTag(''%s''));', paramSelectByTag); | ||
eval(Statement); | ||
end | ||
|
||
if ~isempty(paramSelectByFolder) | ||
Statement = generateFolderSelectionStatement(paramSelectByFolder); | ||
eval(Statement); | ||
end | ||
|
||
testFilePaths = {}; | ||
|
||
for i = 1:numel(suite) | ||
baseFolder = suite(i).BaseFolder; | ||
relativePath = strrep(baseFolder, [pwd, filesep], ''); | ||
testClass = suite(i).TestParentName; | ||
|
||
if isstring(testClass) | ||
testClass = char(testClass); | ||
end | ||
|
||
testFilePath = fullfile(relativePath, strcat(testClass, '.m')); | ||
testFilePaths{end+1} = testFilePath; | ||
end | ||
|
||
testNames= unique(testFilePaths); | ||
|
||
if strcmp(paramSplitType, 'timings') | ||
[~, testNames, ~] = cellfun(@fileparts, testNames, 'UniformOutput', false); | ||
end | ||
|
||
tempAllFile = tempname; | ||
tempErrorFile = tempname; | ||
fid = fopen(tempAllFile, 'w'); | ||
fprintf(fid, '%s\n', testNames{:}); | ||
fclose(fid); | ||
|
||
if strcmp(paramSplitType, 'filename') | ||
command = sprintf('circleci tests split %s 2> %s', tempAllFile, tempErrorFile); | ||
else | ||
command = sprintf('circleci tests split --split-by=%s %s 2> %s', paramSplitType, tempAllFile, tempErrorFile); | ||
end | ||
[~, stdout] = system(command); | ||
|
||
stderr = fileread(tempErrorFile); | ||
disp(stderr); | ||
|
||
|
||
stdout = strsplit(stdout, '\n'); | ||
stdout = stdout(~cellfun('isempty', stdout)); | ||
stdout = strtrim(stdout); | ||
stdout = stdout(:)'; | ||
[~, stdout, ~] = cellfun(@fileparts, stdout, 'UniformOutput', false); | ||
|
||
delete(tempAllFile); | ||
delete(tempErrorFile); | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,11 @@ parameters: | |
parameter requires a Parallel Computing Toolbox license. | ||
type: boolean | ||
default: false | ||
split-type: | ||
vanditaMW marked this conversation as resolved.
Show resolved
Hide resolved
|
||
description: > | ||
Option to use CircleCI Test Split feature, specified as 'timings', 'filename' or 'filesize'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to use the same terminology as in CircleCI documentation. Instead of "CircleCI Test Split feature" CircleCI uses "CircleCI test splitting" in their documentation: https://circleci.com/docs/parallelism-faster-jobs/#:~:text=CircleCI%20test%20splitting The information in this description is minimal. For example, it doesn't say anything about the Also, it might be good to clarify how one should use the new parameter alongside |
||
type: string | ||
default: '' | ||
vanditaMW marked this conversation as resolved.
Show resolved
Hide resolved
|
||
output-detail: | ||
description: > | ||
Amount of event detail displayed for the test run, specified as `none`, `terse`, `concise`, `detailed`, | ||
|
@@ -128,6 +133,7 @@ steps: | |
PARAM_TEST_RESULTS_PDF: <<parameters.test-results-pdf>> | ||
PARAM_STRICT: <<parameters.strict>> | ||
PARAM_USE_PARALLEL: <<parameters.use-parallel>> | ||
PARAM_SPLIT_TYPE: <<parameters.split-type>> | ||
PARAM_OUTPUT_DETAIL: <<parameters.output-detail>> | ||
PARAM_LOGGING_LEVEL: <<parameters.logging-level>> | ||
PARAM_STARTUP_OPTIONS: <<parameters.startup-options>> | ||
|
Uh oh!
There was an error while loading. Please reload this page.