Skip to content

Commit aa23b76

Browse files
mw-kapilgclaude
andauthored
Add session file sorting and additional tests (#48)
* store test results in separate files * fix serialization issue * skip rendering empty test session tables Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * remove extra env var * add test session sub-heading * add file sorting and more tests --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bf7b785 commit aa23b76

5 files changed

Lines changed: 311 additions & 60 deletions

File tree

src/main/java/com/mathworks/ci/TestResultsViewAction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import java.nio.file.Path;
1616
import java.nio.file.Paths;
1717
import java.util.ArrayList;
18+
import java.util.Arrays;
19+
import java.util.Comparator;
1820
import java.util.HashMap;
1921
import java.util.Iterator;
2022
import java.util.List;
@@ -84,6 +86,7 @@ public List<List<MatlabTestFile>> getTestResults() throws ParseException, Interr
8486
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + this.actionID + "_*.json");
8587

8688
if (sessionFiles.length > 0) {
89+
Arrays.sort(sessionFiles, Comparator.comparing(FilePath::getName));
8790
for (FilePath sessionFile : sessionFiles) {
8891
parseSessionFile(sessionFile, testResults);
8992
}

src/test/java/com/mathworks/ci/TestResultsViewActionTest.java

Lines changed: 104 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public void verifyMatlabTestFilePath() throws ExecutionException, InterruptedExc
170170
} else {
171171
throw new RuntimeException("Unsupported OS: " + os);
172172
}
173-
173+
174174
List<List<MatlabTestFile>> ta = ac.getTestResults();
175175
String actualPath1 = ta.get(0).get(0).getPath();
176176
Assert.assertEquals("Incorrect test file path",expectedParentPath + "tests" + File.separator + "TestExamples1",actualPath1);
@@ -187,7 +187,7 @@ public void verifyMatlabTestFilePath() throws ExecutionException, InterruptedExc
187187
public void verifyMatlabTestFileLinuxStylePath() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
188188
TestResultsViewAction ac = setupTestResultsViewAction();
189189
String expectedParentPath = "visualization/";
190-
190+
191191
List<List<MatlabTestFile>> ta = ac.getTestResults();
192192
String actualPath1 = ta.get(0).get(0).getLinuxStylePath();
193193
Assert.assertEquals("Incorrect test file path",expectedParentPath + "tests/" + "TestExamples1",actualPath1);
@@ -312,7 +312,7 @@ public void verifyMatlabTestCaseDuration() throws ExecutionException, Interrupte
312312
public void verifyMatlabTestCaseDiagnostics() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
313313
TestResultsViewAction ac = setupTestResultsViewAction();
314314
List<List<MatlabTestFile>> ta = ac.getTestResults();
315-
315+
316316
MatlabTestDiagnostics diagnostics1 = ta.get(0).get(0).getMatlabTestCases().get(4).getDiagnostics().get(0);
317317
String actualDiagnosticsEvent1 = diagnostics1.getEvent();
318318
Assert.assertEquals("Incorrect test diagnostics event","SampleDiagnosticsEvent1",actualDiagnosticsEvent1);
@@ -348,6 +348,73 @@ public void verifyLegacySingleFileFormat() throws ExecutionException, Interrupte
348348
Assert.assertEquals("Incorrect failed tests count", 3, ac.getFailedCount());
349349
}
350350

