Analyser { @NotNull public static Table createCulpritMatrix(List<FinishedBuildWithChanges> buildsWithContainingChanges) { if (buildsWithContainingChanges.size() == 0) { return new Table( new ArrayList<TestName>(), new ArrayList<FinishedBuildWithChanges>(), new HashMap<TestName, FinishedBuildWithChanges>(), new HashMap<TestName, Set<FinishedBuildWithChanges>>()); } List<TestName> failuresInMostRecentBuild = new ArrayList<TestName>(); for (TestName testFailure : SinCityUtils.getNamesOfFailingTests(buildsWithContainingChanges.get(0).getBuild())) { failuresInMostRecentBuild.add(testFailure); } Map<TestName, Set<FinishedBuildWithChanges>> buildsSuspectedOfCausingFailure = new HashMap<TestName, Set<FinishedBuildWithChanges>>(); Map<TestName, FinishedBuildWithChanges> buildInWhichFailureFirstOccurred = new HashMap<TestName, FinishedBuildWithChanges>(); Map<FinishedBuildWithChanges, Set<TestName>> failuresSuspectedToBeCausedByBuild = new LinkedHashMap<FinishedBuildWithChanges, Set<TestName>>(); HashSet<TestName> issuesNotYetClarified = new HashSet<TestName>(failuresInMostRecentBuild); int consecutiveBuildsWithoutNewInfo = 0; for (FinishedBuildWithChanges build : buildsWithContainingChanges) { FinishedBuildTestInfo buildTestInfo = new FinishedBuildTestInfo(build.getBuild()); consecutiveBuildsWithoutNewInfo++; Iterator<TestName> issuesNotYetClarifiedIterator = issuesNotYetClarified.iterator(); while (issuesNotYetClarifiedIterator.hasNext()) { TestName testFailure = issuesNotYetClarifiedIterator.next(); if (buildTestInfo.testFailed(testFailure)) { if (buildsSuspectedOfCausingFailure.containsKey(testFailure)) { for (FinishedBuildWithChanges previousSuspectBuild : buildsSuspectedOfCausingFailure.get(testFailure)) { failuresSuspectedToBeCausedByBuild.get(previousSuspectBuild).remove(testFailure); if (failuresSuspectedToBeCausedByBuild.get(previousSuspectBuild).isEmpty()) { failuresSuspectedToBeCausedByBuild.remove(previousSuspectBuild); } } } buildInWhichFailureFirstOccurred.put(testFailure, build); if (!failuresSuspectedToBeCausedByBuild.containsKey(build)) { failuresSuspectedToBeCausedByBuild.put(build, new HashSet<TestName>()); } failuresSuspectedToBeCausedByBuild.get(build).add(testFailure); buildsSuspectedOfCausingFailure.put(testFailure, new HashSet<FinishedBuildWithChanges>(Collections.singletonList(build))); consecutiveBuildsWithoutNewInfo = 0; } else if (buildTestInfo.testSucceeded(testFailure)) { issuesNotYetClarifiedIterator.remove(); consecutiveBuildsWithoutNewInfo = 0; } else { if (!failuresSuspectedToBeCausedByBuild.containsKey(build)) { failuresSuspectedToBeCausedByBuild.put(build, new HashSet<TestName>()); } failuresSuspectedToBeCausedByBuild.get(build).add(testFailure); buildsSuspectedOfCausingFailure.get(testFailure).add(build); } } if (consecutiveBuildsWithoutNewInfo >= getMaxNumberOfConsecutiveBuildsWithoutNewInfo()) break; } return new Table( failuresInMostRecentBuild, new ArrayList<FinishedBuildWithChanges>(failuresSuspectedToBeCausedByBuild.keySet()), buildInWhichFailureFirstOccurred, buildsSuspectedOfCausingFailure ); }  @NotNull static Table createCulpritMatrix(List<FinishedBuildWithChanges> buildsWithContainingChanges);  }
@Test public void test00EmptyHistory() { Table culpritTable = Analyser.createCulpritMatrix(new ArrayList<FinishedBuildWithChanges>()); assertThat(culpritTable.getNumberOfColumns(), is(0)); assertThat(culpritTable.getNumberOfRows(), is(0)); }
@Test public void test01NoOutstandingFailures() { mockery.checking(new Expectations() {{ allowing(buildGood).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); }}); Table culpritTable = Analyser.createCulpritMatrix(Collections.singletonList( new FinishedBuildWithChanges(buildGood, change0, Collections.<SVcsModification>emptyList()))); assertThat(culpritTable.getNumberOfColumns(), is(0)); assertThat(culpritTable.getNumberOfRows(), is(0)); }
@Test public void test02OneChangeOneBuild() { mockery.checking(new Expectations() {{ allowing(buildBad1).getTestMessages(0, -1); will(returnValue(Collections.singletonList(test1FailureTestInfo))); allowing(test1FailureTestInfo).getTestName(); will(returnValue(test1TestName)); allowing(buildGood).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); allowing(buildGood).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsGood)); allowing(buildStatisticsGood).getAllTests(); will(returnValue(Collections.singletonList(test1STestRun))); allowing(test1STestRun).getTest(); will(returnValue(test1STest)); allowing(test1STest).getName(); will(returnValue(test1TestName)); }}); Table culpritTable = Analyser.createCulpritMatrix(Arrays.asList( new FinishedBuildWithChanges(buildBad1, change1, Collections.singletonList(change1)), new FinishedBuildWithChanges(buildGood, change0, Collections.<SVcsModification>emptyList()))); assertThat(culpritTable.getNumberOfColumns(), is(1)); assertThat(culpritTable.getNumberOfRows(), is(1)); assertThat(culpritTable.getBuildRowCell(0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getBuildRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getChangeRowCell(0).getContent(), is(change1)); assertThat(culpritTable.getChangeRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getFailureColumnCell(0).getContent(), is(test1TestName)); assertThat(culpritTable.getFailureColumnCell(0).getColspan(), is(1)); assertThat(culpritTable.getCell(0, 0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getCell(0, 0).getColspan(), is(1)); }
@Test public void test03NoChangeOneBuild() { mockery.checking(new Expectations() {{ allowing(buildBad1).getTestMessages(0, -1); will(returnValue(Collections.singletonList(test1FailureTestInfo))); allowing(test1FailureTestInfo).getTestName(); will(returnValue(test1TestName)); allowing(buildGood).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); allowing(buildGood).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsGood)); allowing(buildStatisticsGood).getAllTests(); will(returnValue(Collections.singletonList(test1STestRun))); allowing(test1STestRun).getTest(); will(returnValue(test1STest)); allowing(test1STest).getName(); will(returnValue(test1TestName)); }}); Table culpritTable = Analyser.createCulpritMatrix(Arrays.asList( new FinishedBuildWithChanges(buildBad1, change0, Collections.<SVcsModification>emptyList()), new FinishedBuildWithChanges(buildGood, change0, Collections.<SVcsModification>emptyList()))); assertThat(culpritTable.getNumberOfColumns(), is(1)); assertThat(culpritTable.getNumberOfRows(), is(1)); assertThat(culpritTable.getBuildRowCell(0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getBuildRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getChangeRowCell(0).getContent(), nullValue()); assertThat(culpritTable.getChangeRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getFailureColumnCell(0).getContent(), is(test1TestName)); assertThat(culpritTable.getFailureColumnCell(0).getColspan(), is(1)); assertThat(culpritTable.getCell(0, 0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getCell(0, 0).getColspan(), is(1)); }
@Test public void test04MultipleChangesOneBuild() { mockery.checking(new Expectations() {{ allowing(buildBad1).getTestMessages(0, -1); will(returnValue(Collections.singletonList(test1FailureTestInfo))); allowing(test1FailureTestInfo).getTestName(); will(returnValue(test1TestName)); allowing(buildGood).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); allowing(buildGood).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsGood)); allowing(buildStatisticsGood).getAllTests(); will(returnValue(Collections.singletonList(test1STestRun))); allowing(test1STestRun).getTest(); will(returnValue(test1STest)); allowing(test1STest).getName(); will(returnValue(test1TestName)); }}); Table culpritTable = Analyser.createCulpritMatrix(Arrays.asList( new FinishedBuildWithChanges(buildBad1, change1, Arrays.asList(change2, change1)), new FinishedBuildWithChanges(buildGood, change0, Collections.<SVcsModification>emptyList()))); assertThat(culpritTable.getNumberOfColumns(), is(2)); assertThat(culpritTable.getNumberOfRows(), is(1)); assertThat(culpritTable.getBuildRowCell(0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getBuildRowCell(0).getColspan(), is(2)); assertThat(culpritTable.getBuildRowCell(1), nullValue()); assertThat(culpritTable.getChangeRowCell(0).getContent(), is(change2)); assertThat(culpritTable.getChangeRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getChangeRowCell(1).getContent(), is(change1)); assertThat(culpritTable.getChangeRowCell(1).getColspan(), is(1)); assertThat(culpritTable.getFailureColumnCell(0).getContent(), is(test1TestName)); assertThat(culpritTable.getFailureColumnCell(0).getColspan(), is(1)); assertThat(culpritTable.getCell(0, 0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getCell(0, 0).getColspan(), is(2)); assertThat(culpritTable.getCell(0, 1), nullValue()); }
@Test public void test05FailingRecently() { mockery.checking(new Expectations() {{ allowing(buildBad2).getTestMessages(0, -1); will(returnValue(Collections.singletonList(test1FailureTestInfo))); allowing(test1FailureTestInfo).getTestName(); will(returnValue(test1TestName)); allowing(buildNoRun).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); allowing(buildNoRun).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsNoRun)); allowing(buildStatisticsNoRun).getAllTests(); will(returnValue(Collections.emptyList())); allowing(buildBad1).getTestMessages(0, -1); will(returnValue(Collections.singletonList(test1FailureTestInfo))); allowing(buildGood).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); allowing(buildGood).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsGood)); allowing(buildStatisticsGood).getAllTests(); will(returnValue(Collections.singletonList(test1STestRun))); allowing(test1STestRun).getTest(); will(returnValue(test1STest)); allowing(test1STest).getName(); will(returnValue(test1TestName)); }}); Table culpritTable = Analyser.createCulpritMatrix(Arrays.asList( new FinishedBuildWithChanges(buildBad2, change1, Collections.<SVcsModification>emptyList()), new FinishedBuildWithChanges(buildNoRun, change1, Collections.<SVcsModification>emptyList()), new FinishedBuildWithChanges(buildBad1, change1, Collections.singletonList(change1)))); assertThat(culpritTable.getNumberOfColumns(), is(1)); assertThat(culpritTable.getNumberOfRows(), is(1)); assertThat(culpritTable.getBuildRowCell(0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getBuildRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getChangeRowCell(0).getContent(), is(change1)); assertThat(culpritTable.getChangeRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getFailureColumnCell(0).getContent(), is(test1TestName)); assertThat(culpritTable.getFailureColumnCell(0).getColspan(), is(1)); assertThat(culpritTable.getCell(0, 0).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getCell(0, 0).getColspan(), is(1)); }
@Test public void test10Regression() { mockery.checking(new Expectations() {{ allowing(buildBad2).getTestMessages(0, -1); will(returnValue(Arrays.asList(test1FailureTestInfo, test2FailureTestInfo))); allowing(test1FailureTestInfo).getTestName(); will(returnValue(test1TestName)); allowing(test2FailureTestInfo).getTestName(); will(returnValue(test2TestName)); allowing(buildBad1).getTestMessages(0, -1); will(returnValue(Collections.singletonList(test1FailureTestInfo))); allowing(buildBad1).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsNoRun)); allowing(buildStatisticsNoRun).getAllTests(); will(returnValue(Arrays.asList(test1STestRun))); allowing(test1STestRun).getTest(); will(returnValue(test1STest)); allowing(test1STest).getName(); will(returnValue(test1TestName)); allowing(buildGood).getTestMessages(0, -1); will(returnValue(Collections.emptyList())); allowing(buildGood).getBuildStatistics(BuildStatisticsOptions.ALL_TESTS_NO_DETAILS); will(returnValue(buildStatisticsGood)); allowing(buildStatisticsGood).getAllTests(); will(returnValue(Arrays.asList(test1STestRun, test2STestRun))); allowing(test2STestRun).getTest(); will(returnValue(test2STest)); allowing(test2STest).getName(); will(returnValue(test2TestName)); }}); Table culpritTable = Analyser.createCulpritMatrix(Arrays.asList( new FinishedBuildWithChanges(buildBad2, change2, Collections.singletonList(change2)), new FinishedBuildWithChanges(buildBad1, change1, Collections.singletonList(change1)), new FinishedBuildWithChanges(buildGood, change0, Collections.singletonList(change0)))); assertThat(culpritTable.getNumberOfColumns(), is(2)); assertThat(culpritTable.getNumberOfRows(), is(2)); assertThat(culpritTable.getBuildRowCell(0).getContent().getBuild(), is(buildBad2)); assertThat(culpritTable.getBuildRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getBuildRowCell(1).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getBuildRowCell(1).getColspan(), is(1)); assertThat(culpritTable.getChangeRowCell(0).getContent(), is(change2)); assertThat(culpritTable.getChangeRowCell(0).getColspan(), is(1)); assertThat(culpritTable.getChangeRowCell(1).getContent(), is(change1)); assertThat(culpritTable.getChangeRowCell(1).getColspan(), is(1)); assertThat(culpritTable.getFailureColumnCell(0).getContent(), is(test1TestName)); assertThat(culpritTable.getFailureColumnCell(0).getColspan(), is(1)); assertThat(culpritTable.getFailureColumnCell(1).getContent(), is(test2TestName)); assertThat(culpritTable.getFailureColumnCell(1).getColspan(), is(1)); assertThat(culpritTable.getCell(0, 0).getContent(), nullValue()); assertThat(culpritTable.getCell(0, 0).getColspan(), is(1)); assertThat(culpritTable.getCell(0, 1).getContent().getBuild(), is(buildBad1)); assertThat(culpritTable.getCell(0, 1).getColspan(), is(1)); assertThat(culpritTable.getCell(1, 0).getContent().getBuild(), is(buildBad2)); assertThat(culpritTable.getCell(1, 0).getColspan(), is(2)); assertThat(culpritTable.getCell(1, 1), nullValue()); }