Skip to content

Commit

Permalink
Add optional attribute to set the junit results parse interval (#32)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Beland <[email protected]>
Co-authored-by: Tim Jacomb <[email protected]>
  • Loading branch information
3 people authored Jan 13, 2022
1 parent 21ab521 commit 3233792
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,10 @@ protected AbstractRealtimeTestResultAction() {}

@Override
public TestResult getResult() {
// Refresh every 1/100 of a job estimated duration but not more often than every 5 seconds
final long threshold = Math.max(5000, run.getEstimatedDuration() / 100);
final long threshold = getParseInterval();
// TODO possible improvements:
// · always run parse in case result == null
// · run parse regardless of cache if result.getTotalCount() == 0
// · refresh no less often than every 1m even if job is estimated to take >100m
if (updated > System.currentTimeMillis() - threshold && !Main.isUnitTest) {
LOGGER.fine("Cache hit");
return result;
Expand Down Expand Up @@ -82,6 +80,13 @@ public TestResult getResult() {
return result;
}

protected long getParseInterval() {
// Refresh every 1/100 of a job estimated duration but not more often than every 5 seconds
return Math.max(5000, run.getEstimatedDuration() / 100);
// TODO possible improvements:
// · refresh no less often than every 1m even if job is estimated to take >100m
}

@Override
public int getFailCount() {
if (getResult() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,23 @@ class PipelineRealtimeTestResultAction extends AbstractRealtimeTestResultAction
private final String glob;
@CheckForNull
private transient final StepContext context;
private final Long parseInterval;

PipelineRealtimeTestResultAction(
String id,
FilePath ws,
boolean keepLongStdio,
String glob,
StepContext context
StepContext context,
Long parseInterval
) {
this.id = id;
node = FilePathUtils.getNodeName(ws);
workspace = ws.getRemote();
this.keepLongStdio = keepLongStdio;
this.glob = glob;
this.context = context;
this.parseInterval = parseInterval;
}

@Override
Expand All @@ -86,6 +89,11 @@ public String getUrlName() {
return "realtimeTestReport-" + id;
}

@Override
protected long getParseInterval() {
return parseInterval != null ? parseInterval.longValue() : super.getParseInterval();
}

@Override
protected TestResult parse() throws IOException, InterruptedException {
FilePath ws = FilePathUtils.find(node, workspace);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class RealtimeJUnitStep extends Step {
private Double healthScaleFactor;
private boolean allowEmptyResults;
private boolean skipMarkingBuildUnstable;
private Long parseInterval;

@DataBoundConstructor
public RealtimeJUnitStep(String testResults) {
Expand Down Expand Up @@ -132,6 +133,15 @@ public void setSkipMarkingBuildUnstable(boolean skipMarkingBuildUnstable) {
this.skipMarkingBuildUnstable = skipMarkingBuildUnstable;
}

public Long getParseInterval() {
return parseInterval;
}

@DataBoundSetter
public void setParseInterval(Long parseInterval) {
this.parseInterval = parseInterval;
}

@Override
public StepExecution start(StepContext context) throws Exception {
JUnitResultArchiver delegate = new JUnitResultArchiver(testResults);
Expand All @@ -140,16 +150,20 @@ public StepExecution start(StepContext context) throws Exception {
delegate.setKeepLongStdio(keepLongStdio);
delegate.setTestDataPublishers(getTestDataPublishers());
delegate.setSkipMarkingBuildUnstable(isSkipMarkingBuildUnstable());
return new Execution2(context, delegate);
// step takes value in milliseconds but users provide in seconds
Long parseInterval = this.parseInterval != null ? this.parseInterval * 1000 : null;
return new Execution2(context, delegate, parseInterval);
}

@SuppressFBWarnings("SE_BAD_FIELD") // FIXME
static class Execution2 extends GeneralNonBlockingStepExecution {
private final JUnitResultArchiver archiver;
private final Long parseInterval;

Execution2(StepContext context, JUnitResultArchiver archiver) {
Execution2(StepContext context, JUnitResultArchiver archiver, Long parseInterval) {
super(context);
this.archiver = archiver;
this.parseInterval = parseInterval;
}

@Override
Expand All @@ -168,7 +182,8 @@ private void doStart() throws IOException, InterruptedException {
context.get(FilePath.class),
archiver.isKeepLongStdio(),
archiver.getTestResults(),
context
context,
parseInterval
)
);
AbstractRealtimeTestResultAction.saveBuild(r);
Expand Down Expand Up @@ -249,7 +264,8 @@ void doStart() throws IOException, InterruptedException {
context.get(FilePath.class),
archiver.isKeepLongStdio(),
archiver.getTestResults(),
context
context,
null
)
);
AbstractRealtimeTestResultAction.saveBuild(r);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ THE SOFTWARE.
-->

<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:f="/lib/form">
<!-- like f:property but without actually using a nested object (see main class for discussion): -->
<j:set var="descriptor" value="${descriptor.delegateDescriptor}"/>
<st:include from="${descriptor}" page="${descriptor.configPage}"/>
<j:set var="delegateDescriptor" value="${descriptor.delegateDescriptor}"/>
<st:include from="${delegateDescriptor}" page="${delegateDescriptor.configPage}"/>
<f:entry title="${%Parse Interval}" field="parseInterval">
<f:number/>
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div>
<p>
The interval between two file system scans to parse test results (in seconds).
Must be a positive value greater than 0.
Default value is calculated as 1/100 of the estimated build duration, but never more often than every 5 seconds.
</p>
</div>

0 comments on commit 3233792

Please sign in to comment.