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>
-        &nbsp;&nbsp;
-        <span id="loadStatus"></span>
+            &nbsp;&nbsp;
+            <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) {

Reply via email to