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 927e940  IGNITE-11994: Added query option for detailed report for 
current tracked branch - Fixes #135.
927e940 is described below

commit 927e940832659f16324acbc82961274d15967211
Author: Dmitriy Pavlov <dpav...@apache.org>
AuthorDate: Fri Jul 19 21:45:58 2019 +0300

    IGNITE-11994: Added query option for detailed report for current tracked 
branch - Fixes #135.
    
    Signed-off-by: Dmitriy Pavlov <dpav...@apache.org>
---
 .../ignite/ci/tcbot/issue/IssueDetector.java       |  11 +-
 .../ignite/ci/web/rest/GetChainResultsAsHtml.java  |   6 +-
 .../ci/web/rest/build/GetBuildTestFailures.java    |   5 +-
 .../rest/tracked/GetTrackedBranchTestResults.java  |  62 +++++++----
 ignite-tc-helper-web/src/main/webapp/current.html  | 122 ++++++++++++++++++++-
 .../src/main/webapp/js/testfails-2.2.js            |  10 +-
 ignite-tc-helper-web/src/main/webapp/pr.html       |   2 -
 .../ci/tcbot/chain/BuildChainProcessorTest.java    |   6 +-
 .../ci/tcbot/chain/TrackedBranchProcessorTest.java |   3 +-
 .../tcbot/engine/chain/BuildChainProcessor.java    |  49 ++++++---
 .../ignite/tcbot/engine/chain/FullChainRunCtx.java |  49 +++++----
 .../ignite/tcbot/engine/chain/MultBuildRunCtx.java |   7 +-
 .../ignite/tcbot/engine/chain/SortOption.java      |  45 ++++++++
 .../ignite/tcbot/engine/pr/PrChainsProcessor.java  |  15 ++-
 .../ignite/tcbot/engine/tracked/DisplayMode.java   |  45 ++++++++
 .../tracked/IDetailedStatusForTrackedBranch.java   |  11 +-
 .../tracked/TrackedBranchChainsProcessor.java      |  12 +-
 .../apache/ignite/tcbot/engine/ui/DsChainUi.java   |  92 +++++++++-------
 .../apache/ignite/tcbot/engine/ui/DsSuiteUi.java   |  13 ++-
 19 files changed, 437 insertions(+), 128 deletions(-)

diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
index ef0c678..7d6ebbb 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
@@ -37,6 +37,7 @@ import org.apache.ignite.ci.issue.Issue;
 import org.apache.ignite.ci.issue.IssueKey;
 import org.apache.ignite.ci.issue.IssueType;
 import org.apache.ignite.ci.jobs.CheckQueueJob;
+import org.apache.ignite.tcbot.engine.tracked.DisplayMode;
 import org.apache.ignite.tcbot.notify.ISlackSender;
 import org.apache.ignite.ci.tcbot.user.IUserStorage;
 import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
@@ -575,7 +576,10 @@ public class IssueDetector {
             buildsToQry,
             creds,
             SyncMode.RELOAD_QUEUED,
-            false);
+            false,
+            null,
+            DisplayMode.None,
+            null);
 
         DsSummaryUi failures =
             tbProc.getTrackedBranchTestFailures(brachName,
@@ -583,7 +587,10 @@ public class IssueDetector {
                 1,
                 creds,
                 SyncMode.RELOAD_QUEUED,
-                false);
+                false,
+                null,
+                DisplayMode.OnlyFailures,
+                null);
 
         String issRes = registerIssuesAndNotifyLater(failures, 
backgroundOpsCreds);
 
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
index f8eccb7..6fc3b53 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/GetChainResultsAsHtml.java
@@ -81,7 +81,8 @@ public class GetChainResultsAsHtml {
             ProcessLogsMode.SUITE_NOT_COMPLETE,
             false,
             failRateBranch,
-            SyncMode.RELOAD_QUEUED);
+            SyncMode.RELOAD_QUEUED,
+            null);
 
         DsChainUi status = new DsChainUi(srvCode, tcIgn.serverCode(), 
ctx.branchName());
 
@@ -89,7 +90,8 @@ public class GetChainResultsAsHtml {
 
         status.chainName = ctx.suiteName();
 
-        status.initFromContext(tcIgn, ctx, failRateBranch, 
injector.getInstance(IStringCompactor.class), false);
+        IStringCompactor c = injector.getInstance(IStringCompactor.class);
+        status.initFromContext(tcIgn, ctx, failRateBranch, c, false, null, 
null);
 
         res.append(showChainAtServerData(status));
 
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
index 6dd733e..0960b68 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/build/GetBuildTestFailures.java
@@ -131,7 +131,8 @@ public class GetBuildTestFailures {
             procLogs,
             false,
             failRateBranch,
-            syncMode);
+            syncMode,
+            null);
 
         DsChainUi chainStatus = new DsChainUi(srvCode, tcIgnited.serverCode(), 
ctx.branchName());
 
