This is an automated email from the ASF dual-hosted git repository.
dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push:
new 99933de IGNITE-12010: Consider newly contributed test as a blocker if
it runs more than 1 minute
99933de is described below
commit 99933ded617c523c37adeeede5009f4cd2a6f922
Author: Dmitriy Pavlov <[email protected]>
AuthorDate: Wed Jul 24 21:50:48 2019 +0300
IGNITE-12010: Consider newly contributed test as a blocker if it runs more
than 1 minute
---
.../tcbot/visa/TcBotTriggerAndSignOffService.java | 22 +-----
.../org/apache/ignite/ci/web/model/Version.java | 2 +-
.../src/main/webapp/js/testfails-2.2.js | 11 ++-
ignite-tc-helper-web/src/main/webapp/pr.html | 10 +--
.../ci/tcbot/chain/BuildChainProcessorTest.java | 4 +-
.../org/apache/ignite/tcbot/common/TcBotConst.java | 5 ++
.../ignite/tcbot/engine/chain/FullChainRunCtx.java | 8 +-
.../tcbot/engine/chain/IMultTestOccurrence.java | 36 ---------
.../ignite/tcbot/engine/chain/MultBuildRunCtx.java | 87 ++++++++++++++--------
.../tcbot/engine/chain/TestCompactedMult.java | 77 +++++++++++++++----
.../ignite/tcbot/engine/pr/PrChainsProcessor.java | 36 +++++----
.../apache/ignite/tcbot/engine/ui/DsChainUi.java | 3 +-
.../apache/ignite/tcbot/engine/ui/DsSuiteUi.java | 4 +-
.../ignite/tcbot/engine/ui/DsTestFailureUi.java | 5 +-
.../teamcity/ignited/fatbuild/TestCompacted.java | 15 +++-
15 files changed, 194 insertions(+), 131 deletions(-)
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
index 0ea1dbc..9917e6b 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java
@@ -810,14 +810,7 @@ public class TcBotTriggerAndSignOffService {
return new Visa("JIRA wasn't commented - no finished builds to
analyze." +
" Check builds availabiliy for branch: " +
build.branchName + "/" + baseBranch);
- blockers = suitesStatuses.stream()
- .mapToInt(suite -> {
- if (suite.testFailures.isEmpty())
- return 1;
-
- return suite.testFailures.size();
- })
- .sum();
+ blockers =
suitesStatuses.stream().mapToInt(DsSuiteUi::totalBlockers).sum();
String comment = generateJiraComment(suitesStatuses, build.webUrl,
buildTypeId, tcIgnited, blockers, build.branchName, baseBranch);
@@ -879,18 +872,7 @@ public class TcBotTriggerAndSignOffService {
else
res.append(jiraEscText(failure.name));
- DsHistoryStatUi recent = failure.histBaseBranch.recent;
-
- if (recent != null) {
- if (recent.failureRate != null) {
- res.append(" - ").append(recent.failureRate).append("%
fails in last ")
- .append(recent.runs).append("
").append(jiraEscText(baseBranchDisp)).append(" runs.");
- }
- else if (recent.failures != null && recent.runs != null) {
- res.append(" - ").append(recent.failures).append("
fails / ")
- .append(recent.runs).append("
").append(jiraEscText(baseBranchDisp)).append(" runs.");
- }
- }
+ res.append(" - ").append(jiraEscText(failure.blockerComment));
res.append("\\n");
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
index b3e3f12..91748b4 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
@@ -28,7 +28,7 @@ package org.apache.ignite.ci.web.model;
public static final String GITHUB_REF =
"https://github.com/apache/ignite-teamcity-bot";
/** TC Bot Version. */
- public static final String VERSION = "20190723";
+ public static final String VERSION = "20190724";
/** Java version, where Web App is running. */
public String javaVer;
diff --git a/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
b/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
index 0947a62..bcd935c 100644
--- a/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
+++ b/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
@@ -819,9 +819,14 @@ function showTestFailData(testFail, isFailureShown,
settings) {
var haveIssue = isDefinedAndFilled(testFail.webIssueUrl) &&
isDefinedAndFilled(testFail.webIssueText);
- var color = (isFailureShown && failRateDefined)
- ? failureRateToColor(failRate)
- : "white";
+ var color;
+ if (testFail.success === true) {
+ color = "green";
+ } else {
+ color = (isFailureShown && failRateDefined)
+ ? failureRateToColor(failRate)
+ : "white";
+ }
var investigated = isDefinedAndFilled(testFail.investigated) &&
testFail.investigated;
if (investigated) {
diff --git a/ignite-tc-helper-web/src/main/webapp/pr.html
b/ignite-tc-helper-web/src/main/webapp/pr.html
index e05a730..58a2acf 100644
--- a/ignite-tc-helper-web/src/main/webapp/pr.html
+++ b/ignite-tc-helper-web/src/main/webapp/pr.html
@@ -29,7 +29,7 @@
},
methods: {
formChanged: function () {
- checkForUpdate();
+ loadData();
}
}
});
@@ -191,7 +191,7 @@ function showData(result) {
<div id="vueQueryForm">
<v-app id="prQueryForm" name="prQueryForm">
- <span class="formgroup" style="margin: 14px">
+ <div class="formgroup">
<span>Base branch: </span>
<select v-model="baseBranchSelected" @change="formChanged">
<option disabled value="">Please select one</option>
@@ -200,9 +200,9 @@ function showData(result) {
{{ option }}
</option>
</select>
- </span>
-
- <span id="loadStatus"></span>
+
+ <span id="loadStatus"></span>
+ </div>
<div id="divFailures"></div>
</v-app>
</div>
diff --git
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
index 97f2eda..c79bcd7 100644
---
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
+++
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessorTest.java
@@ -100,7 +100,7 @@ public class BuildChainProcessorTest {
else
assertTrue(suite.failedTests() >= 1);
- for (IMultTestOccurrence test : suite.getFailedTests()) {
+ for (TestCompactedMult test : suite.getFailedTests()) {
if (test.getName().startsWith(UNIQUE_FAILED_TEST))
assertEquals(1, test.failuresCount());
else if (test.getName().equals(TEST_FAILING_EVERY_TIME))
@@ -132,7 +132,7 @@ public class BuildChainProcessorTest {
System.out.println(suite.getFailedTestsNames().collect(Collectors.toList()));
if (suite.suiteName() != null &&
suite.suiteName().startsWith(UNIQUE_FAILED_TEST)) {
- for (IMultTestOccurrence test : suite.getFailedTests())
+ for (TestCompactedMult test : suite.getFailedTests())
fail("Failure found but should be hidden by re-run " +
test.getName());
}
}
diff --git
a/tcbot-common/src/main/java/org/apache/ignite/tcbot/common/TcBotConst.java
b/tcbot-common/src/main/java/org/apache/ignite/tcbot/common/TcBotConst.java
index 44433db..0905cce 100644
--- a/tcbot-common/src/main/java/org/apache/ignite/tcbot/common/TcBotConst.java
+++ b/tcbot-common/src/main/java/org/apache/ignite/tcbot/common/TcBotConst.java
@@ -17,6 +17,8 @@
package org.apache.ignite.tcbot.common;
+import java.util.concurrent.TimeUnit;
+
/**
* TC Bot constants: contains magic numbers for project.
*
@@ -46,4 +48,7 @@ public class TcBotConst {
/** Non flaky test failure rate: less that this failure rate in base
branch is still blocker border, percents. */
public static final double
NON_FLAKY_TEST_FAIL_RATE_BLOCKER_BORDER_PERCENTS = 4.;
+
+ /** Max test duration for runall. If duration is greater, (new) test
considered as blocker. */
+ public static final long MAX_NEW_TEST_DURATION_FOR_RUNALL_MS =
TimeUnit.MINUTES.toMillis(1);
}
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/FullChainRunCtx.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/FullChainRunCtx.java
index 849ce9a..a59e210 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/FullChainRunCtx.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/FullChainRunCtx.java
@@ -63,7 +63,13 @@ public class FullChainRunCtx {
}
public Stream<MultBuildRunCtx> failedChildSuites() {
- return suites().filter(MultBuildRunCtx::isFailed);
+ Predicate<MultBuildRunCtx> filter = MultBuildRunCtx::isFailed;
+
+ return filteredChildSuites(filter);
+ }
+
+ public Stream<MultBuildRunCtx>
filteredChildSuites(Predicate<MultBuildRunCtx> filter) {
+ return suites().filter(filter);
}
/**
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/IMultTestOccurrence.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/IMultTestOccurrence.java
deleted file mode 100644
index 2348d0f..0000000
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/IMultTestOccurrence.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.tcbot.engine.chain;
-
-import org.apache.ignite.tcservice.model.result.tests.TestOccurrenceFull;
-import org.apache.ignite.tcignited.history.IRunHistory;
-
-/**
- * Multiple test occurrence. For single build context - max 1 failure
- */
-public interface IMultTestOccurrence {
- public String getName();
-
- public boolean isInvestigated();
-
- public int failuresCount();
-
- public long getAvgDurationMs();
-
- Iterable<TestOccurrenceFull> getOccurrences();
-}
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/MultBuildRunCtx.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/MultBuildRunCtx.java
index c605fa3..cd5524f 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/MultBuildRunCtx.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/MultBuildRunCtx.java
@@ -20,7 +20,6 @@ package org.apache.ignite.tcbot.engine.chain;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.cache.CacheBuilder;
-import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -33,6 +32,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
@@ -40,6 +40,7 @@ import javax.annotation.Nullable;
import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.ProblemCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.TestCompacted;
+import org.apache.ignite.tcbot.common.TcBotConst;
import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
import org.apache.ignite.tcbot.common.exeption.ExceptionUtil;
import org.apache.ignite.tcbot.common.util.CollectionUtil;
@@ -71,9 +72,13 @@ public class MultBuildRunCtx implements ISuiteResults {
/** Builds: Single execution. */
private List<SingleBuildRunCtx> builds = new CopyOnWriteArrayList<>();
- private final com.google.common.cache.Cache<Integer,
Optional<ISuiteRunHistory>> historyCacheMap
+ /** History cache map. */
+ private final com.google.common.cache.Cache<Integer,
Optional<ISuiteRunHistory>> histCacheMap
= CacheBuilder.newBuilder().build();
+ /** Tests merged: test name ID -> test compacted */
+ private volatile Map<Integer, TestCompactedMult> testsMerged = null;
+
public void addBuild(SingleBuildRunCtx ctx) {
builds.add(ctx);
}
@@ -315,23 +320,18 @@ public class MultBuildRunCtx implements ISuiteResults {
public Stream<TestCompactedMult> getTopLongRunning() {
Comparator<TestCompactedMult> comparing =
Comparator.comparing(TestCompactedMult::getAvgDurationMs);
- Map<Integer, TestCompactedMult> res = new HashMap<>();
-
- builds.forEach(singleBuildRunCtx -> {
- saveToMap(res, singleBuildRunCtx.getAllTests());
- });
-
- return CollectionUtil.top(res.values().stream(), 3,
comparing).stream();
+ return CollectionUtil.top(getTestsMerged().values().stream(), 3,
comparing).stream();
}
public List<TestCompactedMult> getFailedTests() {
- Map<Integer, TestCompactedMult> res = new HashMap<>();
-
- builds.forEach(singleBuildRunCtx -> {
- saveToMap(res, singleBuildRunCtx.getFailedNotMutedTests());
- });
+ return getFilteredTests(TestCompactedMult::isFailedButNotMuted);
+ }
- return new ArrayList<>(res.values());
+ public List<TestCompactedMult>
getFilteredTests(Predicate<TestCompactedMult> filter) {
+ return getTestsMerged().values()
+ .stream()
+ .filter(filter)
+ .collect(Collectors.toList());
}
public void saveToMap(Map<Integer, TestCompactedMult> res,
Stream<TestCompacted> tests) {
@@ -608,23 +608,48 @@ public class MultBuildRunCtx implements ISuiteResults {
return
(int)buildsStream().mapToInt(SingleBuildRunCtx::totalNotMutedTests).average().orElse(0.0);
}
- public int trustedTests(ITeamcityIgnited tcIgnited,
- @Nullable Integer branchName) {
+ /**
+ * @return all tests grouped by its name
+ */
+ private Map<Integer, TestCompactedMult> getTestsMerged() {
+ if (testsMerged == null) {
+ synchronized (this) {
+ if (testsMerged == null) {
+ HashMap<Integer, TestCompactedMult> res = new HashMap<>();
+
+ builds.forEach(singleBuildRunCtx -> {
+ saveToMap(res, singleBuildRunCtx.getAllTests());
+ });
+
+ testsMerged = res;
+ }
+ }
+ }
+ return testsMerged;
+ }
+ /**
+ * @param tcIgnited Tc ignited.
+ * @param branchName Branch name.
+ */
+ public int trustedTests(ITeamcityIgnited tcIgnited, @Nullable Integer
branchName) {
AtomicInteger trustedCnt = new AtomicInteger();
- Map<Integer, TestCompactedMult> res = new HashMap<>();
- //todo can cache mult occurrences in ctx
- builds.forEach(singleBuildRunCtx -> {
- saveToMap(res,
- singleBuildRunCtx.getAllTests().filter(t -> !t.isIgnoredTest()
&& !t.isMutedTest()));
- });
+ getFilteredTests(t -> !t.isMutedOrIgored()).forEach((testMult) -> {
+ IRunHistory baseBranchStat = testMult.history(tcIgnited,
branchName);
+
+ boolean testWillBeBlockerIfFailed = false;
- res.forEach((testNameId, compactedMult) -> {
- IRunHistory stat = compactedMult.history(tcIgnited, branchName);
- String testBlockerComment =
TestCompactedMult.getPossibleBlockerComment(stat);
- boolean b = testBlockerComment != null;
- if (b) // this test will be considered as blocker if will fail
+ if (baseBranchStat == null)
+ testWillBeBlockerIfFailed = true;
+
+ float failRate = baseBranchStat.getFailRate();
+ boolean lowFailureRate = failRate * 100.0f <
TcBotConst.NON_FLAKY_TEST_FAIL_RATE_BLOCKER_BORDER_PERCENTS;
+
+ if (lowFailureRate && !baseBranchStat.isFlaky())
+ testWillBeBlockerIfFailed = true;
+
+ if (testWillBeBlockerIfFailed) // this test will be considered as
blocker if will fail
trustedCnt.addAndGet(1);
});
@@ -667,7 +692,7 @@ public class MultBuildRunCtx implements ISuiteResults {
return null;
try {
- return historyCacheMap.get(baseBranchId,
+ return histCacheMap.get(baseBranchId,
() -> {
return
Optional.ofNullable(tcIgn.getSuiteRunHist(buildTypeIdId, baseBranchId));
})
@@ -677,4 +702,8 @@ public class MultBuildRunCtx implements ISuiteResults {
throw ExceptionUtil.propagateException(e);
}
}
+
+ public boolean hasTestToReport(ITeamcityIgnited tcIgnited, Integer
baseBranchId) {
+ return !getFilteredTests(test -> test.includeIntoReport(tcIgnited,
baseBranchId)).isEmpty();
+ }
}
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/TestCompactedMult.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/TestCompactedMult.java
index 6f25d1c..f54a509 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/TestCompactedMult.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/TestCompactedMult.java
@@ -20,6 +20,7 @@ package org.apache.ignite.tcbot.engine.chain;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.TestCompacted;
@@ -30,32 +31,39 @@ import org.apache.ignite.tcignited.history.IRunHistSummary;
import org.apache.ignite.tcignited.history.IRunHistory;
import org.apache.ignite.tcignited.history.IRunStat;
import org.apache.ignite.tcignited.history.ISuiteRunHistory;
+import org.apache.ignite.tcservice.model.result.tests.TestOccurrence;
import org.apache.ignite.tcservice.model.result.tests.TestOccurrenceFull;
/**
* Test occurrence merged from several runs.
*/
-public class TestCompactedMult implements IMultTestOccurrence {
+public class TestCompactedMult {
private final List<TestCompacted> occurrences = new ArrayList<>();
private IStringCompactor compactor;
private MultBuildRunCtx ctx;
private long avgDuration = -1;
+ /** Status success. */
+ private static volatile int STATUS_SUCCESS = -1;
+
public TestCompactedMult(IStringCompactor compactor, MultBuildRunCtx ctx) {
this.compactor = compactor;
this.ctx = ctx;
+
+ //Each time compactor should give same result
+ if (STATUS_SUCCESS == -1)
+ STATUS_SUCCESS =
compactor.getStringId(TestOccurrence.STATUS_SUCCESS);
}
@Nullable public Integer testName() {
return occurrences.isEmpty() ? null :
occurrences.iterator().next().testName();
}
- /** {@inheritDoc} */
- @Override public String getName() {
+
+ public String getName() {
return occurrences.isEmpty() ? "" :
occurrences.iterator().next().testName(compactor);
}
-
- /** {@inheritDoc} */
- @Override public boolean isInvestigated() {
+
+ public boolean isInvestigated() {
return occurrences.stream().anyMatch(TestCompacted::isInvestigated);
}
@@ -63,16 +71,14 @@ public class TestCompactedMult implements
IMultTestOccurrence {
private int getFailedButNotMutedCount() {
return (int)occurrences.stream()
.filter(Objects::nonNull)
- .filter(t -> t.isFailedButNotMuted(compactor)).count();
+ .filter(t -> t.isFailedButNotMuted(STATUS_SUCCESS)).count();
}
- /** {@inheritDoc} */
- @Override public int failuresCount() {
+ public int failuresCount() {
return getFailedButNotMutedCount();
}
- /** {@inheritDoc} */
- @Override public long getAvgDurationMs() {
+ public long getAvgDurationMs() {
if (avgDuration < 0) {
avgDuration = (long)occurrences.stream()
.map(TestCompacted::getDuration)
@@ -85,8 +91,8 @@ public class TestCompactedMult implements IMultTestOccurrence
{
return avgDuration;
}
- /** {@inheritDoc} */
- @Override public Iterable<TestOccurrenceFull> getOccurrences() {
+
+ public Iterable<TestOccurrenceFull> getOccurrences() {
return occurrences.stream()
.map(testCompacted -> testCompacted.toTestOccurrence(compactor, 0))
.collect(Collectors.toList());
@@ -96,7 +102,19 @@ public class TestCompactedMult implements
IMultTestOccurrence {
* @param baseBranchStat Base branch statistics.
* @return non null comment in case test failure is a blocker for merge
into base branch.
*/
- public static String getPossibleBlockerComment(IRunHistSummary
baseBranchStat) {
+ public String getPossibleBlockerComment(IRunHistSummary baseBranchStat) {
+ if (failuresCount() == 0) {
+ if (baseBranchStat == null) {
+ long durationMs = getAvgDurationMs();
+ if (durationMs >
TcBotConst.MAX_NEW_TEST_DURATION_FOR_RUNALL_MS)
+ return "New test duration " +
+ TimeUnit.MILLISECONDS.toSeconds(durationMs) + "s" +
+ " is more that 1 minute";
+ }
+
+ return null;
+ }
+
if (baseBranchStat == null)
return "History for base branch is absent.";
@@ -132,4 +150,35 @@ public class TestCompactedMult implements
IMultTestOccurrence {
return suiteRunHist.getTestRunHist(name);
}
+
+ /**
+ */
+ public boolean isFailedButNotMuted() {
+ return occurrences.stream().anyMatch(o ->
o.isFailedButNotMuted(STATUS_SUCCESS));
+ }
+
+ /**
+ *
+ */
+ public boolean isMutedOrIgored() {
+ return occurrences.stream().anyMatch(TestCompacted::isMutedOrIgnored);
+ }
+
+ /**
+ * Filter to determine if this test execution should be shown in the
report of failures.
+ *
+ * @param tcIgnited Tc ignited.
+ * @param baseBranchId Base branch id.
+ */
+ public boolean includeIntoReport(ITeamcityIgnited tcIgnited, Integer
baseBranchId) {
+ if (isFailedButNotMuted())
+ return true;
+
+ boolean longRun = getAvgDurationMs() >
TcBotConst.MAX_NEW_TEST_DURATION_FOR_RUNALL_MS;
+
+ if (longRun)
+ return history(tcIgnited, baseBranchId) == null;
+
+ return false;
+ }
}
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pr/PrChainsProcessor.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pr/PrChainsProcessor.java
index ad2cfb8..23b1cc5 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pr/PrChainsProcessor.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/pr/PrChainsProcessor.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.inject.Inject;
@@ -34,8 +35,8 @@ import
org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
import org.apache.ignite.tcbot.engine.chain.LatestRebuildMode;
+import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
import org.apache.ignite.tcbot.engine.chain.ProcessLogsMode;
-import org.apache.ignite.tcbot.engine.chain.TestCompactedMult;
import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
import org.apache.ignite.tcbot.engine.conf.ITrackedBranch;
import org.apache.ignite.tcbot.engine.conf.ITrackedChain;
@@ -252,7 +253,6 @@ public class PrChainsProcessor {
ICredentialsProv prov,
SyncMode syncMode,
@Nullable String baseBranchForTc) {
- //using here non persistent TC allows to skip update statistic
ITeamcityIgnited tcIgnited = tcIgnitedProvider.server(srvId, prov);
List<Integer> hist = tcIgnited.getLastNBuildsFromHistory(buildTypeId,
branchForTc, 1);
@@ -285,28 +285,33 @@ public class PrChainsProcessor {
private List<DsSuiteUi> findBlockerFailures(FullChainRunCtx
fullChainRunCtx,
ITeamcityIgnited tcIgnited,
String baseBranch) {
+ String normalizedBaseBranch = RunHistSync.normalizeBranch(baseBranch);
+ Integer baseBranchId =
compactor.getStringIdIfPresent(normalizedBaseBranch);
+
+ Predicate<MultBuildRunCtx> filter = suite ->
suite.hasTestToReport(tcIgnited, baseBranchId);
+
return fullChainRunCtx
- .failedChildSuites()
+ .filteredChildSuites(filter)
.map((ctx) -> {
- String normalizedBaseBranch =
RunHistSync.normalizeBranch(baseBranch);
- Integer baseBranchId =
compactor.getStringIdIfPresent(normalizedBaseBranch);
IRunHistory statInBaseBranch = ctx.history(tcIgnited,
baseBranchId);
String suiteComment = ctx.getPossibleBlockerComment(compactor,
statInBaseBranch, tcIgnited.config());
- List<DsTestFailureUi> failures =
ctx.getFailedTests().stream().map(occurrence -> {
- IRunHistory stat = occurrence.history(tcIgnited,
baseBranchId);
- String testBlockerComment =
TestCompactedMult.getPossibleBlockerComment(stat);
+ List<DsTestFailureUi> failures = ctx.getFilteredTests(test ->
test.includeIntoReport(tcIgnited, baseBranchId))
+ .stream()
+ .map(occurrence -> {
+ IRunHistory stat = occurrence.history(tcIgnited,
baseBranchId);
+ String testBlockerComment =
occurrence.getPossibleBlockerComment(stat);
- if (!Strings.isNullOrEmpty(testBlockerComment)) {
- final DsTestFailureUi failure = new DsTestFailureUi();
+ if (!Strings.isNullOrEmpty(testBlockerComment)) {
+ final DsTestFailureUi failure = new
DsTestFailureUi();
- failure.initFromOccurrence(occurrence, tcIgnited,
ctx.projectId(), ctx.branchName(), baseBranch, baseBranchId);
+ failure.initFromOccurrence(occurrence, tcIgnited,
ctx.projectId(), ctx.branchName(), baseBranch, baseBranchId);
- return failure;
- }
- return null;
- }).filter(Objects::nonNull).collect(Collectors.toList());
+ return failure;
+ }
+ return null;
+ }).filter(Objects::nonNull).collect(Collectors.toList());
// test failure based blockers and/or blocker found by suite
results
@@ -325,4 +330,5 @@ public class PrChainsProcessor {
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
+
}
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
index 4f1994e..2b62ffd 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsChainUi.java
@@ -198,7 +198,8 @@ public class DsChainUi {
if (dModeToUse == DisplayMode.None)
return; //don't convert any suite for UI
- if (suite.isFailed() || dModeToUse ==
DisplayMode.ShowAllSuites) {
+ if (suite.isFailed() || dModeToUse == DisplayMode.ShowAllSuites
+ || suite.hasTestToReport(tcIgnited, baseBranchId)) {
final DsSuiteUi suiteCurStatus = new DsSuiteUi();
suiteCurStatus.initFromContext(tcIgnited, suite,
baseBranchTc, compactor, true, calcTrustedTests);
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
index 0d69840..58dac7e 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsSuiteUi.java
@@ -30,6 +30,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.ignite.tcbot.common.TcBotConst;
import org.apache.ignite.tcbot.common.util.UrlUtil;
import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
import org.apache.ignite.tcbot.engine.chain.TestCompactedMult;
@@ -193,7 +194,8 @@ public class DsSuiteUi extends DsHistoryStatUi {
Integer buildTypeIdId = suite.buildTypeIdId();
if (includeTests) {
- List<TestCompactedMult> tests = suite.getFailedTests();
+ List<TestCompactedMult> tests = suite.getFilteredTests(test ->
test.includeIntoReport(tcIgnited, baseBranchId));
+
Function<TestCompactedMult, Float> function = testCompactedMult ->
{
IRunHistory res = testCompactedMult.history(tcIgnited,
baseBranchId);
diff --git
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
index 6f9f127..bf61f2a 100644
---
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
+++
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/DsTestFailureUi.java
@@ -88,6 +88,8 @@ public class DsTestFailureUi {
/** Blocker comment: indicates test seems to be introduced failure. */
@Nullable public String blockerComment;
+ public boolean success = false;
+
/**
* @param failure test ocurrence (probably multiple)
* @param tcIgn Teamcity.
@@ -102,6 +104,7 @@ public class DsTestFailureUi {
@Nullable final String branchName,
@Nullable final String baseBranchName,
Integer baseBranchId) {
+ success = !failure.isFailedButNotMuted();
name = failure.getName();
investigated = failure.isInvestigated();
curFailures = failure.failuresCount();
@@ -145,7 +148,7 @@ public class DsTestFailureUi {
});
final IRunHistory stat = failure.history(tcIgn, baseBranchId);
- blockerComment = TestCompactedMult.getPossibleBlockerComment(stat);
+ blockerComment = failure.getPossibleBlockerComment(stat);
}
/**
diff --git
a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
index 92a85df..1eeb543 100644
---
a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
+++
b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
@@ -343,7 +343,18 @@ public class TestCompacted {
}
public boolean isFailedButNotMuted(IStringCompactor compactor) {
- return isFailedTest(compactor) && !(isMutedTest() || isIgnoredTest());
+ return isFailedTest(compactor) && !(isMutedOrIgnored());
+ }
+
+ /**
+ * @param successStatus Success status code.
+ */
+ public boolean isFailedButNotMuted(int successStatus) {
+ return successStatus != status() && !isMutedOrIgnored();
+ }
+
+ public boolean isMutedOrIgnored() {
+ return isMutedTest() || isIgnoredTest();
}
public boolean isIgnoredTest() {
@@ -359,7 +370,7 @@ public class TestCompacted {
}
public boolean isFailedTest(IStringCompactor compactor) {
- return compactor.getStringId(TestOccurrence.STATUS_SUCCESS) != status;
+ return compactor.getStringId(TestOccurrence.STATUS_SUCCESS) !=
status();
}
public String testName(IStringCompactor compactor) {