Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-10682] Ignore failed (or aborted) builds when computing
the history information. I.e., failed builds will not be considered 
during new warnings evaluation and in trend graphs.
  • Loading branch information
uhafner committed Aug 22, 2011
1 parent 67001d6 commit 96ad36e
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 24 deletions.
22 changes: 15 additions & 7 deletions src/main/java/hudson/plugins/analysis/core/BuildHistory.java
Expand Up @@ -7,6 +7,7 @@

import javax.annotation.CheckForNull;

import hudson.model.Result;
import hudson.model.AbstractBuild;

import hudson.plugins.analysis.util.model.AnnotationContainer;
Expand Down Expand Up @@ -68,9 +69,11 @@ public AnnotationContainer getReferenceAnnotations() {
*/
private ResultAction<? extends BuildResult> getReferenceAction() {
for (AbstractBuild<?, ?> build = baseline.getPreviousBuild(); build != null; build = build.getPreviousBuild()) {
ResultAction<? extends BuildResult> action = build.getAction(type);
if (action != null && action.isSuccessful()) {
return action;
if (build.getResult().isBetterThan(Result.FAILURE)) {
ResultAction<? extends BuildResult> action = build.getAction(type);
if (action != null && action.isSuccessful()) {
return action;
}
}
}
return getPreviousAction(); // fallback, use previous build
Expand All @@ -87,7 +90,10 @@ private ResultAction<? extends BuildResult> getReferenceAction() {
public AbstractBuild<?, ?> getReferenceBuild() {
ResultAction<? extends BuildResult> action = getReferenceAction();
if (action != null) {
return action.getBuild();
AbstractBuild<?, ?> build = action.getBuild();
if (build.getResult().isBetterThan(Result.FAILURE)) {
return build;
}
}
return null;
}
Expand Down Expand Up @@ -122,9 +128,11 @@ public boolean hasPreviousResult() {
@CheckForNull
private ResultAction<? extends BuildResult> getPreviousAction() {
for (AbstractBuild<?, ?> build = baseline.getPreviousBuild(); build != null; build = build.getPreviousBuild()) {
ResultAction<? extends BuildResult> action = build.getAction(type);
if (action != null) {
return action;
if (build.getResult().isBetterThan(Result.FAILURE)) {
ResultAction<? extends BuildResult> action = build.getAction(type);
if (action != null) {
return action;
}
}
}
return null;
Expand Down
141 changes: 124 additions & 17 deletions src/test/java/hudson/plugins/analysis/core/BuildHistoryTest.java
Expand Up @@ -7,6 +7,7 @@

import org.junit.Test;

import hudson.model.Result;
import hudson.model.AbstractBuild;

import hudson.plugins.analysis.util.model.AnnotationContainer;
Expand All @@ -24,7 +25,7 @@ public class BuildHistoryTest {
*/
@Test(expected = NoSuchElementException.class)
public void testNoPreviousResult() throws Exception {
BuildHistory history = createHistory(mock(AbstractBuild.class));
BuildHistory history = createHistory(mockBuild());

assertFalse("Build has a previous result", history.hasPreviousResult());
assertEquals("Build has wrong reference annotations", 0,
Expand All @@ -45,13 +46,14 @@ public void testNoPreviousResult() throws Exception {
@Test
@SuppressWarnings("rawtypes")
public void testHasPreviousResult() throws Exception {
AbstractBuild withResult = mock(AbstractBuild.class);
AbstractBuild noResult = mock(AbstractBuild.class);
AbstractBuild baseline = mock(AbstractBuild.class);
AbstractBuild withResult = mockBuild();
AbstractBuild noResult = mockBuild();
AbstractBuild baseline = mockBuild();

when(baseline.getPreviousBuild()).thenReturn(noResult);
when(noResult.getPreviousBuild()).thenReturn(withResult);

TestResultAction action = mock(TestResultAction.class);
TestResultAction action = mockAction(withResult);
when(withResult.getAction(TestResultAction.class)).thenReturn(action);
BuildResult result = mock(BuildResult.class);
when(action.getResult()).thenReturn(result);
Expand All @@ -64,6 +66,48 @@ public void testHasPreviousResult() throws Exception {
assertSame("Build has wrong reference result", container, history.getReferenceAnnotations());
}

/**
* Verifies that we find the correct results for the following constellation.
* <ol>
* <li>Build with result and build result ABORTED</li>
* <li>Build with no result</li>
* <li>Baseline</li>
* </ol>
* @throws Exception the exception
*/
@Test
@SuppressWarnings("rawtypes")
public void testHasNoPreviousResultDueToFailure() throws Exception {
AbstractBuild withResult = mockBuild(Result.ABORTED);
AbstractBuild noResult = mockBuild();
AbstractBuild baseline = mockBuild();

when(baseline.getPreviousBuild()).thenReturn(noResult);
when(noResult.getPreviousBuild()).thenReturn(withResult);

TestResultAction action = mockAction(withResult);
when(withResult.getAction(TestResultAction.class)).thenReturn(action);
BuildResult result = mock(BuildResult.class);
when(action.getResult()).thenReturn(result);
AnnotationContainer container = mock(AnnotationContainer.class);
when(result.getContainer()).thenReturn(container);
BuildHistory history = createHistory(baseline);

assertFalse("Build has previous result", history.hasPreviousResult());
}

@SuppressWarnings("rawtypes")
private AbstractBuild mockBuild() {
return mockBuild(Result.SUCCESS);
}

@SuppressWarnings("rawtypes")
private AbstractBuild mockBuild(final Result result) {
AbstractBuild build = mock(AbstractBuild.class);
when(build.getResult()).thenReturn(result);
return build;
}

/**
* Verifies that we find the correct results for the following constellation.
* <ol>
Expand All @@ -78,35 +122,98 @@ public void testHasPreviousResult() throws Exception {
@SuppressWarnings("rawtypes")
@Test
public void testHasReferenceResult() throws Exception {
AbstractBuild withSuccessResult = mock(AbstractBuild.class);
AbstractBuild noResult2 = mock(AbstractBuild.class);
AbstractBuild withFailureResult = mock(AbstractBuild.class);
AbstractBuild noResult1 = mock(AbstractBuild.class);
AbstractBuild baseline = mock(AbstractBuild.class);
AbstractBuild withSuccessResult = mockBuild();
AbstractBuild noResult2 = mockBuild();
AbstractBuild withFailureResult = mockBuild();
AbstractBuild noResult1 = mockBuild();
AbstractBuild baseline = mockBuild();

when(baseline.getPreviousBuild()).thenReturn(noResult1);
when(noResult1.getPreviousBuild()).thenReturn(withFailureResult);
when(withFailureResult.getPreviousBuild()).thenReturn(noResult2);
when(noResult2.getPreviousBuild()).thenReturn(withSuccessResult);

TestResultAction failureAction = mock(TestResultAction.class);
BuildResult failureResult = createFailureResult(withFailureResult);

AnnotationContainer container = createSuccessfulResult(withSuccessResult);

BuildHistory history = createHistory(baseline);

assertTrue("Build has no previous result", history.hasPreviousResult());
assertSame("Build has wrong previous result", failureResult, history.getPreviousResult());
assertTrue("Build has no reference build", history.hasReferenceBuild());
assertSame("Build has wrong reference result", withSuccessResult, history.getReferenceBuild());
assertSame("Build has wrong reference result", container, history.getReferenceAnnotations());
}

/**
* Verifies that we find the correct results for the following constellation.
* <ol>
* <li>Build with result, build result = SUCCESS and build result ABORTED</li>
* <li>Build with no result</li>
* <li>Build with result, build result = FAILURE</li>
* <li>Build with no result</li>
* <li>Baseline</li>
* </ol>
* @throws Exception the exception
*/
@SuppressWarnings("rawtypes")
@Test
public void testHasNoReferenceResult() throws Exception {
AbstractBuild withSuccessResultAndSuccessfulBuild = mockBuild();
AbstractBuild withSuccessResult = mockBuild(Result.ABORTED);
AbstractBuild noResult2 = mockBuild();
AbstractBuild withFailureResult = mockBuild();
AbstractBuild noResult1 = mockBuild();
AbstractBuild baseline = mockBuild();

when(baseline.getPreviousBuild()).thenReturn(noResult1);
when(noResult1.getPreviousBuild()).thenReturn(withFailureResult);
when(withFailureResult.getPreviousBuild()).thenReturn(noResult2);
when(noResult2.getPreviousBuild()).thenReturn(withSuccessResult);
when(withSuccessResult.getPreviousBuild()).thenReturn(withSuccessResultAndSuccessfulBuild);

BuildResult failureResult = createFailureResult(withFailureResult);

createSuccessfulResult(withSuccessResult);
AnnotationContainer used = createSuccessfulResult(withSuccessResultAndSuccessfulBuild);

BuildHistory history = createHistory(baseline);

assertTrue("Build has no previous result", history.hasPreviousResult());
assertSame("Build has wrong previous result", failureResult, history.getPreviousResult());
assertTrue("Build has no reference build", history.hasReferenceBuild());
assertSame("Build has wrong reference result", withSuccessResultAndSuccessfulBuild, history.getReferenceBuild());
assertSame("Build has wrong reference result", used, history.getReferenceAnnotations());
}

@SuppressWarnings("rawtypes")
private BuildResult createFailureResult(final AbstractBuild withFailureResult) {
TestResultAction failureAction = mockAction(withFailureResult);
when(withFailureResult.getAction(TestResultAction.class)).thenReturn(failureAction);
when(failureAction.isSuccessful()).thenReturn(false);
BuildResult failureResult = mock(BuildResult.class);
when(failureAction.getResult()).thenReturn(failureResult);
return failureResult;
}

TestResultAction successAction = mock(TestResultAction.class);
@SuppressWarnings("rawtypes")
private AnnotationContainer createSuccessfulResult(final AbstractBuild withSuccessResult) {
TestResultAction successAction = mockAction(withSuccessResult);
when(withSuccessResult.getAction(TestResultAction.class)).thenReturn(successAction);
when(successAction.isSuccessful()).thenReturn(true);
BuildResult successResult = mock(BuildResult.class);
AnnotationContainer container = mock(AnnotationContainer.class);
when(successResult.getContainer()).thenReturn(container);
when(successAction.getResult()).thenReturn(successResult);
return container;
}

BuildHistory history = createHistory(baseline);

assertTrue("Build has no previous result", history.hasPreviousResult());
assertSame("Build has wrong previous result", failureResult, history.getPreviousResult());
assertSame("Build has wrong reference result", container, history.getReferenceAnnotations());
@SuppressWarnings({"rawtypes", "unchecked"})
private TestResultAction mockAction(final AbstractBuild build) {
TestResultAction action = mock(TestResultAction.class);
when(action.getBuild()).thenReturn(build);
return action;
}

/**
Expand Down

0 comments on commit 96ad36e

Please sign in to comment.