Skip to content
Permalink
Browse files
[FIXED JENKINS-29649] Now JUnit and TAP publisher do not clash with e…
…ach other trying to draw a plot on a project page.
  • Loading branch information
Vladislav Ponomarev committed Aug 19, 2016
1 parent ed157bd commit bc46bc5d413cbb139a4c0931752f42a594728cd8
@@ -25,18 +25,28 @@

import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.tasks.test.TestResultProjectAction;
import hudson.model.Job;

/**
* Base class for TAP Project action.
*
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 1.0
*/
public class AbstractTapProjectAction extends TestResultProjectAction implements Action {
public class AbstractTapProjectAction implements Action {

public final Job<?,?> job;

@Deprecated
public final AbstractProject<?,?> project;

public AbstractTapProjectAction(Job<?,?> job) {
this.job = job;
project = job instanceof AbstractProject ? (AbstractProject) job : null;
}

public AbstractTapProjectAction(AbstractProject<?, ?> project) {
super(project);
this((Job) project);
}

public static final String URL_NAME = "tapResults";
@@ -23,26 +23,25 @@
*/
package org.tap4j.plugin;

import hudson.matrix.MatrixProject;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Run;
import hudson.model.Job;
import hudson.matrix.MatrixProject;
import hudson.model.Run;
import hudson.util.ChartUtil;
import hudson.util.DataSetBuilder;
import hudson.util.RunList;
import org.jfree.chart.JFreeChart;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.tap4j.plugin.util.GraphHelper;

import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.jfree.chart.JFreeChart;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.tap4j.plugin.util.GraphHelper;

/**
* A TAP Project action, with a graph and a list of builds.
*
@@ -51,8 +50,6 @@
*/
public class TapProjectAction extends AbstractTapProjectAction {

private AbstractProject<?, ?> project;

protected class Result {
public int numPassed;
public int numFailed;
@@ -80,7 +77,10 @@ public void add(Result r) {

public TapProjectAction(AbstractProject<?, ?> project) {
super(project);
this.project = project;
}

public TapProjectAction(Job<?, ?> job) {
super(job);
}

public AbstractProject<?, ?> getProject() {
@@ -23,45 +23,52 @@
*/
package org.tap4j.plugin;

import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.Action;
import hudson.model.Job;
import hudson.model.Run;
import hudson.tasks.junit.CaseResult;
import hudson.tasks.test.AbstractTestResultAction;
import hudson.tasks.test.TestResult;

import java.util.Collections;
import java.util.List;

import jenkins.tasks.SimpleBuildStep;
import org.kohsuke.stapler.StaplerProxy;
import org.kohsuke.stapler.export.Exported;
import org.tap4j.plugin.model.TapStreamResult;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
*
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 0.1
*/
public class TapTestResultAction extends AbstractTestResultAction<AbstractTestResultAction<?>> implements StaplerProxy {
public class TapTestResultAction
extends AbstractTestResultAction<AbstractTestResultAction<?>>
implements StaplerProxy, SimpleBuildStep.LastBuildAction {

private final AbstractBuild<?, ?> owner;
private final TapResult tapResult;
private TapResult tapResult;

/**
* @param owner
* @param tapResult
*/
@Deprecated
protected TapTestResultAction(AbstractBuild<?, ?> owner, TapResult tapResult) {
super(owner);
this.owner = owner;
this.tapResult = tapResult;
this((Run) owner, tapResult);
}

/**
* @return the owner
* @param owner
* @param tapResult
*/
public AbstractBuild<?, ?> getOwner() {
return owner;
protected TapTestResultAction(Run owner, TapResult tapResult) {
super(owner);
this.tapResult = tapResult;
}

/**
* @return the tapResult
*/
@@ -122,20 +129,6 @@ public TestResult getResult() {
return new TapStreamResult(owner, tapResult);
}

/*
* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getPreviousResult()
*/
@Override
public AbstractTestResultAction<?> getPreviousResult() {
AbstractBuild<?, ?> previousBuild = owner.getPreviousBuild();
if (previousBuild != null) {
TapTestResultAction previousBuildAction = previousBuild.getAction(TapTestResultAction.class);
return previousBuildAction;
}
return new EmptyTapTestResultAction(owner);
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getUrlName()
*/
@@ -153,94 +146,13 @@ public String getDisplayName() {
return "TAP Test Results";
}

}

class EmptyTapTestResultAction extends TapTestResultAction {

private final AbstractBuild<?, ?> owner;

/**
* @param owner
* @param tapResult
*/
protected EmptyTapTestResultAction(AbstractBuild<?, ?> owner) {
super(owner, null);
this.owner = owner;
}

/*
* (non-Javadoc)
* @see org.tap4j.plugin.TapTestResultAction#getOwner()
*/
public AbstractBuild<?, ?> getOwner() {
return owner;
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getFailCount()
*/
@Override
@Exported(visibility = 2)
public int getFailCount() {
return 0;
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getTotalCount()
*/
@Override
@Exported(visibility = 2)
public int getTotalCount() {
return 0;
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getSkipCount()
*/
@Override
@Exported(visibility = 2)
public int getSkipCount() {
return 0;
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getFailedTests()
*/
@Override
public List<CaseResult> getFailedTests() {
//throw new AssertionError("Not supposed to be called");
return Collections.emptyList();
}

/*
* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getPreviousResult()
*/
@Override
public AbstractTestResultAction<?> getPreviousResult() {
AbstractBuild<?, ?> previousBuild = owner.getPreviousBuild();
if (previousBuild != null) {
TapTestResultAction previousBuildAction = previousBuild.getAction(TapTestResultAction.class);
return previousBuildAction;
public Collection<? extends Action> getProjectActions() {
Job<?,?> job = run.getParent();
if (!Util.filter(job.getActions(), TapProjectAction.class).isEmpty()) {
return Collections.emptySet();
}
return null;
return Collections.singleton(new TapProjectAction(job));
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getUrlName()
*/
@Override
@Exported(visibility = 2)
public String getUrlName() {
return "tapTestReport";
}

/* (non-Javadoc)
* @see hudson.tasks.test.AbstractTestResultAction#getDisplayName()
*/
@Override
public String getDisplayName() {
return "TAP Test Results";
}

}

@@ -0,0 +1,86 @@
/*
* The MIT License
*
* Copyright (c) 2009, Yahoo!, 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.tap4j.plugin;

import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.model.Project;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.recipes.LocalData;


public class PublishersCombinationTest {

@Rule
public JenkinsRule rule = new JenkinsRule();
private Project project;

@Before
public void setUp() throws Exception {

project = (Project) rule.jenkins.getItem("multiPublish");
}

@Issue("JENKINS-29649")
@LocalData
@Test
public void combinedWithJunit() throws Exception {

// Validate that there are test results where I expect them to be:
JenkinsRule.WebClient wc = rule.createWebClient();

// On the project page:
HtmlPage projectPage = wc.getPage(project);

assertJunitPart(projectPage);
assertTapPart(projectPage);
}

private void assertJunitPart(HtmlPage page) {

// we should have a link that reads "Latest Test Result"
// that link should go to http://localhost:8080/job/breakable/lastBuild/testReport/
rule.assertXPath(page, "//a[@href='lastCompletedBuild/testReport/']");
rule.assertXPathValue(page, "//a[@href='lastCompletedBuild/testReport/']", "Latest Test Result");
rule.assertXPathValueContains(page, "//a[@href='lastCompletedBuild/testReport/']", "Latest Test Result");

// there should be a test result trend graph
rule.assertXPath(page, "//img[@src='test/trend']");

// superficially assert that the number of tests was correct
rule.assertXPath(page, "//area[@title='#3: 4 tests' and @href='3/testReport/']");
}

private void assertTapPart(HtmlPage page) {

// there should be a TAP result trend graph
rule.assertXPath(page, "//img[@src='tapResults/graph']");

// superficially assert that the number of tests was correct
rule.assertXPath(page, "//area[@title='1 Skip(s)' and @href='3/tapResults/']");
}
}
Binary file not shown.

0 comments on commit bc46bc5

Please sign in to comment.