351+
@Test
352+
public void verifySingleSessionReturnsOneSession() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
353+
TestResultsViewAction ac = setupTestResultsViewActionFromFiles("t1",
354+
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + "abc123_20260101_120000_001.json");
355+
List<List<MatlabTestFile>> ta = ac.getTestResults();
356+
Assert.assertEquals("Should return exactly 1 session", 1, ta.size());
357+
Assert.assertEquals("Incorrect test files", 1, ta.get(0).size());
358+
Assert.assertEquals("Incorrect test results", 9, ta.get(0).get(0).getMatlabTestCases().size());
359+
Assert.assertEquals("Incorrect total count", 9, ac.getTotalCount());
360+
Assert.assertEquals("Incorrect passed count", 4, ac.getPassedCount());
361+
Assert.assertEquals("Incorrect failed count", 3, ac.getFailedCount());
362+
Assert.assertEquals("Incorrect incomplete count", 1, ac.getIncompleteCount());
363+
Assert.assertEquals("Incorrect not run count", 1, ac.getNotRunCount());
364+
}
365+
366+
@Test
367+
public void verifySingleObjectSessionFile() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
368+
TestResultsViewAction ac = setupTestResultsViewActionFromFiles("t1",
369+
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + "abc123_20260101_120000_002.json");
370+
List<List<MatlabTestFile>> ta = ac.getTestResults();
371+
Assert.assertEquals("Should return exactly 1 session", 1, ta.size());
372+
Assert.assertEquals("Incorrect test files", 1, ta.get(0).size());
373+
Assert.assertEquals("Incorrect test results", 1, ta.get(0).get(0).getMatlabTestCases().size());
374+
375+
MatlabTestFile testFile = ta.get(0).get(0);
376+
Assert.assertEquals("Incorrect test file name", "TestExamples2", testFile.getName());
377+
Assert.assertEquals("Incorrect test file status", TestStatus.INCOMPLETE, testFile.getStatus());
378+
379+
MatlabTestCase testCase = testFile.getMatlabTestCases().get(0);
380+
Assert.assertEquals("Incorrect test case name", "testNonLeapYear", testCase.getName());
381+
Assert.assertEquals("Incorrect test case status", TestStatus.INCOMPLETE, testCase.getStatus());
382+
Assert.assertEquals("Incorrect test case duration", new BigDecimal("0.10"), testCase.getDuration());
383+
Assert.assertEquals("Should have 1 diagnostic", 1, testCase.getDiagnostics().size());
384+
Assert.assertEquals("Incorrect diagnostic event", "SampleDiagnosticsEvent2", testCase.getDiagnostics().get(0).getEvent());
385+
Assert.assertEquals("Incorrect diagnostic report", "SampleDiagnosticsReport2", testCase.getDiagnostics().get(0).getReport());
386+
}
387+
388+
@Test
389+
public void verifyMultipleDiagnosticsAndDurationRounding() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
390+
TestResultsViewAction ac = setupTestResultsViewActionFromFiles("t3",
391+
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + "abc123_20260101_120000_001.json");
392+
List<List<MatlabTestFile>> ta = ac.getTestResults();
393+
Assert.assertEquals("Should return exactly 1 session", 1, ta.size());
394+
Assert.assertEquals("Incorrect test files", 1, ta.get(0).size());
395+
Assert.assertEquals("Incorrect test results", 5, ta.get(0).get(0).getMatlabTestCases().size());
396+
397+
MatlabTestCase multiDiagCase = ta.get(0).get(0).getMatlabTestCases().get(0);
398+
Assert.assertEquals("Incorrect test case name", "testMultipleDiags", multiDiagCase.getName());
399+
Assert.assertEquals("Incorrect test case status", TestStatus.FAILED, multiDiagCase.getStatus());
400+
Assert.assertEquals("Should have 2 diagnostics", 2, multiDiagCase.getDiagnostics().size());
401+
Assert.assertEquals("Incorrect first diagnostic event", "DiagEvent1", multiDiagCase.getDiagnostics().get(0).getEvent());
402+
Assert.assertEquals("Incorrect first diagnostic report", "First diagnostic report", multiDiagCase.getDiagnostics().get(0).getReport());
403+
Assert.assertEquals("Incorrect second diagnostic event", "DiagEvent2", multiDiagCase.getDiagnostics().get(1).getEvent());
404+
Assert.assertEquals("Incorrect second diagnostic report", "Second diagnostic report", multiDiagCase.getDiagnostics().get(1).getReport());
405+
406+
MatlabTestCase rounding1 = ta.get(0).get(0).getMatlabTestCases().get(2);
407+
Assert.assertEquals("Duration should round to 2 decimal places", new BigDecimal("0.11"), rounding1.getDuration());
408+
MatlabTestCase rounding2 = ta.get(0).get(0).getMatlabTestCases().get(3);
409+
Assert.assertEquals("Duration should round to 2 decimal places", new BigDecimal("1.00"), rounding2.getDuration());
410+
MatlabTestCase rounding3 = ta.get(0).get(0).getMatlabTestCases().get(4);
411+
Assert.assertEquals("Duration should round to 2 decimal places", new BigDecimal("0.01"), rounding3.getDuration());
412+
413+
Assert.assertEquals("Incorrect total count", 5, ac.getTotalCount());
414+
Assert.assertEquals("Incorrect passed count", 4, ac.getPassedCount());
415+
Assert.assertEquals("Incorrect failed count", 1, ac.getFailedCount());
416+
}
417+
351418
@Test
352419
public void verifyTestResultWithMissingDetails() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
353420
TestResultsViewAction ac = setupTestResultsViewActionWithMissingDetails();
@@ -367,85 +434,62 @@ public void verifyTestResultWithMissingDetails() throws ExecutionException, Inte
367434
}
368435

