Skip to content

Commit

Permalink
Refactor Continuous Testing RPC service and UI
Browse files Browse the repository at this point in the history
 - merge observers for test state and results
 - replace direct rendering of results and state by custom API object (DTO)
 - optimize size and structure of JSON message

resolves #43067
  • Loading branch information
ueberfuhr committed Sep 9, 2024
1 parent fe706f2 commit 7f23428
Show file tree
Hide file tree
Showing 11 changed files with 607 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.TestSource;
import org.junit.platform.engine.TestTag;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.engine.reporting.ReportEntry;
Expand Down Expand Up @@ -258,8 +259,9 @@ public void executionSkipped(TestIdentifier testIdentifier, String reason) {
if (testClass != null) {
Map<UniqueId, TestResult> results = resultsByClass.computeIfAbsent(testClass.getName(),
s -> new HashMap<>());
TestResult result = new TestResult(displayName, testClass.getName(), id,
TestExecutionResult.aborted(null),
TestResult result = new TestResult(displayName, testClass.getName(),
toTagList(testIdentifier),
id, TestExecutionResult.aborted(null),
logHandler.captureOutput(), testIdentifier.isTest(), runId, 0, true);
results.put(id, result);
if (result.isTest()) {
Expand Down Expand Up @@ -312,8 +314,9 @@ public void executionFinished(TestIdentifier testIdentifier,
}
Map<UniqueId, TestResult> results = resultsByClass.computeIfAbsent(testClassName,
s -> new HashMap<>());
TestResult result = new TestResult(displayName, testClassName, id,
testExecutionResult,
TestResult result = new TestResult(displayName, testClassName,
toTagList(testIdentifier),
id, testExecutionResult,
logHandler.captureOutput(), testIdentifier.isTest(), runId,
System.currentTimeMillis() - startTimes.get(testIdentifier), true);
if (!results.containsKey(id)) {
Expand All @@ -332,6 +335,7 @@ public void executionFinished(TestIdentifier testIdentifier,
results.put(id,
new TestResult(currentNonDynamicTest.get().getDisplayName(),
result.getTestClass(),
toTagList(testIdentifier),
currentNonDynamicTest.get().getUniqueIdObject(),
TestExecutionResult.failed(failure), List.of(), false, runId, 0,
false));
Expand All @@ -349,6 +353,7 @@ public void executionFinished(TestIdentifier testIdentifier,
for (TestIdentifier child : children) {
UniqueId childId = UniqueId.parse(child.getUniqueId());
result = new TestResult(child.getDisplayName(), testClassName,
toTagList(testIdentifier),
childId,
testExecutionResult,
logHandler.captureOutput(), child.isTest(), runId,
Expand Down Expand Up @@ -419,6 +424,15 @@ public void reportingEntryPublished(TestIdentifier testIdentifier, ReportEntry e
}
}

private static List<String> toTagList(TestIdentifier testIdentifier) {
return testIdentifier
.getTags()
.stream()
.map(TestTag::getName)
.sorted()
.toList();
}

private Class<?> getTestClassFromSource(Optional<TestSource> optionalTestSource) {
if (optionalTestSource.isPresent()) {
var testSource = optionalTestSource.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,39 @@
import java.util.ArrayList;
import java.util.List;

public class TestClassResult implements Comparable<TestClassResult> {
import io.quarkus.dev.testing.results.TestClassResultInterface;
import io.quarkus.dev.testing.results.TestResultInterface;

public class TestClassResult implements TestClassResultInterface {
final String className;
final List<TestResult> passing;
final List<TestResult> failing;
final List<TestResult> skipped;
final long latestRunId;
final long time;

public TestClassResult(String className, List<TestResult> passing, List<TestResult> failing, List<TestResult> skipped,
public TestClassResult(
String className,
List<TestResult> passing,
List<TestResult> failing,
List<TestResult> skipped,
long time) {
this.className = className;
this.passing = passing;
this.failing = failing;
this.skipped = skipped;
this.time = time;
long runId = 0;
for (TestResult i : passing) {
runId = Math.max(i.runId, runId);
for (TestResultInterface i : passing) {
runId = Math.max(i.getRunId(), runId);
}
for (TestResult i : failing) {
runId = Math.max(i.runId, runId);
for (TestResultInterface i : failing) {
runId = Math.max(i.getRunId(), runId);
}
latestRunId = runId;
}

@Override
public String getClassName() {
return className;
}
Expand All @@ -53,15 +61,12 @@ public long getTime() {
}

@Override
public int compareTo(TestClassResult o) {
return className.compareTo(o.className);
}

public List<TestResult> getResults() {
List<TestResult> ret = new ArrayList<>();
ret.addAll(passing);
ret.addAll(failing);
ret.addAll(skipped);
return ret;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.UniqueId;

public class TestResult {
import io.quarkus.dev.testing.results.TestResultInterface;

public class TestResult implements TestResultInterface {

final String displayName;
final String testClass;
final List<String> tags;
final UniqueId uniqueId;
final TestExecutionResult testExecutionResult;
final List<String> logOutput;
Expand All @@ -20,10 +23,12 @@ public class TestResult {
final List<Throwable> problems;
final boolean reportable;

public TestResult(String displayName, String testClass, UniqueId uniqueId, TestExecutionResult testExecutionResult,
public TestResult(String displayName, String testClass, List<String> tags, UniqueId uniqueId,
TestExecutionResult testExecutionResult,
List<String> logOutput, boolean test, long runId, long time, boolean reportable) {
this.displayName = displayName;
this.testClass = testClass;
this.tags = tags;
this.uniqueId = uniqueId;
this.testExecutionResult = testExecutionResult;
this.logOutput = logOutput;
Expand All @@ -46,39 +51,66 @@ public TestExecutionResult getTestExecutionResult() {
return testExecutionResult;
}

@Override
public List<String> getLogOutput() {
return logOutput;
}

@Override
public String getDisplayName() {
return displayName;
}

@Override
public String getTestClass() {
return testClass;
}

@Override
public List<String> getTags() {
return tags;
}

public UniqueId getUniqueId() {
return uniqueId;
}

@Override
public boolean isTest() {
return test;
}

@Override
public String getId() {
return uniqueId.toString();
}

@Override
public long getRunId() {
return runId;
}

@Override
public long getTime() {
return time;
}

@Override
public List<Throwable> getProblems() {
return problems;
}

@Override
public boolean isReportable() {
return reportable;
}

@Override
public State getState() {
return switch (testExecutionResult.getStatus()) {
case FAILED -> State.FAILED;
case ABORTED -> State.SKIPPED;
case SUCCESSFUL -> State.PASSED;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import java.util.Map;

import io.quarkus.deployment.dev.ClassScanResult;
import io.quarkus.dev.testing.results.TestResultInterface;
import io.quarkus.dev.testing.results.TestRunResultsInterface;

public class TestRunResults {
public class TestRunResults implements TestRunResultsInterface {

/**
* The run id
Expand All @@ -28,7 +30,7 @@ public class TestRunResults {
private final long started;
private final long completed;

private final Map<String, TestClassResult> results;
private final Map<String, ? extends TestClassResult> results;
private final Map<String, TestClassResult> currentFailing = new HashMap<>();
private final Map<String, TestClassResult> historicFailing = new HashMap<>();
private final Map<String, TestClassResult> currentPassing = new HashMap<>();
Expand Down Expand Up @@ -58,9 +60,9 @@ public TestRunResults(long id, ClassScanResult trigger, boolean full, long start
long currentFailedCount = 0;
long currentSkippedCount = 0;
for (Map.Entry<String, TestClassResult> i : results.entrySet()) {
passedCount += i.getValue().getPassing().stream().filter(TestResult::isTest).count();
failedCount += i.getValue().getFailing().stream().filter(TestResult::isTest).count();
skippedCount += i.getValue().getSkipped().stream().filter(TestResult::isTest).count();
passedCount += i.getValue().getPassing().stream().filter(TestResultInterface::isTest).count();
failedCount += i.getValue().getFailing().stream().filter(TestResultInterface::isTest).count();
skippedCount += i.getValue().getSkipped().stream().filter(TestResultInterface::isTest).count();
currentPassedCount += i.getValue().getPassing().stream().filter(s -> s.isTest() && s.getRunId() == id).count();
currentFailedCount += i.getValue().getFailing().stream().filter(s -> s.isTest() && s.getRunId() == id).count();
currentSkippedCount += i.getValue().getSkipped().stream().filter(s -> s.isTest() && s.getRunId() == id).count();
Expand Down Expand Up @@ -98,6 +100,7 @@ public TestRunResults(long id, ClassScanResult trigger, boolean full, long start
this.currentSkippedCount = currentSkippedCount;
}

@Override
public long getId() {
return id;
}
Expand All @@ -110,6 +113,7 @@ public boolean isFull() {
return full;
}

@Override
public Map<String, TestClassResult> getResults() {
return Collections.unmodifiableMap(results);
}
Expand All @@ -130,14 +134,17 @@ public Map<String, TestClassResult> getHistoricPassing() {
return historicPassing;
}

@Override
public long getStartedTime() {
return started;
}

@Override
public long getCompletedTime() {
return completed;
}

@Override
public long getTotalTime() {
return completed - started;
}
Expand All @@ -154,34 +161,42 @@ public List<TestClassResult> getSkipped() {
return skipped;
}

@Override
public long getPassedCount() {
return passedCount;
}

@Override
public long getFailedCount() {
return failedCount;
}

@Override
public long getSkippedCount() {
return skippedCount;
}

@Override
public long getCurrentPassedCount() {
return currentPassedCount;
}

@Override
public long getCurrentFailedCount() {
return currentFailedCount;
}

@Override
public long getCurrentSkippedCount() {
return currentSkippedCount;
}

@Override
public long getTotalCount() {
return getPassedCount() + getFailedCount() + getSkippedCount();
}

@Override
public long getCurrentTotalCount() {
return getCurrentPassedCount() + getCurrentFailedCount() + getCurrentSkippedCount();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.dev.testing.results;

import java.util.List;

public interface TestClassResultInterface extends Comparable<TestClassResultInterface> {

String getClassName();

List<? extends TestResultInterface> getResults();

@Override
default int compareTo(TestClassResultInterface o) {
return getClassName().compareTo(o.getClassName());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.quarkus.dev.testing.results;

import java.util.List;

public interface TestResultInterface {
List<String> getLogOutput();

String getDisplayName();

String getTestClass();

List<String> getTags();

boolean isTest();

String getId();

long getRunId();

long getTime();

List<Throwable> getProblems();

boolean isReportable();

State getState();

enum State {
PASSED,
FAILED,
SKIPPED
}

}
Loading

0 comments on commit 7f23428

Please sign in to comment.