Skip to content

Commit

Permalink
Merge pull request #2 from jglick/pipeline-JENKINS-35420
Browse files Browse the repository at this point in the history
[JENKINS-35420] Pipeline compatibility
  • Loading branch information
olivergondza committed Oct 5, 2017
2 parents 8b63623 + b4f960a commit cedf6b2
Show file tree
Hide file tree
Showing 15 changed files with 763 additions and 177 deletions.
108 changes: 98 additions & 10 deletions pom.xml
Expand Up @@ -3,7 +3,8 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.19</version>
<version>2.30</version> <!-- TODO 2.33+ once https://github.com/jenkinsci/maven-plugin/pull/102 is released -->
<relativePath />
</parent>

<artifactId>junit-realtime-test-reporter</artifactId>
Expand All @@ -19,7 +20,12 @@
<email>ogondza@gmail.com</email>
</developer>
</developers>

<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>
<scm>
<connection>scm:git:git://github.com/jenkinsci/junit-realtime-test-reporter.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/junit-realtime-test-reporter.git</developerConnection>
Expand All @@ -29,18 +35,19 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<surefire.useFile>false</surefire.useFile>
<jenkins.version>1.609</jenkins.version>
<jenkins-test-harness.version>2.17</jenkins-test-harness.version>
<java.level>6</java.level>
<findbugs.skip>true</findbugs.skip>
<jenkins.version>2.32.3</jenkins.version>
<java.level>7</java.level>
<findbugs.skip>true</findbugs.skip> <!-- TODO -->
<workflow-step-api-plugin.version>2.13</workflow-step-api-plugin.version>
<workflow-support-plugin.version>2.14</workflow-support-plugin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>maven-plugin</artifactId>
<version>2.0</version>
<optional>true</optional>
</dependency>
<!-- Exclude sisu-guice we do not care for to make enforcer happy -->
<dependency>
Expand All @@ -57,26 +64,107 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>junit</artifactId>
<version>1.13</version>
<version>1.21</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>matrix-project</artifactId>
<version>1.4.1</version>
<!-- TODO make this dep optional -->
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow-step-api-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-api</artifactId>
<version>2.20</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>${workflow-support-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow-step-api-plugin.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-support</artifactId>
<version>${workflow-support-plugin.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.39</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.11.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<version>2.15</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-basic-steps</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-multibranch</artifactId>
<version>2.16</version>
<scope>test</scope>
</dependency>
<!-- upper bound deps -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
<version>1.33</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>scm-api</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>mailer</artifactId>
<version>1.20</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</project>
@@ -0,0 +1,121 @@
/*
* The MIT License
*
* Copyright 2017 CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jenkinsci.plugins.junitrealtimetestreporter;

import hudson.AbortException;
import hudson.Main;
import hudson.model.Run;
import hudson.tasks.test.AbstractTestResultAction;
import hudson.tasks.test.TestResult;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.StaplerProxy;

abstract class AbstractRealtimeTestResultAction extends AbstractTestResultAction<AbstractRealtimeTestResultAction> implements StaplerProxy {

private static final Logger LOGGER = Logger.getLogger(AbstractRealtimeTestResultAction.class.getName());

protected TestResult result;
private transient long updated;

protected AbstractRealtimeTestResultAction() {}

protected abstract TestResult parse() throws IOException, InterruptedException;

@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);
if (updated > System.currentTimeMillis() - threshold && !Main.isUnitTest) {
LOGGER.fine("Cache hit");
return result;
}
try {
final long started = System.currentTimeMillis(); // TODO use nanoTime
// TODO this can block on Remoting and hang the UI; need to refresh results asynchronously
result = parse();
result.setParentAction(this);
LOGGER.log(Level.FINE, "Parsing took {0} ms", System.currentTimeMillis() - started);
updated = System.currentTimeMillis();
} catch (AbortException ex) {
// Thrown when there are no reports or no workspace witch is normal
// at the beginning the build. This is also a signal that there are
// no reports to update (already parsed was excluded and no new have
// arrived so far).
LOGGER.fine("No new reports found.");
} catch (InterruptedException ex) {
LOGGER.log(Level.WARNING, "Unable to parse", ex);
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Unable to parse", ex);
}
return result;
}

@Override
public int getFailCount() {
if (getResult() == null) {
return 0;
}
return getResult().getFailCount();
}

@Override
public int getTotalCount() {
if (getResult() == null) {
return 0;
}
return getResult().getTotalCount();
}

@Override
public TestResult getTarget() {
if (!run.isBuilding()) {
LOGGER.log(Level.WARNING, "Dangling RealtimeTestResultAction on {0}. Probably not finalized correctly.", run);
detachAllFrom(run);
throw new HttpRedirect(run.getUrl());
}
if (getResult() != null) {
return getResult();
}
return new NullTestResult(this);
}

static void saveBuild(Run<?, ?> build) {
try {
build.save();
} catch (IOException x) {
LOGGER.log(Level.WARNING, null, x);
}
}

/*package*/ static void detachAllFrom(final Run<?, ?> build) {
if (build.removeActions(AbstractRealtimeTestResultAction.class)) {
LOGGER.log(Level.FINE, "Detaching RealtimeTestResultAction from {0}", build);
saveBuild(build);
}
}

}
Expand Up @@ -24,7 +24,6 @@
package org.jenkinsci.plugins.junitrealtimetestreporter;

import hudson.Extension;
import hudson.maven.MavenModuleSetBuild;
import hudson.model.TaskListener;
import hudson.model.AbstractBuild;
import hudson.model.Run;
Expand All @@ -47,24 +46,22 @@ public void onStarted(Run<?, ?> run, TaskListener listener) {

if (!isApplicable(build)) return;

build.addAction(new RealtimeTestResultAction(build));
build.addAction(new RealtimeTestResultAction());
AbstractRealtimeTestResultAction.saveBuild(run);
}

@Override
public void onFinalized(Run<?, ?> run) {
if ( !( run instanceof AbstractBuild )) {
return;
}
final AbstractBuild<?, ?> build = (AbstractBuild<?, ?>) run;

RealtimeTestResultAction.detachFrom(build);
AbstractRealtimeTestResultAction.detachAllFrom(run);
}

private static boolean isApplicable(final AbstractBuild<?, ?> build) {

if (!RealtimeTestResultAction.getConfig(build).reportInRealtime) return false;
if (!PerJobConfiguration.isActive(build.getParent())) return false;

if (build instanceof MavenModuleSetBuild) return true;
if (build.getClass().getName().equals("hudson.maven.MavenModuleSetBuild")) {
return true;
}

if (RealtimeTestResultAction.getArchiver(build) == null) return false;

Expand Down
Expand Up @@ -65,9 +65,10 @@ private static class Attach implements BuildCallable<Void, IOException> {

public Void call(MavenBuild build) throws IOException, InterruptedException {

if (RealtimeTestResultAction.getConfig(build).reportInRealtime) {
if (PerJobConfiguration.isActive(build.getParent())) {

build.addAction(new RealtimeTestResultAction(build));
build.addAction(new RealtimeTestResultAction());
AbstractRealtimeTestResultAction.saveBuild(build);
}
return null;
}
Expand All @@ -77,15 +78,15 @@ private static class Detach implements BuildCallable<Void, IOException> {

public Void call(MavenBuild build) throws IOException, InterruptedException {

if (RealtimeTestResultAction.getConfig(build).reportInRealtime) {
if (PerJobConfiguration.isActive(build.getParent())) {

RealtimeTestResultAction.detachFrom(build);
}
return null;
}
}

@Extension
@Extension(optional = true)
public static class Descriptor extends MavenReporterDescriptor {

@Override
Expand Down
Expand Up @@ -24,6 +24,7 @@
package org.jenkinsci.plugins.junitrealtimetestreporter;

import hudson.model.AbstractBuild;
import hudson.model.Run;
import hudson.tasks.test.TestObject;
import hudson.tasks.test.TestResult;

Expand All @@ -34,9 +35,9 @@
*/
/*package*/ final class NullTestResult extends TestResult {

private final RealtimeTestResultAction action;
private final AbstractRealtimeTestResultAction action;

/*package*/ NullTestResult(final RealtimeTestResultAction action) {
/*package*/ NullTestResult(final AbstractRealtimeTestResultAction action) {

this.action = action;
}
Expand All @@ -53,9 +54,8 @@ public String getDisplayName() {
}

@Override
public AbstractBuild<?, ?> getOwner() {

return action.owner;
public Run<?, ?> getRun() {
return action.run;
}

@Override
Expand Down

0 comments on commit cedf6b2

Please sign in to comment.