369436
private TestResultsViewAction setupTestResultsViewActionWithMissingDetails() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
437+
return setupTestResultsViewActionFromFiles("t2",
438+
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + "abc123_20260101_120000_001.json");
439+
}
440+
441+
private TestResultsViewAction setupTestResultsViewAction() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
442+
return setupTestResultsViewActionFromFiles("t1",
443+
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + "abc123_20260101_120000_001.json",
444+
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + "abc123_20260101_120000_002.json");
445+
}
446+
447+
private TestResultsViewAction setupTestResultsViewActionLegacy() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
370448
FreeStyleBuild build = getFreestyleBuild();
371449
final String actionID = "abc123";
450+
final String targetFile = MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + ".json";
372451
FilePath artifactRoot = new FilePath(build.getRootDir());
373-
374-
String os = System.getProperty("os.name").toLowerCase();
375-
String osName = "";
376-
String workspaceParent = "";
377-
if (os.contains("win")) {
378-
osName = "windows";
379-
workspaceParent = "C:\\";
380-
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
381-
osName = "linux";
382-
workspaceParent = "/home/user/";
383-
} else if (os.contains("mac")) {
384-
osName = "mac";
385-
workspaceParent = "/Users/username/";
386-
} else {
387-
throw new RuntimeException("Unsupported OS: " + os);
388-
}
389-
final FilePath workspace = new FilePath(new File(workspaceParent + "workspace"));
390-
String resourcePrefix = "testArtifacts/t2/" + osName + "/";
391-
copyFileInWorkspace(resourcePrefix + MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + "_20260101_120000_001.json",
392-
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + "_20260101_120000_001.json", artifactRoot);
452+
String osName = getOsName();
453+
final FilePath workspace = new FilePath(new File(getWorkspaceParent() + "workspace"));
454+
copyFileInWorkspace("testArtifacts/t1/" + osName + "/" + MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + ".json", targetFile, artifactRoot);
393455
return new TestResultsViewAction(build, workspace, actionID);
394456
}
395457

396-
private TestResultsViewAction setupTestResultsViewAction() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
458+
private TestResultsViewAction setupTestResultsViewActionFromFiles(String testDir, String... fileNames) throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
397459
FreeStyleBuild build = getFreestyleBuild();
398460
final String actionID = "abc123";
399461
FilePath artifactRoot = new FilePath(build.getRootDir());
462+
String osName = getOsName();
463+
final FilePath workspace = new FilePath(new File(getWorkspaceParent() + "workspace"));
464+
String resourcePrefix = "testArtifacts/" + testDir + "/" + osName + "/";
465+
for (String fileName : fileNames) {
466+
copyFileInWorkspace(resourcePrefix + fileName, fileName, artifactRoot);
467+
}
468+
return new TestResultsViewAction(build, workspace, actionID);
469+
}
400470

471+
private String getOsName() {
401472
String os = System.getProperty("os.name").toLowerCase();
402-
String osName = "";
403-
String workspaceParent = "";
404473
if (os.contains("win")) {
405-
osName = "windows";
406-
workspaceParent = "C:\\";
474+
return "windows";
407475
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
408-
osName = "linux";
409-
workspaceParent = "/home/user/";
476+
return "linux";
410477
} else if (os.contains("mac")) {
411-
osName = "mac";
412-
workspaceParent = "/Users/username/";
413-
} else {
414-
throw new RuntimeException("Unsupported OS: " + os);
478+
return "mac";
415479
}
416-
final FilePath workspace = new FilePath(new File(workspaceParent + "workspace"));
417-
String resourcePrefix = "testArtifacts/t1/" + osName + "/";
418-
copyFileInWorkspace(resourcePrefix + MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + "_20260101_120000_001.json",
419-
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + "_20260101_120000_001.json", artifactRoot);
420-
copyFileInWorkspace(resourcePrefix + MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + "_20260101_120000_002.json",
421-
MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + "_20260101_120000_002.json", artifactRoot);
422-
return new TestResultsViewAction(build, workspace, actionID);
480+
throw new RuntimeException("Unsupported OS: " + os);
423481
}
424482