@@ -139,7 +140,7 @@ public class GetBuildTestFailures {
         if (cnt > 0)
             runningUpdates.addAndGet(cnt);
 
-        chainStatus.initFromContext(tcIgnited, ctx, failRateBranch, 
injector.getInstance(IStringCompactor.class), false);
+        chainStatus.initFromContext(tcIgnited, ctx, failRateBranch, 
injector.getInstance(IStringCompactor.class), false, null, null);
 
         res.addChainOnServer(chainStatus);
 
diff --git 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
index e0fbc41..a9affe8 100644
--- 
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
+++ 
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/tracked/GetTrackedBranchTestResults.java
@@ -19,6 +19,7 @@ package org.apache.ignite.ci.web.rest.tracked;
 
 import com.google.inject.Injector;
 import java.util.Set;
+import javax.annotation.Nonnull;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
@@ -27,14 +28,17 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
-import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
-import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.ci.tcbot.visa.TcBotTriggerAndSignOffService;
 import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.ci.web.CtxListener;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.tcbot.engine.chain.SortOption;
+import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
+import org.apache.ignite.tcbot.engine.tracked.DisplayMode;
+import org.apache.ignite.tcbot.engine.tracked.IDetailedStatusForTrackedBranch;
+import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
 import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
 import org.apache.ignite.tcbot.engine.ui.UpdateInfo;
-import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
 import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.tcservice.model.mute.MuteInfo;
@@ -61,8 +65,12 @@ public class GetTrackedBranchTestResults {
     @Path("updates")
     public UpdateInfo getTestFailsUpdates(@Nullable @QueryParam("branch") 
String branchOrNull,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs,
-        @QueryParam("trustedTests") @Nullable Boolean trustedTests) {
-        return new 
UpdateInfo().copyFrom(getTestFailsResultsNoSync(branchOrNull, checkAllLogs, 
trustedTests));
+        @Nullable @QueryParam("trustedTests") Boolean trustedTests,
+        @Nullable @QueryParam("tagSelected") String tagSelected,
+        @Nullable @QueryParam("displayMode") String displayMode,
+        @Nullable @QueryParam("sortOption") String sortOption) {
+        return new 
UpdateInfo().copyFrom(getTestFailsResultsNoSync(branchOrNull, checkAllLogs, 
trustedTests, tagSelected,
+            displayMode, sortOption));
     }
 
     @GET
@@ -70,8 +78,11 @@ public class GetTrackedBranchTestResults {
     @Produces(MediaType.TEXT_PLAIN)
     public String getTestFailsText(@Nullable @QueryParam("branch") String 
branchOrNull,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs,
-        @QueryParam("trustedTests") @Nullable Boolean trustedTests) {
-        return getTestFailsResultsNoSync(branchOrNull, checkAllLogs, 
trustedTests).toString();
+        @Nullable @QueryParam("trustedTests") Boolean trustedTests,
+        @Nullable @QueryParam("tagSelected") String tagSelected,
+        @Nullable @QueryParam("displayMode") String displayMode,
+        @Nullable @QueryParam("sortOption") String sortOption) {
+        return getTestFailsResultsNoSync(branchOrNull, checkAllLogs, 
trustedTests, tagSelected, displayMode, sortOption).toString();
     }
 
     @GET
@@ -79,8 +90,11 @@ public class GetTrackedBranchTestResults {
     public DsSummaryUi getTestFailsResultsNoSync(
         @Nullable @QueryParam("branch") String branch,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs,
-        @QueryParam("trustedTests") @Nullable Boolean trustedTests) {
-        return latestBuildResults(branch, checkAllLogs, trustedTests, 
SyncMode.NONE);
+        @Nullable @QueryParam("trustedTests") Boolean trustedTests,
+        @Nullable @QueryParam("tagSelected") String tagSelected,
+        @Nullable @QueryParam("displayMode") String displayMode,
+        @Nullable @QueryParam("sortOption") String sortOption) {
+        return latestBuildResults(branch, checkAllLogs, trustedTests, 
tagSelected, SyncMode.NONE, displayMode, sortOption);
     }
 
     @GET
@@ -89,22 +103,30 @@ public class GetTrackedBranchTestResults {
     public DsSummaryUi getTestFailsNoCache(
         @Nullable @QueryParam("branch") String branch,
         @Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs,
-        @QueryParam("trustedTests") @Nullable Boolean trustedTests) {
-        return latestBuildResults(branch, checkAllLogs, trustedTests, 
SyncMode.RELOAD_QUEUED);
+        @Nullable @QueryParam("trustedTests") Boolean trustedTests,
+        @Nullable @QueryParam("tagSelected") String tagSelected,
+        @Nullable @QueryParam("displayMode") String displayMode,
+        @Nullable @QueryParam("sortOption") String sortOption) {
+        return latestBuildResults(branch, checkAllLogs, trustedTests, 
tagSelected, SyncMode.RELOAD_QUEUED, displayMode, sortOption);
     }
 
-    @NotNull public DsSummaryUi latestBuildResults(
-        @QueryParam("branch") @Nullable String branch,
-        @QueryParam("checkAllLogs") @Nullable Boolean checkAllLogs,
-        @QueryParam("trustedTests") @Nullable Boolean trustedTests,
-        SyncMode mode) {
+    @NotNull private DsSummaryUi latestBuildResults(
+        @Nullable String branch,
+        @Nullable Boolean checkAllLogs,
+        @Nullable Boolean trustedTests,
+        @Nullable String tagSelected,
+        @Nonnull SyncMode mode,
+        @Nullable String displayMode,
+        @Nullable String sortOption) {
         ITcBotUserCreds creds = ITcBotUserCreds.get(req);
 
         Injector injector = CtxListener.getInjector(ctx);
 
-        return injector.getInstance(TrackedBranchChainsProcessor.class)
+        return injector.getInstance(IDetailedStatusForTrackedBranch.class)
             .getTrackedBranchTestFailures(branch, checkAllLogs, 1, creds, mode,
-                Boolean.TRUE.equals(trustedTests));
+                Boolean.TRUE.equals(trustedTests), tagSelected,
+                DisplayMode.parseStringValue(displayMode),
+                SortOption.parseStringValue(sortOption));
     }
 
     @GET
@@ -132,7 +154,7 @@ public class GetTrackedBranchTestResults {
         return mergedBuildsResults(branchOpt, cnt, checkAllLogs, 
SyncMode.RELOAD_QUEUED);
     }
 
-    @NotNull public DsSummaryUi mergedBuildsResults(
+    @NotNull private DsSummaryUi mergedBuildsResults(
         @QueryParam("branch") @Nullable String branchOpt,
         @QueryParam("count") Integer cnt,
         @QueryParam("checkAllLogs") @Nullable Boolean checkAllLogs,
@@ -142,7 +164,7 @@ public class GetTrackedBranchTestResults {
         Injector injector = CtxListener.getInjector(ctx);
 
         return injector.getInstance(TrackedBranchChainsProcessor.class)
-            .getTrackedBranchTestFailures(branchOpt, checkAllLogs, cntLimit, 
creds, mode, false);
+            .getTrackedBranchTestFailures(branchOpt, checkAllLogs, cntLimit, 
creds, mode, false, null, DisplayMode.OnlyFailures, null);
     }
 
     /**
diff --git a/ignite-tc-helper-web/src/main/webapp/current.html 
b/ignite-tc-helper-web/src/main/webapp/current.html
index 882a8b0..50d619a 100644
--- a/ignite-tc-helper-web/src/main/webapp/current.html
+++ b/ignite-tc-helper-web/src/main/webapp/current.html
@@ -10,17 +10,78 @@
     <script src="https://code.jquery.com/jquery-1.12.4.js";></script>
     <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js";></script>
 
+    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js";></script>
+
     <script src="js/common-1.6.js"></script>
     <script src="js/testfails-2.2.js"></script>
 </head>
 <body>
 <script>
 var g_shownDataHashCodeHex = "";
+var gVue;
+
+function genLink() {
+    let newUrl = "./current.html?";
+
+    var branch = findGetParameter("branch");
+    newUrl += "branch=" + (branch != null ? branch : "master");
+
+    if (isDefinedAndFilled(gVue.$data.tagSelected))
+        newUrl += "&tagSelected=" + gVue.$data.tagSelected;
+
+    if (gVue.$data.displayMode != null)
+        newUrl += "&displayMode=" + gVue.$data.displayMode;
+
+    if (gVue.$data.sortOption != null)
+        newUrl += "&sortOption=" + gVue.$data.sortOption;
+
+    let permalink = $("#permalink");
+    permalink.attr("href", newUrl);
+
+    permalink.html("Permalink");
+}
+
+function showQueryForm() {
+    gVue = new Vue({
+        el: '#vueQueryForm',
+        data: {
+            tagSelected: '',
+            tagsPresent: [""],
+            displayMode: 'Failures',
+            sortOption: 'FailureRate'
+        },
+        methods: {
+            formChanged: function () {
+                checkForUpdate();
+                genLink();
+            }
+        }
+    });
+
+    let tagSelected = findGetParameter("tagSelected");
+    if (tagSelected != null) {
+        gVue.$data.tagsPresent.push(tagSelected);
+        gVue.$data.tagSelected = tagSelected;
+    }
+
+    let displayMode = findGetParameter("displayMode");
+    if (displayMode != null) {
+        gVue.$data.displayMode = displayMode;
+    }
+
+    let sortOption = findGetParameter("sortOption");
+    if (sortOption != null) {
+        gVue.$data.sortOption = sortOption;
+    }
+
+    genLink();
+}
 
 $(document).ready(function() {
     $.getScript("js/testfails-2.2.js", function(data, textStatus, jqxhr){ });
     
     $( document ).tooltip();
+    showQueryForm();
     loadData();
 
     $.ajax({ url: "/rest/branches/version",  success: showVersionInfo, error: 
showErrInLoadStatus });
@@ -43,6 +104,21 @@ function parmsForRest() {
         curReqParms += "&trustedTests=" + trustedTests;
     }
 
+    var tagSelected = gVue.$data.tagSelected;
+    if (tagSelected != null) {
+        curReqParms += "&tagSelected=" + tagSelected;
+    }
+
+    var displayMode = gVue.$data.displayMode;
+    if (displayMode != null) {
+        curReqParms += "&displayMode=" + displayMode;
+    }
+
+    var sortOption = gVue.$data.sortOption;
+    if (sortOption != null) {
+        curReqParms += "&sortOption=" + sortOption;
+    }
+
     return curReqParms;
 }
 
@@ -126,6 +202,25 @@ function loadPartialData() {
 }
 
 function showData(result) {
+    let setOfTags = new Set(gVue.$data.tagsPresent);
+    for (let i = 0; i < result.servers.length; i++) {
+        let chain = result.servers[i];
+
+        for (let j = 0; j < chain.suites.length; j++) {
+            let suite = chain.suites[j];
+
+            if(isDefinedAndFilled(suite.tags)) {
+                for (let k = 0; k < suite.tags.length; k++) {
+                    const tag = suite.tags[k];
+
+                    setOfTags.add(tag);
+                }
+            }
+        }
+    }
+
+    gVue.$data.tagsPresent = Array.from(setOfTags);
+
     //var txtUrl = "rest/tracked/results/txt" + parmsForRest();
 
     $("#divFailures").html(showChainOnServersResults(result));
@@ -135,7 +230,32 @@ function showData(result) {
 </script>
 
 <div id="loadStatus"></div>
-<div id="divFailures"></div>
+
+<div id="vueQueryForm" class="h-25">
+    <v-app id="prQueryForm" name="prQueryForm" class="h-25">
+        <span>Tag filter: </span>
+        <select v-model="tagSelected" @change="formChanged">
+            <option disabled value="">Please select one</option>
+
+            <option v-for="option in tagsPresent" v-bind:value="option">
+                {{ option }}
+            </option>
+        </select>
+        <span>Display Mode: </span>
+        <select v-model="displayMode" @change="formChanged">
+            <option value="Failures">Show failures only</option>
+            <option value="AllSuites">Show all suites</option>
+        </select>
+        <span>Sort: </span>
+        <select v-model="sortOption" @change="formChanged">
+            <option value="FailureRate">Failure Rate</option>
+            <option value="SuiteDuration">Suite Duration</option>
+        </select>
+        <span> <a id="permalink"></a></span>
+        <div id="divFailures"></div>
+    </v-app>
+</div>
+
 
 <div id="version"></div>
 <div style="visibility:hidden;"><div id="triggerConfirm" title="Trigger 
Confirmation"></div><div id="triggerDialog" title="Trigger Result"></div></div>
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 88e9348..0947a62 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
@@ -614,7 +614,7 @@ function showSuiteData(suite, settings, prNum) {
     moreInfoTxt += "<br>";
 
     var res = "<tr class='suiteBlock'><td colspan='4' style='width: 100%'>" +
-              "<table style='width: 100%' border='0px'>"
+              "<table style='width: 100%' border='0px'>";
 
     res += "<tr bgcolor='#FAFAFF'><td align='right' valign='top' width='10%' 
colspan='2'>";
 
@@ -641,7 +641,13 @@ function showSuiteData(suite, settings, prNum) {
         res += "<span title='"+ suite.problemRef.name +"'>&#128030;</span> "
     }
 
-    var color = failureRateToColor(suite.failureRate);
+    var color;
+
+    if(isDefinedAndFilled(suite.success) && suite.success===true) {
+        color = 'green';
+    } else {
+        color = failureRateToColor(suite.failureRate);
+    }
 
     if (isDefinedAndFilled(suite.latestRuns)) {
         res += drawLatestRuns(suite.latestRuns) + " ";
diff --git a/ignite-tc-helper-web/src/main/webapp/pr.html 
b/ignite-tc-helper-web/src/main/webapp/pr.html
index b9f097d..278a70c 100644
--- a/ignite-tc-helper-web/src/main/webapp/pr.html
+++ b/ignite-tc-helper-web/src/main/webapp/pr.html
@@ -51,10 +51,8 @@
             },
             error: showErrInLoadStatus
         });
-
     }
 
-
     $(document).ready(function () {
         $.getScript("js/testfails-2.2.js", function (data, textStatus, jqxhr) 
{});
 
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 e8b213f..97f2eda 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
@@ -87,7 +87,7 @@ public class BuildChainProcessorTest {
 
         FullChainRunCtx ctx = bcp.loadFullChainContext(tcIgnited,
             entry,
-            LatestRebuildMode.ALL, ProcessLogsMode.SUITE_NOT_COMPLETE, false, 
ITeamcity.DEFAULT, SyncMode.NONE);
+            LatestRebuildMode.ALL, ProcessLogsMode.SUITE_NOT_COMPLETE, false, 
ITeamcity.DEFAULT, SyncMode.NONE, null);
         List<MultBuildRunCtx> suites = 
ctx.failedChildSuites().collect(Collectors.toList());
 
         assertTrue(!suites.isEmpty());
@@ -123,7 +123,7 @@ public class BuildChainProcessorTest {
 
         FullChainRunCtx ctx2 = bcp.loadFullChainContext(tcIgnited,
             entry,
-            LatestRebuildMode.ALL, ProcessLogsMode.SUITE_NOT_COMPLETE, false, 
ITeamcity.DEFAULT, SyncMode.NONE);
+            LatestRebuildMode.ALL, ProcessLogsMode.SUITE_NOT_COMPLETE, false, 
ITeamcity.DEFAULT, SyncMode.NONE, null);
         List<MultBuildRunCtx> suites2 = 
ctx2.failedChildSuites().collect(Collectors.toList());
 
         assertTrue(!suites2.isEmpty());
@@ -153,7 +153,7 @@ public class BuildChainProcessorTest {
 
         FullChainRunCtx ctx = bcp.loadFullChainContext(tcIgnitedMock(builds),
             entry,
-            LatestRebuildMode.LATEST, ProcessLogsMode.SUITE_NOT_COMPLETE, 
false, ITeamcity.DEFAULT, SyncMode.NONE);
+            LatestRebuildMode.LATEST, ProcessLogsMode.SUITE_NOT_COMPLETE, 
false, ITeamcity.DEFAULT, SyncMode.NONE, null);
         List<MultBuildRunCtx> suites = 
ctx.failedChildSuites().collect(Collectors.toList());
 
         assertTrue(!suites.isEmpty());
diff --git 
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
 
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
index c6211e6..499337a 100644
--- 
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
+++ 
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/TrackedBranchProcessorTest.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.ignite.tcbot.engine.tracked.DisplayMode;
 import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
 import org.apache.ignite.tcservice.ITeamcity;
 import org.apache.ignite.tcbot.engine.conf.BranchTracked;
@@ -120,7 +121,7 @@ public class TrackedBranchProcessorTest {
             false,
             1,
             mock, SyncMode.RELOAD_QUEUED,
-            false);
+            false, null, DisplayMode.OnlyFailures, null);
 
         Gson gson = new GsonBuilder().setPrettyPrinting().create();
         System.out.println(gson.toJson(failures));
diff --git 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
index 579dbb0..f4f38e3 100644
--- 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
+++ 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
@@ -138,16 +138,18 @@ public class BuildChainProcessor {
      * @param includeScheduledInfo Include scheduled info.
      * @param failRateBranch Fail rate branch.
      * @param mode background data update mode.
+     * @param sortOption how to sort suites in context, default is by failure 
rate (most often - first).
      */
     @AutoProfiling
     public FullChainRunCtx loadFullChainContext(
-            ITeamcityIgnited tcIgn,
-            Collection<Integer> entryPoints,
-            LatestRebuildMode includeLatestRebuild,
-            ProcessLogsMode procLog,
-            boolean includeScheduledInfo,
-            @Nullable String failRateBranch,
-            SyncMode mode) {
+        ITeamcityIgnited tcIgn,
+        Collection<Integer> entryPoints,
+        LatestRebuildMode includeLatestRebuild,
+        ProcessLogsMode procLog,
+        boolean includeScheduledInfo,
+        @Nullable String failRateBranch,
+        SyncMode mode,
+        @Nullable SortOption sortOption) {
 
         if (entryPoints.isEmpty())
             return new FullChainRunCtx(Build.createFakeStub());
@@ -199,21 +201,34 @@ public class BuildChainProcessor {
             contexts.add(ctx);
         });
 
-        Function<MultBuildRunCtx, Float> function = ctx -> {
-            IRunHistory runStat = ctx.history(tcIgn, failRateBranchId);
-
-            if (runStat == null)
-                return 0f;
-
-            //some hack to bring timed out suites to top
-            return runStat.getCriticalFailRate() * 3.14f + 
runStat.getFailRate();
-        };
 
         Integer someEntryPnt = entryPoints.iterator().next();
         Future<FatBuildCompacted> build = getOrLoadBuild(someEntryPnt, mode, 
builds, tcIgn);
         FullChainRunCtx fullChainRunCtx = new 
FullChainRunCtx(FutureUtil.getResult(build).toBuild(compactor));
 
-        contexts.sort(Comparator.comparing(function).reversed());
+        Function<MultBuildRunCtx, Double> function = null;
+
+        if (sortOption == null || sortOption == SortOption.FailureRate) {
+            function = ctx -> {
+                IRunHistory runStat = ctx.history(tcIgn, failRateBranchId);
+
+                if (runStat == null)
+                    return 0d;
+
+                //some hack to bring timed out suites to top
+                return runStat.getCriticalFailRate() * 3.14d + 
runStat.getFailRate();
+            };
+        }
+        else if (sortOption == SortOption.SuiteDuration) {
+            function = ctx -> {
+                Long duration = ctx.buildDuration();
+
+                return duration == null ? 0 : (double)duration;
+            };
+        }
+
+        if (function != null)
+            contexts.sort(Comparator.comparing(function).reversed());
 
         fullChainRunCtx.addAllSuites(contexts);
 
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 b6a2eaf..849ce9a 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
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Future;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 import org.apache.ignite.tcservice.model.result.Build;
 import org.apache.ignite.tcbot.common.util.TimeUtil;
@@ -67,28 +68,34 @@ public class FullChainRunCtx {
 
     /**
      * @return may return less time than actual duration if not all statistic 
is provided
+     * @param suiteFilter
      */
-    public Long getTotalDuration() {
-        return sumOfNonNulls(getDurations());
+    public Long getTotalDuration(
+        Predicate<MultBuildRunCtx> suiteFilter) {
+        return sumOfNonNulls(getDurations(suiteFilter));
     }
 
-    public boolean hasFullDurationInfo() {
-        return getDurations().noneMatch(Objects::isNull);
+    public boolean hasFullDurationInfo(
+        Predicate<MultBuildRunCtx> suiteFilter) {
+        return getDurations(suiteFilter).noneMatch(Objects::isNull);
     }
 
     /**
      * @return returns durations of all suites (last builds)
+     * @param suiteFilter
      */
-    private Stream<Long> getDurations() {
-        return suitesNonComposite().map(MultBuildRunCtx::buildDuration);
+    private Stream<Long> getDurations(Predicate<MultBuildRunCtx> suiteFilter) {
+        return 
suitesNonComposite().filter(suiteFilter).map(MultBuildRunCtx::buildDuration);
     }
 
     /**
      * @return sum of durations of all suites printable.
+     * @param suiteFilter
      */
-    @Nonnull public String getDurationPrintable() {
-        return (TimeUtil.millisToDurationPrintable(getTotalDuration()))
-            + (hasFullDurationInfo() ? "" : "+");
+    @Nonnull public String getDurationPrintable(
+        Predicate<MultBuildRunCtx> suiteFilter) {
+        return 
(TimeUtil.millisToDurationPrintable(getTotalDuration(suiteFilter)))
+            + (hasFullDurationInfo(suiteFilter) ? "" : "+");
     }
 
     public void addAllSuites(List<MultBuildRunCtx> suites) {
@@ -107,8 +114,8 @@ public class FullChainRunCtx {
         return fakeStub;
     }
 
-    public String getTestsDurationPrintable() {
-        long tests = 
sumOfNonNulls(suitesNonComposite().map(MultBuildRunCtx::getAvgTestsDuration));
+    public String getTestsDurationPrintable(Predicate<MultBuildRunCtx> 
suiteFilter) {
+        long tests = 
sumOfNonNulls(suitesNonComposite().filter(suiteFilter).map(MultBuildRunCtx::getAvgTestsDuration));
 
         return (TimeUtil.millisToDurationPrintable(tests));
     }
@@ -117,30 +124,30 @@ public class FullChainRunCtx {
         return suites().filter(ctx -> !ctx.isComposite());
     }
 
-    public String getLostInTimeoutsPrintable() {
-        long timeouts = 
suitesNonComposite().mapToLong(MultBuildRunCtx::getLostInTimeouts).sum();
+    public String getLostInTimeoutsPrintable(Predicate<MultBuildRunCtx> 
suiteFilter) {
+        long timeouts = 
suitesNonComposite().filter(suiteFilter).mapToLong(MultBuildRunCtx::getLostInTimeouts).sum();
 
         return TimeUtil.millisToDurationPrintable(timeouts);
     }
 
-    public String durationNetTimePrintable() {
+    public String durationNetTimePrintable(Predicate<MultBuildRunCtx> 
suiteFilter) {
         return TimeUtil.millisToDurationPrintable(
-            
sumOfNonNulls(suitesNonComposite().map(MultBuildRunCtx::buildDurationNetTime)));
+            
sumOfNonNulls(suitesNonComposite().filter(suiteFilter).map(MultBuildRunCtx::buildDurationNetTime)));
     }
 
-    public String sourceUpdateDurationPrintable() {
+    public String sourceUpdateDurationPrintable(Predicate<MultBuildRunCtx> 
suiteFilter) {
         return TimeUtil.millisToDurationPrintable(
-            
sumOfNonNulls(suitesNonComposite().map(MultBuildRunCtx::sourceUpdateDuration)));
+            
sumOfNonNulls(suitesNonComposite().filter(suiteFilter).map(MultBuildRunCtx::sourceUpdateDuration)));
     }
 
-    public String artifcactPublishingDurationPrintable() {
+    public String 
artifcactPublishingDurationPrintable(Predicate<MultBuildRunCtx> suiteFilter) {
         return TimeUtil.millisToDurationPrintable(
-            
sumOfNonNulls(suitesNonComposite().map(MultBuildRunCtx::artifcactPublishingDuration)));
+            
sumOfNonNulls(suitesNonComposite().filter(suiteFilter).map(MultBuildRunCtx::artifcactPublishingDuration)));
     }
 
-    public String dependeciesResolvingDurationPrintable() {
+    public String 
dependeciesResolvingDurationPrintable(Predicate<MultBuildRunCtx> suiteFilter) {
         return TimeUtil.millisToDurationPrintable(
-            
sumOfNonNulls(suitesNonComposite().map(MultBuildRunCtx::dependeciesResolvingDuration)));
+            
sumOfNonNulls(suitesNonComposite().filter(suiteFilter).map(MultBuildRunCtx::dependeciesResolvingDuration)));
     }
 
     public long sumOfNonNulls(Stream<Long> st) {
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 b947da0..c605fa3 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
@@ -604,12 +604,12 @@ public class MultBuildRunCtx implements ISuiteResults {
             || hasMetricProblem();
     }
 
-    public Integer totalTests() {
+    public int totalTests() {
         return 
(int)buildsStream().mapToInt(SingleBuildRunCtx::totalNotMutedTests).average().orElse(0.0);
     }
 
-    public Integer trustedTests(ITeamcityIgnited tcIgnited,
-        String normalizedBaseBranch) {
+    public int trustedTests(ITeamcityIgnited tcIgnited,
+        @Nullable Integer branchName) {
 
         AtomicInteger trustedCnt = new AtomicInteger();
         Map<Integer, TestCompactedMult> res = new HashMap<>();
@@ -619,7 +619,6 @@ public class MultBuildRunCtx implements ISuiteResults {
             saveToMap(res,
                 singleBuildRunCtx.getAllTests().filter(t -> !t.isIgnoredTest() 
&& !t.isMutedTest()));
         });
-        Integer branchName = 
compactor.getStringIdIfPresent(normalizedBaseBranch);
 
         res.forEach((testNameId, compactedMult) -> {
             IRunHistory stat = compactedMult.history(tcIgnited, branchName);
diff --git 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SortOption.java
 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SortOption.java
new file mode 100644
index 0000000..959a94c
--- /dev/null
+++ 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SortOption.java
@@ -0,0 +1,45 @@
+/*
+ * 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 com.google.common.base.Strings;
+
+public enum SortOption {
+    /** No Sort. */ None("None"),
+    /** Most Often failed. */ FailureRate("FailureRate"),
+    /** Suite Duration. */ SuiteDuration("SuiteDuration") ;
+
+    private String name;
+
+    SortOption(String name) {
+        this.name = name;
+    }
+
+    public static SortOption parseStringValue(String v) {
+        if (Strings.isNullOrEmpty(v))
+            return FailureRate;
+        SortOption[] values = SortOption.values();
+
+        for (int i = 0; i < values.length; i++) {
+            SortOption val = values[i];
+            if (val.name.equals(v))
+                return val;
+        }
+
+        return FailureRate;
+    }
+}
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 8c1640e..ad2cfb8 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
@@ -147,7 +147,8 @@ public class PrChainsProcessor {
             logs,
             buildResMergeCnt == 1,
             baseBranchForTc,
-            mode);
+            mode,
+            null);
 
         DsChainUi chainStatus = new DsChainUi(srvCodeOrAlias, 
tcIgnited.serverCode(), branchForTc);
 
@@ -162,7 +163,7 @@ public class PrChainsProcessor {
                 runningUpdates.addAndGet(cnt0);
 
             //fail rate reference is always default (master)
-            chainStatus.initFromContext(tcIgnited, ctx, baseBranchForTc, 
compactor, false); // don't need for PR
+            chainStatus.initFromContext(tcIgnited, ctx, baseBranchForTc, 
compactor, false, null, null); // don't need for PR
 
             initJiraAndGitInfo(chainStatus, jiraIntegration, 
gitHubConnIgnited);
         }
@@ -265,7 +266,8 @@ public class PrChainsProcessor {
             ProcessLogsMode.SUITE_NOT_COMPLETE,
             false,
             baseBranch,
-            syncMode);
+            syncMode,
+            null);
 
         if (ctx.isFakeStub())
             return null;
@@ -274,14 +276,15 @@ public class PrChainsProcessor {
     }
 
     /**
-     * @return Failures for given server.
+     * @return Blocker failures for given server.
      * @param fullChainRunCtx
      * @param tcIgnited
      * @param baseBranch
      */
     //todo may avoid creation of UI model for simple comment.
-    private List<DsSuiteUi> findBlockerFailures(FullChainRunCtx 
fullChainRunCtx, ITeamcityIgnited tcIgnited,
-                                                String baseBranch) {
+    private List<DsSuiteUi> findBlockerFailures(FullChainRunCtx 
fullChainRunCtx,
+        ITeamcityIgnited tcIgnited,
+        String baseBranch) {
         return fullChainRunCtx
             .failedChildSuites()
             .map((ctx) -> {
diff --git 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/DisplayMode.java
 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/DisplayMode.java
new file mode 100644
index 0000000..77fd6b7
--- /dev/null
+++ 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/DisplayMode.java
@@ -0,0 +1,45 @@
+/*
+ * 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.tracked;
+
+import com.google.common.base.Strings;
+
+public enum DisplayMode {
+    /** Technical mode for skipping UI conversions. */ None("None"),
+    /** Show only  Failures. */ OnlyFailures("Failures"),
+    /** Show all suites. */ ShowAllSuites("AllSuites");
+
+    private String name;
+
+    DisplayMode(String name) {
+        this.name = name;
+    }
+
+    public static DisplayMode parseStringValue(String v) {
+        if (Strings.isNullOrEmpty(v))
+            return OnlyFailures;
+        DisplayMode[] values = DisplayMode.values();
+
+        for (int i = 0; i < values.length; i++) {
+            DisplayMode val = values[i];
+            if (val.name.equals(v))
+                return val;
+        }
+
+        return OnlyFailures;
+    }
+}
diff --git 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/IDetailedStatusForTrackedBranch.java
 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/IDetailedStatusForTrackedBranch.java
index 8b9372c..851ba38 100644
--- 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/IDetailedStatusForTrackedBranch.java
+++ 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/IDetailedStatusForTrackedBranch.java
@@ -17,6 +17,7 @@
 package org.apache.ignite.tcbot.engine.tracked;
 
 import javax.annotation.Nullable;
+import org.apache.ignite.tcbot.engine.chain.SortOption;
 import org.apache.ignite.tcbot.engine.ui.DsSummaryUi;
 import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.tcignited.creds.ICredentialsProv;
@@ -31,7 +32,10 @@ public interface IDetailedStatusForTrackedBranch {
      * @param buildResMergeCnt Build results merge count.
      * @param creds Credentials.
      * @param syncMode Sync mode.
-     * @param calcTrustedTests Calc trusted tests.
+     * @param calcTrustedTests Calculate trusted tests count.
+     * @param tagSelected Selected tag based filter. If null or empty all data 
is returned.
+     * @param displayMode Suites and tests display mode. Default - failures 
only.
+     * @param sortOption Sort mode
      */
     public DsSummaryUi getTrackedBranchTestFailures(
         @Nullable String branch,
@@ -39,7 +43,10 @@ public interface IDetailedStatusForTrackedBranch {
         int buildResMergeCnt,
         ICredentialsProv creds,
         SyncMode syncMode,
-        boolean calcTrustedTests);
+        boolean calcTrustedTests,
+        @Nullable String tagSelected,
+        @Nullable DisplayMode displayMode,
+        @Nullable SortOption sortOption);
 
     //  * @param baseTrackedBranch Branch tracked branch in Bot, has a 
priority if both TC & Bot branches (baseBranchForTcParm) present.
 }
diff --git 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
index a266d3c..8777df3 100644
--- 
a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
+++ 
b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/tracked/TrackedBranchChainsProcessor.java
@@ -28,6 +28,7 @@ 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.ProcessLogsMode;
+import org.apache.ignite.tcbot.engine.chain.SortOption;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.tcbot.engine.conf.ITrackedBranch;
 import org.apache.ignite.tcbot.engine.ui.DsChainUi;
@@ -57,6 +58,7 @@ public class TrackedBranchChainsProcessor implements 
IDetailedStatusForTrackedBr
     /** Compactor. */
     @Inject private IStringCompactor compactor;
 
+    /** {@inheritDoc} */
     @AutoProfiling
     @Nonnull
     @Override public DsSummaryUi getTrackedBranchTestFailures(
@@ -65,7 +67,10 @@ public class TrackedBranchChainsProcessor implements 
IDetailedStatusForTrackedBr
         int buildResMergeCnt,
         ICredentialsProv creds,
         SyncMode syncMode,
-        boolean calcTrustedTests) {
+        boolean calcTrustedTests,
+        @Nullable String tagSelected,
+        @Nullable DisplayMode displayMode,
+        @Nullable SortOption sortOption) {
         final DsSummaryUi res = new DsSummaryUi();
         final AtomicInteger runningUpdates = new AtomicInteger();
 
@@ -113,14 +118,15 @@ public class TrackedBranchChainsProcessor implements 
IDetailedStatusForTrackedBr
                     logs,
                     includeScheduled,
                     baseBranchTc,
-                    syncMode
+                    syncMode,
+                    sortOption
                 );
 
                 int cnt = (int)ctx.getRunningUpdates().count();
                 if (cnt > 0)
                     runningUpdates.addAndGet(cnt);
 
-                chainStatus.initFromContext(tcIgnited, ctx, baseBranchTc, 
compactor, calcTrustedTests);
+                chainStatus.initFromContext(tcIgnited, ctx, baseBranchTc, 
compactor, calcTrustedTests, tagSelected, displayMode);
 
                 return chainStatus;
             })
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 a6904c7..4f1994e 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
@@ -17,11 +17,13 @@
 
 package org.apache.ignite.tcbot.engine.ui;
 
+import com.google.common.base.Strings;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import org.apache.ignite.internal.util.typedef.T2;
@@ -30,6 +32,7 @@ import org.apache.ignite.tcbot.common.util.UrlUtil;
 import org.apache.ignite.tcbot.engine.chain.FullChainRunCtx;
 import org.apache.ignite.tcbot.engine.chain.MultBuildRunCtx;
 import org.apache.ignite.tcbot.engine.chain.TestCompactedMult;
+import org.apache.ignite.tcbot.engine.tracked.DisplayMode;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcservice.model.conf.BuildType;
@@ -37,6 +40,7 @@ import org.apache.ignite.tcservice.model.conf.BuildType;
 import static org.apache.ignite.tcbot.engine.ui.DsSuiteUi.branchForLink;
 import static 
org.apache.ignite.tcbot.engine.ui.DsSuiteUi.createOccurForLogConsumer;
 import static 
org.apache.ignite.tcbot.engine.ui.DsSuiteUi.createOrrucForLongRun;
+import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
 
 /**
  * Detailed status of PR or tracked branch for chain.
@@ -155,62 +159,74 @@ public class DsChainUi {
         this.webToPr = webToPr;
     }
 
-
-
-
     public void initFromContext(ITeamcityIgnited tcIgnited,
         FullChainRunCtx ctx,
         @Nullable String baseBranchTc,
         IStringCompactor compactor,
-        boolean calcTrustedTests) {
+        boolean calcTrustedTests,
+        @Nullable String tagSelected,
+        @Nullable DisplayMode displayMode) {
         failedTests = 0;
         failedToFinish = 0;
         totalTests = 0;
         trustedTests = 0;
-        //todo mode with not failed
-        Stream<MultBuildRunCtx> stream = ctx.failedChildSuites();
 
-        stream.forEach(
-            suite -> {
-                final DsSuiteUi suiteCurStatus = new DsSuiteUi();
+        String failRateNormalizedBranch = normalizeBranch(baseBranchTc);
+        Integer baseBranchId = 
compactor.getStringIdIfPresent(failRateNormalizedBranch);
 
-                suiteCurStatus.initFromContext(tcIgnited, suite, baseBranchTc, 
compactor, true, calcTrustedTests);
+        DisplayMode dModeToUse
+            = displayMode == null ? DisplayMode.OnlyFailures : displayMode;
 
-                failedTests += suiteCurStatus.failedTests != null ? 
suiteCurStatus.failedTests : 0;
-                totalTests += suiteCurStatus.totalTests != null ? 
suiteCurStatus.totalTests : 0;
-                trustedTests += suiteCurStatus.trustedTests != null ? 
suiteCurStatus.trustedTests : 0;
-                if (suite.hasAnyBuildProblemExceptTestOrSnapshot() || 
suite.onlyCancelledBuilds())
-                    failedToFinish++;
+        Predicate<MultBuildRunCtx> suiteFilter = suite -> {
+            if (Strings.isNullOrEmpty(tagSelected))
+                return true;
 
-                suites.add(suiteCurStatus);
-            }
-        );
+            return suite.tags().contains(tagSelected);
+        };
 
-        if(calcTrustedTests) {
-            //todo odd convertion
-            ctx.suites().filter(s -> !s.isFailed()).forEach(suite -> {
+        ctx.suites()
+            .filter(suite -> !suite.isComposite())
+            .filter(suiteFilter)
+            .peek(suite -> {
+                Integer totalTests = suite.totalTests();
+                this.totalTests += totalTests != null ? totalTests : 0;
 
-                final DsSuiteUi suiteCurStatus = new DsSuiteUi();
+                if (calcTrustedTests)
+                    trustedTests += suite.trustedTests(tcIgnited, 
baseBranchId);
+            })
+            .forEach(suite -> {
+                if (dModeToUse == DisplayMode.None)
+                    return; //don't convert any suite for UI
 
-                suiteCurStatus.initFromContext(tcIgnited, suite, baseBranchTc, 
compactor, true, calcTrustedTests);
+                if (suite.isFailed() || dModeToUse == 
DisplayMode.ShowAllSuites) {
+                    final DsSuiteUi suiteCurStatus = new DsSuiteUi();
 
-                totalTests += suiteCurStatus.totalTests != null ? 
suiteCurStatus.totalTests : 0;
-                trustedTests += suiteCurStatus.trustedTests != null ? 
suiteCurStatus.trustedTests : 0;
+                    suiteCurStatus.initFromContext(tcIgnited, suite, 
baseBranchTc, compactor, true, calcTrustedTests);
+
+                    failedTests += suiteCurStatus.failedTests != null ? 
suiteCurStatus.failedTests : 0;
+
+                    if (suite.hasAnyBuildProblemExceptTestOrSnapshot() || 
suite.onlyCancelledBuilds())
+                        failedToFinish++;
+
+                    suites.add(suiteCurStatus);
+                }
             });
-        }
 
         totalBlockers = 
suites.stream().mapToInt(DsSuiteUi::totalBlockers).sum();
-        durationPrintable = ctx.getDurationPrintable();
-        testsDurationPrintable = ctx.getTestsDurationPrintable();
-        durationNetTimePrintable = ctx.durationNetTimePrintable();
-        sourceUpdateDurationPrintable = ctx.sourceUpdateDurationPrintable();
-        artifcactPublishingDurationPrintable = 
ctx.artifcactPublishingDurationPrintable();
-        dependeciesResolvingDurationPrintable = 
ctx.dependeciesResolvingDurationPrintable();
-        lostInTimeouts = ctx.getLostInTimeoutsPrintable();
+        durationPrintable = ctx.getDurationPrintable(suiteFilter);
+        testsDurationPrintable = ctx.getTestsDurationPrintable(suiteFilter);
+        durationNetTimePrintable = ctx.durationNetTimePrintable(suiteFilter);
+        sourceUpdateDurationPrintable = 
ctx.sourceUpdateDurationPrintable(suiteFilter);
+        artifcactPublishingDurationPrintable = 
ctx.artifcactPublishingDurationPrintable(suiteFilter);
+        dependeciesResolvingDurationPrintable = 
ctx.dependeciesResolvingDurationPrintable(suiteFilter);
+        lostInTimeouts = ctx.getLostInTimeoutsPrintable(suiteFilter);
         webToHist = buildWebLink(tcIgnited, ctx);
         webToBuild = buildWebLinkToBuild(tcIgnited, ctx);
 
-        Stream<T2<MultBuildRunCtx, TestCompactedMult>> allLongRunning = 
ctx.suites().flatMap(
+        Stream<T2<MultBuildRunCtx, TestCompactedMult>> allLongRunning = 
ctx.suites()
+            .filter(suite -> !suite.isComposite())
+            .filter(suiteFilter)
+            .flatMap(
             suite -> suite.getTopLongRunning().map(t -> new T2<>(suite, t))
         );
         Comparator<T2<MultBuildRunCtx, TestCompactedMult>> durationComp
@@ -229,9 +245,11 @@ public class DsChainUi {
             }
         );
 
-        Stream<T2<MultBuildRunCtx, Map.Entry<String, Long>>> allLogConsumers = 
ctx.suites().flatMap(
-            suite -> suite.getTopLogConsumers().map(t -> new T2<>(suite, t))
-        );
+        Stream<T2<MultBuildRunCtx, Map.Entry<String, Long>>> allLogConsumers = 
ctx.suites()
+            .filter(suite -> !suite.isComposite())
+            .filter(suiteFilter)
+            .flatMap(suite -> suite.getTopLogConsumers().map(t -> new 
T2<>(suite, t)));
+
         Comparator<T2<MultBuildRunCtx, Map.Entry<String, Long>>> 
longConsumingComp
             = Comparator.comparing((pair) -> pair.get2().getValue());
 
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 eea9212..0d69840 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
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
@@ -145,6 +146,8 @@ public class DsSuiteUi extends DsHistoryStatUi {
      */
     @Nullable public String blockerComment;
 
+    public boolean success = false;
+
     /**
      * @param tcIgnited Tc ignited.
      * @param suite Suite.
@@ -209,9 +212,11 @@ public class DsSuiteUi extends DsHistoryStatUi {
             });
 
             suite.getTopLongRunning().forEach(occurrence -> {
-                final DsTestFailureUi failure = 
createOrrucForLongRun(tcIgnited, compactor, suite, occurrence, baseBranch);
+                if (occurrence.getAvgDurationMs() > 
TimeUnit.SECONDS.toMillis(15)) {
+                    final DsTestFailureUi failure = 
createOrrucForLongRun(tcIgnited, compactor, suite, occurrence, baseBranch);
 
-                topLongRunning.add(failure);
+                    topLongRunning.add(failure);
+                }
             });
 
             suite.getCriticalFailLastStartedTest().forEach(
@@ -240,7 +245,7 @@ public class DsSuiteUi extends DsHistoryStatUi {
             totalTests = suite.totalTests();
 
             if(calcTrustedTests)
-                trustedTests = suite.trustedTests(tcIgnited, 
failRateNormalizedBranch);
+                trustedTests = suite.trustedTests(tcIgnited, baseBranchId);
         }
 
         suite.getBuildsWithThreadDump().forEach(buildId -> {
@@ -260,6 +265,8 @@ public class DsSuiteUi extends DsHistoryStatUi {
 
         blockerComment = suite.getPossibleBlockerComment(compactor, 
baseBranchHist, tcIgnited.config());
 
+        success = !suite.isFailed();
+
         return this;
     }
 

Reply via email to