Skip to content

Commit

Permalink
[FIXED JENKINS-17504] Fix 404 bad detail links on results page
Browse files Browse the repository at this point in the history
  • Loading branch information
kinow committed Jul 17, 2013
1 parent 30a1055 commit f1c034f
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 102 deletions.
16 changes: 5 additions & 11 deletions src/main/java/org/tap4j/plugin/AbstractTapProjectAction.java
Expand Up @@ -31,39 +31,33 @@
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 1.0
*/
public class AbstractTapProjectAction
implements Action
{
public class AbstractTapProjectAction implements Action {

public static final String URL_NAME = "tapResults";
public static final String ICON_NAME = "/plugin/tap/icons/tap-24.png";

/* (non-Javadoc)
* @see hudson.model.Action#getDisplayName()
*/
public String getDisplayName()
{
public String getDisplayName() {
return "TAP";
}

/* (non-Javadoc)
* @see hudson.model.Action#getIconFileName()
*/
public String getIconFileName()
{
public String getIconFileName() {
return ICON_NAME;
}

/* (non-Javadoc)
* @see hudson.model.Action#getUrlName()
*/
public String getUrlName()
{
public String getUrlName() {
return URL_NAME;
}

public String getSearchUrl()
{
public String getSearchUrl() {
return URL_NAME;
}

Expand Down
143 changes: 57 additions & 86 deletions src/main/java/org/tap4j/plugin/TapPublisher.java
Expand Up @@ -47,7 +47,9 @@
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.BooleanUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.tap4j.plugin.model.TestSetMap;
import org.tap4j.plugin.util.Constants;

/**
Expand All @@ -56,8 +58,8 @@
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 1.0
*/
@SuppressWarnings("unchecked")
public class TapPublisher extends Recorder implements MatrixAggregatable {

private final String testResults;
private final Boolean failIfNoResults;
private final Boolean failedTestsMarkBuildAsFailure;
Expand All @@ -75,60 +77,22 @@ public TapPublisher(String testResults,
Boolean discardOldReports,
Boolean todoIsFailure) {
this.testResults = testResults;
if(failIfNoResults == null) {
this.failIfNoResults = Boolean.FALSE;
} else {
this.failIfNoResults = failIfNoResults;
}
if(failedTestsMarkBuildAsFailure == null) {
this.failedTestsMarkBuildAsFailure = Boolean.FALSE;
} else {
this.failedTestsMarkBuildAsFailure = failedTestsMarkBuildAsFailure;
}
this.failIfNoResults = BooleanUtils.toBooleanDefaultIfNull(failIfNoResults, false);
this.failedTestsMarkBuildAsFailure = BooleanUtils.toBooleanDefaultIfNull(failedTestsMarkBuildAsFailure, false);
this.outputTapToConsole = outputTapToConsole;
if(enableSubtests == null) {
this.enableSubtests = Boolean.TRUE;
} else {
this.enableSubtests = enableSubtests;
}
if(discardOldReports == null) {
this.discardOldReports = Boolean.FALSE;
} else {
this.discardOldReports = discardOldReports;
}
if(todoIsFailure == null) {
this.todoIsFailure = Boolean.TRUE;
} else {
this.todoIsFailure = todoIsFailure;
}
this.enableSubtests = BooleanUtils.toBooleanDefaultIfNull(enableSubtests, true);
this.discardOldReports = BooleanUtils.toBooleanDefaultIfNull(discardOldReports, false);
this.todoIsFailure = BooleanUtils.toBooleanDefaultIfNull(todoIsFailure, true);
}

public Object readResolve() {
String testResults = this.getTestResults();
Boolean failIfNoResults = this.getFailIfNoResults();
Boolean failedTestsMarkBuildAsFailure = this.getFailedTestsMarkBuildAsFailure();
Boolean outputTapToConsole = this.getOutputTapToConsole();
Boolean enableSubtests = this.getEnableSubtests();
Boolean discardOldReports = this.getDiscardOldReports();
Boolean todoIsFailure = this.getTodoIsFailure();
if (failedTestsMarkBuildAsFailure == null) {
failedTestsMarkBuildAsFailure = Boolean.FALSE;
}
if(failIfNoResults == null) {
failIfNoResults = Boolean.FALSE;
}
if (outputTapToConsole == null) {
outputTapToConsole = Boolean.FALSE;
}
if(enableSubtests == null) {
enableSubtests = Boolean.TRUE;
}
if(discardOldReports == null) {
discardOldReports = Boolean.FALSE;
}
if(todoIsFailure == null) {
todoIsFailure = Boolean.TRUE;
}
Boolean failIfNoResults = BooleanUtils.toBooleanDefaultIfNull(this.getFailIfNoResults(), false);
Boolean failedTestsMarkBuildAsFailure = BooleanUtils.toBooleanDefaultIfNull(this.getFailedTestsMarkBuildAsFailure(), false);
Boolean outputTapToConsole = BooleanUtils.toBooleanDefaultIfNull(this.getOutputTapToConsole(), false);
Boolean enableSubtests = BooleanUtils.toBooleanDefaultIfNull(this.getEnableSubtests(), true);
Boolean discardOldReports = BooleanUtils.toBooleanDefaultIfNull(this.getDiscardOldReports(), false);
Boolean todoIsFailure = BooleanUtils.toBooleanDefaultIfNull(this.getTodoIsFailure(), true);
return new TapPublisher(testResults, failIfNoResults, failedTestsMarkBuildAsFailure, outputTapToConsole, enableSubtests, discardOldReports, todoIsFailure);
}

Expand Down Expand Up @@ -177,6 +141,19 @@ public Boolean getDiscardOldReports() {
public Boolean getTodoIsFailure() {
return todoIsFailure;
}

/**
* Gets the directory where the plug-in saves its TAP streams before processing them and
* displaying in the UI.
* <p>
* Adapted from JUnit Attachments Plug-in.
*
* @param build Jenkins build
* @return virtual directory (FilePath)
*/
public static FilePath getReportsDirectory(AbstractBuild<?, ?> build) {
return new FilePath(new File(build.getRootDir().getAbsolutePath())).child(Constants.TAP_DIR_NAME);
}

/*
* (non-Javadoc)
Expand All @@ -203,16 +180,14 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,

PrintStream logger = listener.getLogger();
logger.println("TAP Reports Processing: START");
logger.println("Looking for TAP results report in workspace using pattern: "
+ this.testResults);
logger.println("Looking for TAP results report in workspace using pattern: " + this.testResults);

FilePath[] reports = locateReports(build.getWorkspace(),
this.testResults);
FilePath[] reports = locateReports(build.getWorkspace(), this.testResults);

/*
* filter out the reports based on timestamps. See JENKINS-12187
*/
if(this.getDiscardOldReports()) {
if (this.getDiscardOldReports()) {
reports = checkReports(build, reports, logger);
}

Expand All @@ -228,7 +203,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
}
}

boolean filesSaved = saveReports(build.getWorkspace(), getTapReportDirectory(build), reports, logger);
boolean filesSaved = saveReports(build.getWorkspace(), TapPublisher.getReportsDirectory(build), reports, logger);
if (!filesSaved) {
logger.println("Failed to save TAP reports");
return Boolean.TRUE;
Expand Down Expand Up @@ -276,27 +251,24 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
* @param logger
* @return
*/
private TapResult loadResults(AbstractBuild<?, ?> owner,
PrintStream logger) {
FilePath tapDir = getTapReportDirectory(owner);
private TapResult loadResults(AbstractBuild<?, ?> owner, PrintStream logger) {
final FilePath tapDir = TapPublisher.getReportsDirectory(owner);
FilePath[] results = null;
TapResult tr = null;
try {
results = tapDir.list("**/*.*");

final TapParser parser = new TapParser(getOutputTapToConsole(), getEnableSubtests(), getTodoIsFailure(), logger);
final TapResult result = parser.parse(results, owner);
result.setOwner(owner);
return result;
} catch (Exception e) {
e.printStackTrace(logger);
}

TapResult tr = null;
if (results == null) {
tr = new TapResult("", owner, Collections.EMPTY_LIST, this.todoIsFailure);
tr.setOwner(owner);
return tr;
tr = new TapResult("", owner, Collections.<TestSetMap>emptyList(), getTodoIsFailure());
tr.setOwner(owner);
return tr;
}

TapParser parser = new TapParser(this.outputTapToConsole, this.enableSubtests, this.todoIsFailure, logger);
TapResult result = parser.parse(results, owner);
result.setOwner(owner);
return result;
}

/**
Expand All @@ -323,6 +295,14 @@ private boolean saveReports(FilePath workspace, FilePath tapDir, FilePath[] repo
return true;
}

/**
* Used to maintain the directory structure when persisting to the tap-reports dir.
*
* @param workspace Jenkins WS
* @param tapDir tap reports dir
* @param orig original directory
* @return persisted directory virtual structure
*/
private FilePath getDistDir(FilePath workspace, FilePath tapDir, FilePath orig) {
if(orig == null)
return null;
Expand All @@ -338,14 +318,8 @@ private FilePath getDistDir(FilePath workspace, FilePath tapDir, FilePath orig)
}

/**
* @param build
* @return
*/
private FilePath getTapReportDirectory(AbstractBuild<?, ?> build) {
return new FilePath(new File(build.getRootDir(), Constants.TAP_DIR_NAME));
}

/**
* Checks that there are new report files.
*
* @param build
* @param reports
* @param logger
Expand All @@ -368,13 +342,10 @@ private FilePath[] checkReports(AbstractBuild<?, ?> build,
* dividing by 1000 and comparing because we want to compare
* secs and not milliseconds
*/
if (build.getTimestamp().getTimeInMillis() / 1000 <= report
.lastModified() / 1000) {
if (build.getTimestamp().getTimeInMillis() / 1000 <= report.lastModified() / 1000) {
filePathList.add(report);
} else {
logger.println(report.getName()
+ " was last modified before "
+ "this build started. Ignoring it.");
logger.println(report.getName() + " was last modified before " + "this build started. Ignoring it.");
}
} catch (IOException e) {
// just log the exception
Expand All @@ -394,8 +365,7 @@ private FilePath[] checkReports(AbstractBuild<?, ?> build,
* @throws InterruptedException
* @throws IOException
*/
private FilePath[] locateReports(FilePath workspace, String testResults)
throws IOException, InterruptedException {
private FilePath[] locateReports(FilePath workspace, String testResults) throws IOException, InterruptedException {
return workspace.list(testResults);
}

Expand All @@ -408,6 +378,8 @@ public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.STEP;
}

// matrix jobs and test result aggregation support

/* (non-Javadoc)
* @see hudson.matrix.MatrixAggregatable#createAggregator(hudson.matrix.MatrixBuild, hudson.Launcher, hudson.model.BuildListener)
*/
Expand All @@ -433,7 +405,6 @@ public String getDisplayName() {
* @see hudson.tasks.BuildStepDescriptor#isApplicable(java.lang.Class)
*/
@Override
@SuppressWarnings("rawtypes")
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return Boolean.TRUE;
}
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/org/tap4j/plugin/model/TestSetMap.java
Expand Up @@ -35,9 +35,7 @@
* @author Bruno P. Kinoshita - http://www.kinoshita.eti.br
* @since 1.0
*/
public class TestSetMap
implements Serializable
{
public class TestSetMap implements Serializable {

private static final long serialVersionUID = 7300386936718557088L;

Expand Down
Expand Up @@ -58,8 +58,8 @@ THE SOFTWARE.
<j:forEach var="f" items="${it.failedTests2}" varStatus="i">
<tr>
<td class="pane">
<a id="test-${f.fullName}-showlink"
href="javascript:showStackTrace('test-${h.jsStringEscape(f.fullName)}','${f.getRelativePathFrom(it)}/summary')">&gt;&gt;&gt;</a>
<!--a id="test-${f.fullName}-showlink"
href="javascript:showStackTrace('test-${h.jsStringEscape(f.fullName)}','${f.getRelativePathFrom(it)}/')">&gt;&gt;&gt;</a-->
<a id="test-${f.fullName}-hidelink" style="display:none"
href="javascript:hideStackTrace('test-${h.jsStringEscape(f.fullName)}')">&lt;&lt;&lt;</a>
<st:nbsp/>
Expand Down
31 changes: 31 additions & 0 deletions src/test/java/org/tap4j/plugin/issue17947/TestIssue17947.java
@@ -0,0 +1,31 @@
package org.tap4j.plugin.issue17947;

import junit.framework.TestCase;

import org.tap4j.model.TestSet;
import org.tap4j.parser.Tap13Parser;

public class TestIssue17947 extends TestCase {

public void testSubtestsIssue17947() {
// tap stream provided by issue reporter
String tap = "1..3\n" +
" 1..1\n" +
" ok 1 - subtest 1\n" +
"ok 1 - test 1\n" +
" 1..4\n" +
" ok 1 - subtest 1\n" +
" ok 2 - subtest 2\n" +
" ok 3 - subtest 3\n" +
" ok 4 - subtest 4\n" +
"ok 2 - test 2\n" +
" 1..15\n" +
" Bail out!\n" +
" not ok 1 - test 3";

Tap13Parser parser = new Tap13Parser(true);
TestSet ts = parser.parseTapStream(tap);
System.out.println(ts.getNumberOfTestResults());
}

}
4 changes: 4 additions & 0 deletions src/test/java/org/tap4j/plugin/issue17947/package-info.java
@@ -0,0 +1,4 @@
/**
* Tests for issue JENKINS-17947.
*/
package org.tap4j.plugin.issue17947;

1 comment on commit f1c034f

@buildhive
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jenkins » tap-plugin #46 UNSTABLE
Looks like this commit caused a build failure
(what's this?)

Please sign in to comment.