425-
private TestResultsViewAction setupTestResultsViewActionLegacy() throws ExecutionException, InterruptedException, URISyntaxException, IOException, ParseException {
426-
FreeStyleBuild build = getFreestyleBuild();
427-
final String actionID = "abc123";
428-
final String targetFile = MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + actionID + ".json";
429-
FilePath artifactRoot = new FilePath(build.getRootDir());
430-
483+
private String getWorkspaceParent() {
431484
String os = System.getProperty("os.name").toLowerCase();
432-
String osName = "";
433-
String workspaceParent = "";
434485
if (os.contains("win")) {
435-
osName = "windows";
436-
workspaceParent = "C:\\";
486+
return "C:\\";
437487
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
438-
osName = "linux";
439-
workspaceParent = "/home/user/";
488+
return "/home/user/";
440489
} else if (os.contains("mac")) {
441-
osName = "mac";
442-
workspaceParent = "/Users/username/";
443-
} else {
444-
throw new RuntimeException("Unsupported OS: " + os);
490+
return "/Users/username/";
445491
}
446-
final FilePath workspace = new FilePath(new File(workspaceParent + "workspace"));
447-
copyFileInWorkspace("testArtifacts/t1/" + osName + "/" + MatlabBuilderConstants.TEST_RESULTS_VIEW_ARTIFACT + ".json", targetFile, artifactRoot);
448-
return new TestResultsViewAction(build, workspace, actionID);
492+
throw new RuntimeException("Unsupported OS: " + os);
449493
}
450494

451495
private FreeStyleBuild getFreestyleBuild() throws ExecutionException, InterruptedException, URISyntaxException {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
[
2+
{
3+
"TestResult": {
4+
"Duration": 0.5,
5+
"Details": {
6+
"DiagnosticRecord": [
7+
{
8+
"Event": "DiagEvent1",
9+
"Report": "First diagnostic report"
10+
},
11+
{
12+
"Event": "DiagEvent2",
13+
"Report": "Second diagnostic report"
14+
}
15+
]
16+
},
17+
"Name": "EdgeCaseTest/testMultipleDiags",
18+
"Passed": false,
19+
"Failed": true,
20+
"Incomplete": false
21+
},
22+
"BaseFolder": "/home/user/workspace/src/tests"
23+
},
24+
{
25+
"TestResult": {
26+
"Duration": 0.3,
27+
"Details": {},
28+
"Name": "EdgeCaseTest/testNoDiag",
29+
"Passed": true,
30+
"Failed": false,
31+
"Incomplete": false
32+
},
33+
"BaseFolder": "/home/user/workspace/src/tests"
34+
},
35+
{
36+
"TestResult": {
37+
"Duration": 0.1111,
38+
"Details": {},
39+
"Name": "EdgeCaseTest/testRounding1",
40+
"Passed": true,
41+
"Failed": false,
42+
"Incomplete": false
43+
},
44+
"BaseFolder": "/home/user/workspace/src/tests"
45+
},
46+
{
47+
"TestResult": {
48+
"Duration": 0.9999,
49+
"Details": {},
50+
"Name": "EdgeCaseTest/testRounding2",
51+
"Passed": true,
52+
"Failed": false,
53+
"Incomplete": false
54+
},
55+
"BaseFolder": "/home/user/workspace/src/tests"
56+
},
57+
{
58+
"TestResult": {
59+
"Duration": 0.005,
60+
"Details": {},
61+
"Name": "EdgeCaseTest/testRounding3",
62+
"Passed": true,
63+
"Failed": false,
64+
"Incomplete": false
65+
},
66+
"BaseFolder": "/home/user/workspace/src/tests"
67+
}
68+
]
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
[
2+
{
3+
"TestResult": {
4+
"Duration": 0.5,
5+
"Details": {
6+
"DiagnosticRecord": [
7+
{
8+
"Event": "DiagEvent1",
9+
"Report": "First diagnostic report"
10+
},
11+
{
12+
"Event": "DiagEvent2",
13+
"Report": "Second diagnostic report"
14+
}
15+
]
16+
},
17+
"Name": "EdgeCaseTest/testMultipleDiags",
18+
"Passed": false,
19+
"Failed": true,
20+
"Incomplete": false
21+
},
22+
"BaseFolder": "/Users/username/workspace/src/tests"
23+
},
24+
{
25+
"TestResult": {
26+
"Duration": 0.3,
27+
"Details": {},
28+
"Name": "EdgeCaseTest/testNoDiag",
29+
"Passed": true,
30+
"Failed": false,
31+
"Incomplete": false
32+
},
33+
"BaseFolder": "/Users/username/workspace/src/tests"
34+
},
35+
{
36+
"TestResult": {
37+
"Duration": 0.1111,
38+
"Details": {},
39+
"Name": "EdgeCaseTest/testRounding1",
40+
"Passed": true,
41+
"Failed": false,
42+
"Incomplete": false
43+
},
44+
"BaseFolder": "/Users/username/workspace/src/tests"
45+
},
46+
{
47+
"TestResult": {
48+
"Duration": 0.9999,
49+
"Details": {},
50+
"Name": "EdgeCaseTest/testRounding2",
51+
"Passed": true,
52+
"Failed": false,
53+
"Incomplete": false
54+
},
55+
"BaseFolder": "/Users/username/workspace/src/tests"
56+
},
57+
{
58+
"TestResult": {
59+
"Duration": 0.005,
60+
"Details": {},
61+
"Name": "EdgeCaseTest/testRounding3",
62+
"Passed": true,
63+
"Failed": false,
64+
"Incomplete": false
65+
},
66+
"BaseFolder": "/Users/username/workspace/src/tests"
67+
}
68+
]

0 commit comments

Comments
 (0)