package hudson.plugins.cigame.rules.unittesting;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import hudson.maven.MavenBuild;
import hudson.model.Result;
import hudson.plugins.cigame.GameDescriptor;
import hudson.plugins.cigame.model.RuleResult;
import hudson.tasks.test.AbstractTestResultAction;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
@SuppressWarnings("unchecked")
public class MavenMultiModuleUnitTestsTest {
private GameDescriptor gameDescriptor;
@Rule
public JenkinsRule jenkinsRule = new JenkinsRule();
@Before
public void setup() {
gameDescriptor = jenkinsRule.jenkins.getDescriptorByType(GameDescriptor.class);
}
// Doesn't work, because MavenModule is final ...
//
// private MavenModuleSetBuild getMultiModuleBuild() {
// MavenModuleSetBuild build = mock(MavenModuleSetBuild.class);
//
// MavenModule module1 = mock(MavenModule.class);
// MavenBuild module1Build1 = mock(MavenBuild.class);
// AbstractTestResultAction testResult11 = mock(AbstractTestResultAction.class);
// when(testResult11.getTotalCount()).thenReturn(3);
// when(module1Build1.getAction(AbstractTestResultAction.class)).thenReturn(testResult11);
//
// MavenModule module2 = mock(MavenModule.class);
// MavenBuild module2Build1 = mock(MavenBuild.class);
// AbstractTestResultAction testResult21 = mock(AbstractTestResultAction.class);
// when(testResult21.getTotalCount()).thenReturn(5);
// when(module2Build1.getAction(AbstractTestResultAction.class)).thenReturn(testResult21);
//
// when(build.getModuleLastBuilds()).thenReturn(
// new ImmutableMap.Builder<MavenModule, MavenBuild>()
// .put(module1, module1Build1)
// .put(module2, module2Build1)
// .build());
// return build;
// }
//
// @Test
// public void testAllTestsCountIfPreviousBuildIsNull() {
// ScoreCard scoreCard = new ScoreCard();
// scoreCard.record(getMultiModuleBuild(), new UnitTestingRuleSet());
//
// Collection<Score> scores = scoreCard.getScores();
// Assert.assertEquals(2, scores.size());
// }
/**
* Test that the 1st ever build will yield points for passing and
* failing tests.
*/
@Test
public void testCountPointsOnFirstBuild() {
MavenBuild currentBuild = mockBuild(Result.SUCCESS, 7, 3, 0);
RuleResult ruleResult = getIncreasingPassedTestsRule().evaluate(null, currentBuild);
Assert.assertEquals(7, ruleResult.getPoints(), 0.1);
ruleResult = getIncreasingFailedTestsRule().evaluate(null, currentBuild);
Assert.assertEquals(-3, ruleResult.getPoints(), 0.1);
}
/**
* Tests that previously passing tests are counted as negative if a module
* is removed.
* Analogue, previously failing tests should be counted as positive.
*/
@Test
public void testCountNegativeIfModuleRemoved() {
MavenBuild currentBuild = null;
MavenBuild previousBuild = mockBuild(Result.SUCCESS, 6, 2, 1);
gameDescriptor.setPassedTestDecreasingPoints(-1);
RuleResult<Integer> ruleResult = new DecreasingPassedTestsRule().evaluate(
previousBuild, currentBuild);
Assert.assertEquals(-6, ruleResult.getPoints(), 0.1);
gameDescriptor.setFailedTestDecreasingPoints(1);
ruleResult = new DecreasingFailedTestsRule().evaluate(
previousBuild, currentBuild);
Assert.assertEquals(2, ruleResult.getPoints(), 0.1);
}
/**
* Tests that on multiple consecutive builds without any test results
* only the first will get negative points.
* I've seen this happen with the maven-jspc-plugin that
* when JSP compilation fails the multimodule build
* itself failed, but the submodule was marked as success
* - only its unit tests weren't executed.
*/
@Test
public void testCountNegativePointsOnlyOnceOnMultipleBuildsWithoutTestResults() {
MavenBuild currentBuild = mockBuildWithoutTestResults(Result.SUCCESS);
MavenBuild previousBuild = mockBuildWithoutTestResults(Result.SUCCESS);
MavenBuild prevPrevBuild = mockBuild(Result.SUCCESS, 6, 0, 0);
when(previousBuild.getPreviousBuild()).thenReturn(prevPrevBuild);
gameDescriptor.setPassedTestDecreasingPoints(-1);
RuleResult<Integer> ruleResult = new DecreasingPassedTestsRule().evaluate(
previousBuild, currentBuild);
// After the first build with 6 passing tests, next build has not got the Test Results.
// So current build must be given the negative marks.
// Assert.assertNull(ruleResult);
Assert.assertEquals(-6, ruleResult.getPoints(), 0.1);
}
/**
* Tests the build from before the previous build is
* taken into account for comparison if the previous build
* is NOT_BUILT or ABORTED.
*/
@Test
public void testSkipUnbuiltAndAbortedBuilds() {
MavenBuild currentBuild = mockBuild(Result.UNSTABLE,
10, 7, 0);
MavenBuild previousBuild = mockBuild(Result.NOT_BUILT,
0, 0, 0);
MavenBuild previouspreviousBuild = mockBuild(Result.UNSTABLE,
8, 4, 0);
when(currentBuild.getPreviousBuild()).thenReturn(previousBuild);
when(previousBuild.getPreviousBuild()).thenReturn(previouspreviousBuild);
RuleResult ruleResult = getIncreasingPassedTestsRule().evaluate(previousBuild, currentBuild);
Assert.assertEquals(2, ruleResult.getPoints(), 0.1);
ruleResult = getIncreasingFailedTestsRule().evaluate(previousBuild, currentBuild);
Assert.assertEquals(-3, ruleResult.getPoints(), 0.1);
// and the same for an ABORTED build
previousBuild = mockBuild(Result.ABORTED,
0, 0, 0);
when(currentBuild.getPreviousBuild()).thenReturn(previousBuild);
when(previousBuild.getPreviousBuild()).thenReturn(previouspreviousBuild);
ruleResult = getIncreasingPassedTestsRule().evaluate(previousBuild, currentBuild);
Assert.assertEquals(2, ruleResult.getPoints(), 0.1);
ruleResult = getIncreasingFailedTestsRule().evaluate(previousBuild, currentBuild);
Assert.assertEquals(-3, ruleResult.getPoints(), 0.1);
}
// TODO ckutz: add test case that check that no NPEs occur when a result is null
private IncreasingFailedTestsRule getIncreasingFailedTestsRule() {
gameDescriptor.setFailedTestIncreasingPoints(-1);
return new IncreasingFailedTestsRule();
}
private IncreasingPassedTestsRule getIncreasingPassedTestsRule() {
gameDescriptor.setPassedTestIncreasingPoints(1);
return new IncreasingPassedTestsRule();
}
static MavenBuild mockBuild(Result buildResult, int passedTestCount,
int failedTestCount, int skippedTestCount) {
MavenBuild build = mock(MavenBuild.class);
AbstractTestResultAction testResult = mock(AbstractTestResultAction.class);
when(testResult.getTotalCount()).thenReturn(passedTestCount + failedTestCount + skippedTestCount);
when(testResult.getFailCount()).thenReturn(failedTestCount);
when(testResult.getSkipCount()).thenReturn(skippedTestCount);
when(build.getAction(AbstractTestResultAction.class)).thenReturn(testResult);
when(build.getResult()).thenReturn(buildResult);
return build;
}
static MavenBuild mockBuildWithoutTestResults(Result buildResult) {
MavenBuild build = mock(MavenBuild.class);
when(build.getResult()).thenReturn(buildResult);
return build;
}
}