You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dp...@apache.org on 2019/08/05 13:57:55 UTC

[ignite-teamcity-bot] branch master updated: IGNITE-10095: Filter suite and test history by build tag finished, Suite History made versioned entity and enforced to rebuild for tags filter, UI bugs fixed - Fixes #144.

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 09bb801  IGNITE-10095: Filter suite and test history by build tag finished, Suite History made versioned entity and enforced to rebuild for tags filter, UI bugs fixed - Fixes #144.
09bb801 is described below

commit 09bb8018cdf9226718922b5ee393e9f6157c0e1d
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Mon Aug 5 16:57:41 2019 +0300

    IGNITE-10095: Filter suite and test history by build tag finished, Suite History made versioned entity and enforced to rebuild for tags filter, UI bugs fixed - Fixes #144.
    
    Signed-off-by: Dmitriy Pavlov <dp...@apache.org>
---
 .../ignite/ci/tcbot/issue/IssueDetector.java       |  2 +-
 .../org/apache/ignite/ci/web/model/Version.java    |  2 +-
 .../ignite/ci/web/rest/GetChainResultsAsHtml.java  |  2 +-
 .../ci/web/rest/build/GetBuildTestFailures.java    |  2 +-
 ignite-tc-helper-web/src/main/webapp/current.html  | 20 +++---
 .../ci/teamcity/ignited/TeamcityIgnitedMock.java   |  2 +-
 .../IgnitedTcInMemoryIntegrationTest.java          |  3 -
 .../tcbot/engine/chain/BuildChainProcessor.java    | 25 ++-----
 .../ignite/tcbot/engine/chain/MultBuildRunCtx.java | 33 ++++++----
 .../tcbot/engine/chain/TestCompactedMult.java      | 22 +++++--
 .../ignite/tcbot/engine/pr/PrChainsProcessor.java  |  9 +--
 .../tracked/TrackedBranchChainsProcessor.java      |  3 +-
 .../apache/ignite/tcbot/engine/ui/DsChainUi.java   | 24 ++++---
 .../apache/ignite/tcbot/engine/ui/DsSuiteUi.java   | 64 +++++++++---------
 .../ignite/tcbot/engine/ui/DsTestFailureUi.java    | 36 +++++++---
 .../ignited/buildtype/ParametersCompacted.java     | 25 +++++--
 .../ignited/fatbuild/FatBuildCompacted.java        | 14 +++-
 .../ci/teamcity/ignited/runhist/Invocation.java    | 28 +++++++-
 .../teamcity/ignited/runhist/InvocationData.java   |  4 ++
 .../teamcity/ignited/runhist/RunHistCompacted.java | 38 +++++++++--
 .../ignite/tcignited/TeamcityIgnitedImpl.java      |  4 +-
 .../ignite/tcignited/TeamcityIgnitedModule.java    |  2 -
 .../tcignited/build/ProactiveFatBuildSync.java     |  4 --
 .../ignite/tcignited/build/SuiteHistory.java       | 16 +++++
 .../ignite/tcignited/build/TestCompactedV2.java    | 28 ++------
 .../tcignited/buildref/BranchEquivalence.java      | 17 +++++
 .../ignite/tcignited/history/HistoryCollector.java | 64 +++++++++++-------
 .../ignite/tcignited/history/IRunHistory.java      |  3 +
 .../ignite/tcignited/history/ISuiteRunHistory.java |  4 ++
 .../ignite/tcignited/history/RunHistSync.java      | 77 ----------------------
 .../ignite/tcignited/history/SuiteInvocation.java  | 23 ++++++-
 .../history/SuiteInvocationHistoryDao.java         | 19 ++++--
 32 files changed, 355 insertions(+), 264 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 2a33891..2feb8c9 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
@@ -67,7 +67,7 @@ import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
+import static org.apache.ignite.tcignited.buildref.BranchEquivalence.normalizeBranch;
 
 /**
  *
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 cc318cf..0fbf12d 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 = "20190803";
+    public static final String VERSION = "20190804";
 
     /** Java version, where Web App is running. */
     public String javaVer;
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 55dd5ad..04c493d 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
@@ -92,7 +92,7 @@ public class GetChainResultsAsHtml {
         status.chainName = ctx.suiteName();
 
         IStringCompactor c = injector.getInstance(IStringCompactor.class);
-        status.initFromContext(tcIgn, ctx, failRateBranch, c, false, null, null, -1);
+        status.initFromContext(tcIgn, ctx, failRateBranch, c, false, null, null, -1, 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 2b38122..6de270d 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
@@ -141,7 +141,7 @@ public class GetBuildTestFailures {
         if (cnt > 0)
             runningUpdates.addAndGet(cnt);
 
-        chainStatus.initFromContext(tcIgnited, ctx, failRateBranch, injector.getInstance(IStringCompactor.class), false, null, null, -1);
+        chainStatus.initFromContext(tcIgnited, ctx, failRateBranch, injector.getInstance(IStringCompactor.class), false, null, null, -1, null);
 
         res.addChainOnServer(chainStatus);
 
diff --git a/ignite-tc-helper-web/src/main/webapp/current.html b/ignite-tc-helper-web/src/main/webapp/current.html
index ac78792..115f358 100644
--- a/ignite-tc-helper-web/src/main/webapp/current.html
+++ b/ignite-tc-helper-web/src/main/webapp/current.html
@@ -110,7 +110,11 @@ function showQueryForm() {
         gVue.$data.count = count;
     }
 
-    gVue.$data.trustedTests = findGetParameter("trustedTests") === "true";
+    let parm = findGetParameter("trustedTests");
+    if (isDefinedAndFilled(parm)) {
+        gVue.$data.trustedTests = parm === "true";
+    }
+
     gVue.$data.checkAllLogs = findGetParameter("checkAllLogs") === "true";
     gVue.$data.hideFlakyFailures = findGetParameter("hideFlakyFailures") === "true";
 
@@ -267,7 +271,7 @@ function loadPartialData() {
 
 function showData(result) {
     let setOfTags = new Set(gVue.$data.tagsPresent);
-    let setOfHistTags = new Set(gVue.$data.tagForHistSelected);
+    let setOfHistTags = new Set(gVue.$data.tagsForHistPresent);
     for (let i = 0; i < result.servers.length; i++) {
         let chain = result.servers[i];
 
@@ -320,7 +324,7 @@ function showData(result) {
                             </option>
                         </select>
 
-                        <span title="Tag filter for filtering history of suites">History tag filter: </span>
+                        &nbsp;&nbsp;&nbsp;<span title="Tag filter for filtering history of suites">History tag filter: </span>
                         <select v-model="tagForHistSelected" @change="formChanged">
                             <option disabled value="">Please select one</option>
 
@@ -334,20 +338,20 @@ function showData(result) {
                             <option value="Failures">Show failures only</option>
                             <option value="AllSuites">Show all suites</option>
                         </select>
-                        <span>Sort: </span>
+                        &nbsp;&nbsp;&nbsp;<span>Sort: </span>
                         <select v-model="sortOption" @change="formChanged">
                             <option value="FailureRate">Failure Rate</option>
                             <option value="SuiteDuration">Suite Duration</option>
                         </select>
-                        <span>Merge Builds: </span>
+                        &nbsp;&nbsp;&nbsp;<span>Merge Builds: </span>
                         <input v-model.number="count" type="number" @change="formChanged">
 
-                        <br>&nbsp;&nbsp;<span title="Show trusted tests count">Trusted tests: </span>
+                        <br><span title="Show trusted tests count">Trusted tests: </span>
                         <input type="checkbox" v-model="trustedTests" @change="formChanged">
-                        &nbsp;&nbsp;<span title="Download and parse all logs">Check logs: </span>
+                        &nbsp;&nbsp;&nbsp;<span title="Download and parse all logs">Check logs: </span>
                         <input type="checkbox" v-model="checkAllLogs" @change="formChanged">
 
-                        <span>Show test longer than, seconds: </span>
+                        &nbsp;&nbsp;&nbsp;<span>Show test longer than, seconds: </span>
                         <input v-model.number="showTestLongerThan" type="number" @change="formChanged">
                     </td>
 
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedMock.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedMock.java
index 2de7fee..b4484dd 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedMock.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedMock.java
@@ -183,7 +183,7 @@ public class TeamcityIgnitedMock {
 
                 final RunHistCompacted hist = histCache.computeIfAbsent(histKey, RunHistCompacted::new);
 
-                Invocation inv = TestCompactedV2.toInvocation(testCompacted, build, (k, v) -> false, successStatusStrId);
+                Invocation inv = TestCompactedV2.toInvocation(testCompacted, build, successStatusStrId);
 
                 hist.addInvocation(inv);
             });
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
index da0a89c..1b34e77 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/tcignited/IgnitedTcInMemoryIntegrationTest.java
@@ -50,7 +50,6 @@ import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
 import org.apache.ignite.tcignited.history.IRunHistory;
 import org.apache.ignite.tcignited.history.ISuiteRunHistory;
 import org.apache.ignite.tcignited.history.BuildStartTimeStorage;
-import org.apache.ignite.tcignited.history.RunHistSync;
 import org.apache.ignite.tcservice.ITeamcity;
 import org.apache.ignite.tcservice.TeamcityServiceConnection;
 import org.apache.ignite.tcservice.http.ITeamcityHttpConnection;
@@ -623,8 +622,6 @@ public class IgnitedTcInMemoryIntegrationTest {
             buildRefDao.save(srvIdMaskHigh, new BuildRefCompacted(build));
         });
 
-        final RunHistSync histSync = injector.getInstance(RunHistSync.class);
-
         final IRunHistory testRunHist = srv.getTestRunHist(c.getStringId(PrChainsProcessorTest.TEST_FLAKY_IN_MASTER),
             c.getStringId(PrChainsProcessorTest.CACHE_1),
             c.getStringId(branch));
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 e1f68b8..09eb044 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
@@ -41,6 +41,7 @@ import javax.inject.Inject;
 import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
 import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
 import org.apache.ignite.tcbot.common.util.FutureUtil;
 import org.apache.ignite.tcbot.engine.pool.TcUpdatePool;
@@ -50,8 +51,8 @@ import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.tcignited.buildlog.IBuildLogProcessor;
+import org.apache.ignite.tcignited.buildref.BranchEquivalence;
 import org.apache.ignite.tcignited.history.IRunHistory;
-import org.apache.ignite.tcignited.history.RunHistSync;
 import org.apache.ignite.tcservice.model.hist.BuildRef;
 import org.apache.ignite.tcservice.model.result.Build;
 import org.slf4j.Logger;
@@ -138,7 +139,7 @@ public class BuildChainProcessor {
      * @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).
-     * @param requireParamVal Require exact parameters value presence in the build.
+     * @param requireParamVal Require exact parameters value presence in the build. Null means no filtering.
      */
     @AutoProfiling
     public FullChainRunCtx loadFullChainContext(
@@ -155,7 +156,7 @@ public class BuildChainProcessor {
         if (entryPoints.isEmpty())
             return new FullChainRunCtx(Build.createFakeStub());
 
-        Integer failRateBranchId = compactor.getStringIdIfPresent(RunHistSync.normalizeBranch(failRateBranch));
+        Integer failRateBranchId = compactor.getStringIdIfPresent(BranchEquivalence.normalizeBranch(failRateBranch));
 
         Map<Integer, Future<FatBuildCompacted>> builds = loadAllBuildsInChains(entryPoints, mode, tcIgn);
 
@@ -193,7 +194,7 @@ public class BuildChainProcessor {
 
             //ask for history for the suite in parallel
             tcUpdatePool.getService().submit(() -> {
-                ctx.history(tcIgn, failRateBranchId);
+                ctx.history(tcIgn, failRateBranchId, null);
             });
 
             analyzeTests(ctx, tcIgn, procLog);
@@ -212,7 +213,7 @@ public class BuildChainProcessor {
 
         if (sortOption == null || sortOption == SortOption.FailureRate) {
             function = ctx -> {
-                IRunHistory runStat = ctx.history(tcIgn, failRateBranchId);
+                IRunHistory runStat = ctx.history(tcIgn, failRateBranchId, null);
 
                 if (runStat == null)
                     return 0d;
@@ -398,19 +399,7 @@ public class BuildChainProcessor {
     private boolean hasAnyParameterValue(@Nonnull Map<Integer, Integer> requireParamVal, FatBuildCompacted fatBuild) {
         ParametersCompacted parameters = fatBuild.parameters();
 
-        if (parameters == null)
-            return false;
-
-        Set<Map.Entry<Integer, Integer>> entries = requireParamVal.entrySet();
-        for (Map.Entry<Integer, Integer> next : entries) {
-            Integer key = next.getKey();
-
-            int valId = parameters.findPropertyStringId(key);
-            if (Objects.equals(next.getValue(), valId))
-                return true;
-        }
-
-        return false;
+        return Invocation.hasAnyParameterValue(parameters, requireParamVal);
     }
 
     @SuppressWarnings("WeakerAccess")
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 7e2b48a..106daf2 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
@@ -162,12 +162,12 @@ public class MultBuildRunCtx implements ISuiteResults {
 
     /** */
     public long getMetricProblemCount() {
-        return buildsStream().filter(ISuiteResults::hasMetricProblem).count();
+        return buildsStream().filter(SingleBuildRunCtx::hasMetricProblem).count();
     }
 
     /** */
     public long getBuildMessageProblemCount() {
-        return buildsStream().filter(ISuiteResults::hasBuildMessageProblem).count();
+        return buildsStream().filter(SingleBuildRunCtx::hasBuildMessageProblem).count();
     }
 
     /** {@inheritDoc} */
@@ -177,7 +177,7 @@ public class MultBuildRunCtx implements ISuiteResults {
 
     /** */
     public long getCompilationProblemCount() {
-        return buildsStream().filter(ISuiteResults::hasCompilationProblem).count();
+        return buildsStream().filter(SingleBuildRunCtx::hasCompilationProblem).count();
     }
 
     /** {@inheritDoc} */
@@ -209,11 +209,11 @@ public class MultBuildRunCtx implements ISuiteResults {
     }
 
     private long getExitCodeProblemsCount() {
-        return buildsStream().filter(ISuiteResults::hasExitCodeProblem).count();
+        return buildsStream().filter(SingleBuildRunCtx::hasExitCodeProblem).count();
     }
 
     private long getOomeProblemCount() {
-        return buildsStream().filter(ISuiteResults::hasOomeProblem).count();
+        return buildsStream().filter(SingleBuildRunCtx::hasOomeProblem).count();
     }
 
     public int failedTests() {
@@ -672,11 +672,13 @@ public class MultBuildRunCtx implements ISuiteResults {
      * @param tcIgn Tc ign.
      * @param baseBranchId Base branch id.
      */
-    public IRunHistory history(ITeamcityIgnited tcIgn, Integer baseBranchId) {
+    public IRunHistory history(ITeamcityIgnited tcIgn,
+        @Nullable Integer baseBranchId,
+        @Nullable Map<Integer, Integer> requireParameters) {
         if (baseBranchId == null)
             return null;
 
-        ISuiteRunHistory suiteHist = suiteHist(tcIgn, baseBranchId);
+        ISuiteRunHistory suiteHist = suiteHist(tcIgn, baseBranchId, requireParameters);
         if (suiteHist == null)
             return null;
 
@@ -684,7 +686,9 @@ public class MultBuildRunCtx implements ISuiteResults {
     }
 
     @Nullable
-    ISuiteRunHistory suiteHist(ITeamcityIgnited tcIgn, @Nullable Integer baseBranchId) {
+    ISuiteRunHistory suiteHist(ITeamcityIgnited tcIgn,
+        @Nullable Integer baseBranchId,
+        @Nullable Map<Integer, Integer> requireParameters) {
         Integer buildTypeIdId = buildTypeIdId();
         Preconditions.checkNotNull(buildTypeIdId, "Build type ID should be filled");
 
@@ -693,14 +697,17 @@ public class MultBuildRunCtx implements ISuiteResults {
             return null;
 
         try {
-            return histCacheMap.get(baseBranchId,
-                () -> {
-                    return Optional.ofNullable(tcIgn.getSuiteRunHist(buildTypeIdId, baseBranchId));
-                })
+            ISuiteRunHistory suiteRunHistory = histCacheMap.get(baseBranchId,
+                () -> Optional.ofNullable(tcIgn.getSuiteRunHist(buildTypeIdId, baseBranchId)))
                 .orElse(null);
+
+            if (suiteRunHistory != null && requireParameters != null && !requireParameters.isEmpty())
+                return suiteRunHistory.filter(requireParameters);
+
+            return suiteRunHistory;
         }
         catch (ExecutionException e) {
-            throw  ExceptionUtil.propagateException(e);
+            throw ExceptionUtil.propagateException(e);
         }
     }
 
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 a37faaf..8462bb8 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
@@ -17,12 +17,6 @@
 
 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.Stream;
-import javax.annotation.Nullable;
 import org.apache.ignite.tcbot.common.TcBotConst;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
@@ -33,6 +27,14 @@ import org.apache.ignite.tcignited.history.IRunStat;
 import org.apache.ignite.tcignited.history.ISuiteRunHistory;
 import org.apache.ignite.tcservice.model.result.tests.TestOccurrence;
 
+import javax.annotation.Nullable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
 /**
  * Test occurrence merged from several runs.
  */
@@ -138,11 +140,17 @@ public class TestCompactedMult {
     }
 
     public IRunHistory history(ITeamcityIgnited ignited, @Nullable Integer baseBranchId) {
+         return history(ignited, baseBranchId, null);
+    }
+
+    public IRunHistory history(ITeamcityIgnited ignited,
+                               @Nullable Integer baseBranchId,
+                               @Nullable Map<Integer, Integer> requireParameters) {
         Integer name = testName();
         if (name == null || baseBranchId == null)
             return null;
 
-        ISuiteRunHistory suiteRunHist = ctx.suiteHist(ignited, baseBranchId);
+        ISuiteRunHistory suiteRunHist = ctx.suiteHist(ignited, baseBranchId, requireParameters);
 
         if (suiteRunHist == null)
             return null;
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 a307f2a..3781a27 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
@@ -49,9 +49,9 @@ import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
 import org.apache.ignite.tcignited.SyncMode;
+import org.apache.ignite.tcignited.buildref.BranchEquivalence;
 import org.apache.ignite.tcignited.creds.ICredentialsProv;
 import org.apache.ignite.tcignited.history.IRunHistory;
-import org.apache.ignite.tcignited.history.RunHistSync;
 import org.apache.ignite.tcservice.ITeamcity;
 
 /**
@@ -165,7 +165,8 @@ public class PrChainsProcessor {
                 runningUpdates.addAndGet(cnt0);
 
             //fail rate reference is always default (master)
-            chainStatus.initFromContext(tcIgnited, ctx, baseBranchForTc, compactor, false, null, null, -1); // don't need for PR
+            chainStatus.initFromContext(tcIgnited, ctx, baseBranchForTc, compactor, false,
+                    null, null, -1, null); // don't need for PR
 
             initJiraAndGitInfo(chainStatus, jiraIntegration, gitHubConnIgnited);
         }
@@ -293,7 +294,7 @@ public class PrChainsProcessor {
     private List<ShortSuiteUi> findBlockerFailures(FullChainRunCtx fullChainRunCtx,
         ITeamcityIgnited tcIgnited,
         String baseBranch) {
-        String normalizedBaseBranch = RunHistSync.normalizeBranch(baseBranch);
+        String normalizedBaseBranch = BranchEquivalence.normalizeBranch(baseBranch);
         Integer baseBranchId = compactor.getStringIdIfPresent(normalizedBaseBranch);
 
         Predicate<MultBuildRunCtx> filter = suite ->
@@ -302,7 +303,7 @@ public class PrChainsProcessor {
         return fullChainRunCtx
             .filteredChildSuites(filter)
             .map((ctx) -> {
-                IRunHistory statInBaseBranch = ctx.history(tcIgnited, baseBranchId);
+                IRunHistory statInBaseBranch = ctx.history(tcIgnited, baseBranchId, null);
 
                 String suiteComment = ctx.getPossibleBlockerComment(compactor, statInBaseBranch, tcIgnited.config());
 
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 0cbab4e..d74daf0 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
@@ -158,7 +158,8 @@ public class TrackedBranchChainsProcessor implements IDetailedStatusForTrackedBr
                 if (cnt > 0)
                     runningUpdates.addAndGet(cnt);
 
-                chainStatus.initFromContext(tcIgnited, ctx, baseBranchTc, compactor, calcTrustedTests, tagSelected, displayMode, maxDurationSec);
+                chainStatus.initFromContext(tcIgnited, ctx, baseBranchTc, compactor, calcTrustedTests, tagSelected,
+                        displayMode, maxDurationSec, requireParamVal);
 
                 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 47b7d0b..49fe56f 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
@@ -39,7 +39,7 @@ import org.apache.ignite.tcservice.model.conf.BuildType;
 
 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;
+import static org.apache.ignite.tcignited.buildref.BranchEquivalence.normalizeBranch;
 
 /**
  * Detailed status of PR or tracked branch for chain.
@@ -165,7 +165,8 @@ public class DsChainUi {
         boolean calcTrustedTests,
         @Nullable String tagSelected,
         @Nullable DisplayMode displayMode,
-        int maxDurationSec) {
+        int maxDurationSec,
+        @Nullable Map<Integer, Integer> requireParamVal) {
         failedTests = 0;
         failedToFinish = 0;
         totalTests = 0;
@@ -188,8 +189,8 @@ public class DsChainUi {
             .filter(suite -> !suite.isComposite())
             .filter(suiteFilter)
             .peek(suite -> {
-                Integer totalTests = suite.totalTests();
-                this.totalTests += totalTests != null ? totalTests : 0;
+                int totalTests = suite.totalTests();
+                this.totalTests += totalTests;
 
                 if (calcTrustedTests)
                     trustedTests += suite.trustedTests(tcIgnited, baseBranchId);
@@ -202,10 +203,15 @@ public class DsChainUi {
                     || dModeToUse == DisplayMode.ShowAllSuites
                     || suite.hasTestToReport(tcIgnited, baseBranchId)
                     || suite.hasLongRunningTest(maxDurationSec)) {
-                    final DsSuiteUi suiteCurStatus = new DsSuiteUi();
-
-                    suiteCurStatus.initFromContext(tcIgnited, suite, baseBranchTc, compactor, true, calcTrustedTests,
-                        maxDurationSec);
+                    DsSuiteUi suiteCurStatus = new DsSuiteUi()
+                        .initFromContext(tcIgnited,
+                            suite,
+                            baseBranchTc,
+                            compactor,
+                            true,
+                            calcTrustedTests,
+                            maxDurationSec,
+                            requireParamVal);
 
                     failedTests += suiteCurStatus.failedTests != null ? suiteCurStatus.failedTests : 0;
 
@@ -241,7 +247,7 @@ public class DsChainUi {
                 MultBuildRunCtx suite = pairCtxAndOccur.get1();
                 TestCompactedMult longRunningOccur = pairCtxAndOccur.get2();
 
-                DsTestFailureUi failure = createOrrucForLongRun(tcIgnited, compactor, suite, longRunningOccur, baseBranchTc);
+                DsTestFailureUi failure = createOrrucForLongRun(tcIgnited, compactor, suite, longRunningOccur, baseBranchTc, requireParamVal);
 
                 failure.testName = "[" + suite.suiteName() + "] " + failure.testName; //may be separate field
 
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 64d4a66..cc4f617 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
@@ -41,7 +41,7 @@ import org.apache.ignite.tcignited.buildlog.ITestLogCheckResult;
 import org.apache.ignite.tcignited.history.IRunHistory;
 
 import static org.apache.ignite.tcbot.common.util.TimeUtil.millisToDurationPrintable;
-import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
+import static org.apache.ignite.tcignited.buildref.BranchEquivalence.normalizeBranch;
 
 
 /**
@@ -51,7 +51,6 @@ import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
  */
 @SuppressWarnings({"WeakerAccess", "PublicField"})
 public class DsSuiteUi extends ShortSuiteUi {
-
     /** Has critical problem: Timeout, JMV Crash, Compilation Error or Failure on Metric */
     @Nullable public Boolean hasCriticalProblem;
 
@@ -140,6 +139,7 @@ public class DsSuiteUi extends ShortSuiteUi {
      * @param includeTests Include tests - usually {@code true}, but it may be disabled for speeding up VISA collection.
      * @param calcTrustedTests
      * @param maxDurationSec 0 or negative means don't indclude. has no effect if tests not included
+     * @param requireParamVal filtering for runs history based on parameter value selected.
      */
     public DsSuiteUi initFromContext(ITeamcityIgnited tcIgnited,
         @Nonnull final MultBuildRunCtx suite,
@@ -147,16 +147,17 @@ public class DsSuiteUi extends ShortSuiteUi {
         @Nonnull IStringCompactor compactor,
         boolean includeTests,
         boolean calcTrustedTests,
-        int maxDurationSec) {
+        int maxDurationSec,
+        @Nullable Map<Integer, Integer> requireParamVal) {
         String failRateNormalizedBranch = normalizeBranch(baseBranch);
         Integer baseBranchId = compactor.getStringIdIfPresent(failRateNormalizedBranch);
-        IRunHistory baseBranchHist = suite.history(tcIgnited, baseBranchId);
+        IRunHistory baseBranchHist = suite.history(tcIgnited, baseBranchId, requireParamVal);
         initFrom(suite, tcIgnited, compactor, baseBranchHist);
 
         String curBranchNormalized = normalizeBranch(suite.branchName());
         Integer curBranchId = compactor.getStringIdIfPresent(curBranchNormalized);
 
-        initSuiteStat(tcIgnited, baseBranchId, curBranchId, suite, baseBranchHist);
+        initSuiteStat(tcIgnited, baseBranchId, curBranchId, suite, baseBranchHist, requireParamVal);
 
         Set<String> collect = suite.lastChangeUsers().collect(Collectors.toSet());
 
@@ -174,7 +175,6 @@ public class DsSuiteUi extends ShortSuiteUi {
         webToHist = buildWebLinkToHist(tcIgnited, suite);
         webToHistBaseBranch = buildWebLinkToHist(tcIgnited, suite, baseBranch);
 
-        Integer buildTypeIdId = suite.buildTypeIdId();
         if (includeTests) {
             List<TestCompactedMult> tests = suite.getFilteredTests(test ->
                 test.hasLongRunningTest(maxDurationSec)
@@ -188,19 +188,21 @@ public class DsSuiteUi extends ShortSuiteUi {
 
             tests.sort(Comparator.comparing(function).reversed());
 
-            tests.forEach(occurrence -> {
-                final DsTestFailureUi failure = new DsTestFailureUi();
-
-                failure.initFromOccurrence(occurrence, tcIgnited, suite.projectId(),
-                    suite.branchName(), baseBranch, baseBranchId);
-                failure.initStat(occurrence, buildTypeIdId, tcIgnited, baseBranchId, curBranchId);
-
-                testFailures.add(failure);
-            });
+            tests.stream()
+                .map(occurrence -> new DsTestFailureUi()
+                    .initFromOccurrence(occurrence,
+                        tcIgnited,
+                        suite.projectId(),
+                        suite.branchName(),
+                        baseBranch,
+                        baseBranchId,
+                        curBranchId,
+                        requireParamVal))
+                .forEach(testFailureUi -> testFailures.add(testFailureUi));
 
             suite.getTopLongRunning().forEach(occurrence -> {
                 if (occurrence.getAvgDurationMs() > TimeUnit.SECONDS.toMillis(15)) {
-                    final DsTestFailureUi failure = createOrrucForLongRun(tcIgnited, compactor, suite, occurrence, baseBranch);
+                    final DsTestFailureUi failure = createOrrucForLongRun(tcIgnited, compactor, suite, occurrence, baseBranch, requireParamVal);
 
                     topLongRunning.add(failure);
                 }
@@ -255,11 +257,12 @@ public class DsSuiteUi extends ShortSuiteUi {
         return this;
     }
 
-
     private IRunHistory initSuiteStat(ITeamcityIgnited tcIgnited,
         Integer failRateNormalizedBranch,
         Integer curBranchNormalized,
-        MultBuildRunCtx suite, IRunHistory referenceStat) {
+        MultBuildRunCtx suite,
+        IRunHistory referenceStat,
+        @Nullable Map<Integer, Integer> requireParamVal) {
         IRunHistory statInBaseBranch = referenceStat;
 
         if (statInBaseBranch != null) {
@@ -276,7 +279,7 @@ public class DsSuiteUi extends ShortSuiteUi {
 
         IRunHistory latestRunsSrc = null;
         if (!Objects.equals(failRateNormalizedBranch, curBranchNormalized)) {
-            IRunHistory statForStripe = suite.history(tcIgnited, curBranchNormalized);
+            IRunHistory statForStripe = suite.history(tcIgnited, curBranchNormalized, requireParamVal);
 
             latestRunsSrc = statForStripe;
             latestRuns = statForStripe != null ? statForStripe.getLatestRunResults() : null;
@@ -303,21 +306,18 @@ public class DsSuiteUi extends ShortSuiteUi {
         return failure;
     }
 
-    @Nonnull public static DsTestFailureUi createOrrucForLongRun(ITeamcityIgnited tcIgnited,
-        IStringCompactor compactor, @Nonnull MultBuildRunCtx suite,
-        final TestCompactedMult occurrence,
-        @Nullable final String failRateBranch) {
-        final DsTestFailureUi failure = new DsTestFailureUi();
-
+    @Nonnull
+    public static DsTestFailureUi createOrrucForLongRun(ITeamcityIgnited tcIgnited,
+        IStringCompactor compactor,
+        @Nonnull MultBuildRunCtx suite,
+        TestCompactedMult occurrence,
+        @Nullable String failRateBranch,
+        @Nullable Map<Integer, Integer> requireParamVal) {
         Integer baseBranchId = compactor.getStringIdIfPresent(normalizeBranch(failRateBranch));
-        Integer buildTypeIdId = suite.buildTypeIdId();
-        failure.initFromOccurrence(occurrence, tcIgnited, suite.projectId(), suite.branchName(),
-            failRateBranch, baseBranchId);
+        Integer curBranchId = compactor.getStringIdIfPresent(normalizeBranch(suite.branchName()));
 
-        failure.initStat(occurrence, buildTypeIdId, tcIgnited,  baseBranchId,
-            compactor.getStringIdIfPresent(normalizeBranch(suite.branchName())));
-
-        return failure;
+        return new DsTestFailureUi().initFromOccurrence(occurrence, tcIgnited, suite.projectId(), suite.branchName(),
+                failRateBranch, baseBranchId, curBranchId, requireParamVal);
     }
 
     public void findFailureAndAddWarning(String testName, ITestLogCheckResult logCheckRes) {
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 a4e0458..a5db1e0 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
@@ -19,6 +19,7 @@ package org.apache.ignite.tcbot.engine.ui;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -33,7 +34,7 @@ import org.apache.ignite.tcignited.buildlog.LogMsgToWarn;
 import org.apache.ignite.tcignited.history.IRunHistory;
 
 import static org.apache.ignite.tcbot.common.util.TimeUtil.millisToDurationPrintable;
-import static org.apache.ignite.tcignited.history.RunHistSync.normalizeBranch;
+import static org.apache.ignite.tcignited.buildref.BranchEquivalence.normalizeBranch;
 
 
 /**
@@ -85,13 +86,17 @@ public class DsTestFailureUi extends ShortTestFailureUi {
      * @param branchName current branch name.
      * @param baseBranchName base branch name (e.g. master), without normalization.
      * @param baseBranchId Normalized base branch ID (from compactor).
+     * @param curBranchId Current branch id to inin statistics.
+     * @param requireParameters Filter suite and test history by parameter value.
      */
-    public void initFromOccurrence(@Nonnull final TestCompactedMult failure,
+    public DsTestFailureUi initFromOccurrence(@Nonnull final TestCompactedMult failure,
         @Nonnull final ITeamcityIgnited tcIgn,
         @Nullable final String projectId,
         @Nullable final String branchName,
         @Nullable final String baseBranchName,
-        Integer baseBranchId) {
+        Integer baseBranchId,
+        @Nullable Integer curBranchId,
+        @Nullable Map<Integer, Integer> requireParameters) {
         success = !failure.isFailedButNotMuted();
 
         investigated = failure.isInvestigated();
@@ -121,12 +126,17 @@ public class DsTestFailureUi extends ShortTestFailureUi {
             .map(ITest::getTestId)
             .filter(Objects::nonNull)
             .forEach(testNameId -> {
-                if (webUrl == null && testNameId != null)
+                if (webUrl == null)
                     webUrl = buildWebLink(tcIgn, testNameId, projectId, branchName);
 
-                if (webUrlBaseBranch == null && testNameId != null)
+                if (webUrlBaseBranch == null)
                     webUrlBaseBranch = buildWebLink(tcIgn, testNameId, projectId, baseBranchName);
             });
+
+
+        initStat(failure, tcIgn, baseBranchId, curBranchId, requireParameters);
+
+        return this;
     }
 
 
@@ -174,21 +184,23 @@ public class DsTestFailureUi extends ShortTestFailureUi {
 
     /**
      * @param occurrence
-     * @param buildTypeIdId
      * @param tcIgnited TC service as Run stat supplier.
      * @param baseBranchId Base branch: Fail rate and flakyness detection normalized branch.
      * @param curBranchNormalized Cur branch normalized.
+     * @param requireParameters
      */
-    public void initStat(TestCompactedMult occurrence, Integer buildTypeIdId, ITeamcityIgnited tcIgnited,
+    public void initStat(TestCompactedMult occurrence,
+        ITeamcityIgnited tcIgnited,
         @Nullable Integer baseBranchId,
-        @Nullable Integer curBranchNormalized) {
-        final IRunHistory stat = occurrence.history(tcIgnited, baseBranchId);
+        @Nullable Integer curBranchNormalized,
+        @Nullable Map<Integer, Integer> requireParameters) {
+        final IRunHistory stat = occurrence.history(tcIgnited, baseBranchId, requireParameters);
         histBaseBranch.init(stat);
 
         IRunHistory statForProblemsDetection;
 
         if (!Objects.equals(curBranchNormalized, baseBranchId)) {
-            statForProblemsDetection = occurrence.history(tcIgnited, curBranchNormalized);
+            statForProblemsDetection = occurrence.history(tcIgnited, curBranchNormalized, requireParameters);
 
             if (statForProblemsDetection != null) {
                 histCurBranch = new DsTestHistoryUi();
@@ -205,6 +217,10 @@ public class DsTestFailureUi extends ShortTestFailureUi {
 
             if (statForProblemsDetection.detectTemplate(EventTemplates.newContributedTestFailure) != null)
                 problemRef = new DsProblemRef("Recently contributed test failure");
+
+            if (stat.isFlaky()
+                    && statForProblemsDetection.detectTemplate(EventTemplates.newFailureForFlakyTest) != null)
+                problemRef = new DsProblemRef("New failure of flaky test");
         }
     }
 
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildtype/ParametersCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildtype/ParametersCompacted.java
index 2308ddb..b889c48 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildtype/ParametersCompacted.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/buildtype/ParametersCompacted.java
@@ -19,17 +19,18 @@ package org.apache.ignite.ci.teamcity.ignited.buildtype;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
+import org.apache.ignite.internal.util.GridIntList;
+import org.apache.ignite.tcbot.persistence.IStringCompactor;
+import org.apache.ignite.tcbot.persistence.Persisted;
+import org.apache.ignite.tcservice.model.conf.bt.Parameters;
+import org.apache.ignite.tcservice.model.conf.bt.Property;
+
+import javax.annotation.Nullable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.function.BiConsumer;
-import javax.annotation.Nullable;
-
-import org.apache.ignite.tcbot.persistence.Persisted;
-import org.apache.ignite.tcservice.model.conf.bt.Parameters;
-import org.apache.ignite.tcservice.model.conf.bt.Property;
-import org.apache.ignite.tcbot.persistence.IStringCompactor;
-import org.apache.ignite.internal.util.GridIntList;
 
 /**
  * Properties (Build/Build Type parameters) compacted value for storing in TC Bot DB
@@ -74,6 +75,16 @@ public class ParametersCompacted {
         }
     }
 
+    public ParametersCompacted(Map<Integer, Integer> parms) {
+        keys = new GridIntList(parms.size());
+        values = new GridIntList(parms.size());
+
+        parms.forEach((strId, val) -> {
+            keys.add(strId);
+            values.add(val);
+        });
+    }
+
     public Parameters toParameters(IStringCompactor compactor) {
         List<Property> props = null;
 
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
index 51eb4aa..8b52eb1 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
@@ -19,7 +19,15 @@ package org.apache.ignite.ci.teamcity.ignited.fatbuild;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.BiPredicate;
 import java.util.stream.Collectors;
@@ -667,7 +675,9 @@ public class FatBuildCompacted extends BuildRefCompacted implements IVersionedEn
                 if (paramsFilter.test(k, v))
                     importantParms.put(k, v);
             });
-            //todo save parameters
+
+            if (!importantParms.isEmpty())
+                invocation.withParameters(importantParms);
         }
 
         return invocation;
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/Invocation.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/Invocation.java
index 68e80cb..e46aba4 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/Invocation.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/Invocation.java
@@ -20,10 +20,13 @@ package org.apache.ignite.ci.teamcity.ignited.runhist;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
+import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
 import org.apache.ignite.tcbot.persistence.Persisted;
 import org.apache.ignite.tcignited.history.ChangesState;
 
 import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 
@@ -51,7 +54,7 @@ public class Invocation {
     private byte changePresent;
 
     /** Additional (important) build Parameters, which can be used for filtering. */
-    @Nullable private Map<Integer, Integer> parms;
+    @Nullable private ParametersCompacted parameters;
 
     /**
      * Creates invocation.
@@ -128,8 +131,29 @@ public class Invocation {
         if (parms == null || parms.isEmpty())
             return this;
 
-        this.parms = parms;
+        this.parameters = new ParametersCompacted(parms);
 
         return this;
     }
+
+
+    public static boolean hasAnyParameterValue(ParametersCompacted parameters, @Nonnull Map<Integer, Integer> requireParamVal) {
+        if (parameters == null)
+            return false;
+
+        Set<Map.Entry<Integer, Integer>> entries = requireParamVal.entrySet();
+        for (Map.Entry<Integer, Integer> next : entries) {
+            Integer key = next.getKey();
+
+            int valId = parameters.findPropertyStringId(key);
+            if (java.util.Objects.equals(next.getValue(), valId))
+                return true;
+        }
+
+        return false;
+    }
+
+    public boolean containsParameterValue(Map<Integer, Integer> requireParameters) {
+        return hasAnyParameterValue(this.parameters, requireParameters);
+    }
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
index 090c39c..f973c07 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
@@ -114,4 +114,8 @@ public class InvocationData {
     public void sort() {
         invocationList.sort(Comparator.comparing(Invocation::buildId));
     }
+
+    public Set<Integer> buildIds() {
+        return invocationList.stream().map(Invocation::buildId).collect(Collectors.toSet());
+    }
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
index 3b86767..722ff7a 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
@@ -18,20 +18,23 @@
 package org.apache.ignite.ci.teamcity.ignited.runhist;
 
 import com.google.common.base.MoreObjects;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
 import org.apache.ignite.tcbot.common.TcBotConst;
 import org.apache.ignite.tcignited.history.ChangesState;
 import org.apache.ignite.tcignited.history.IEventTemplate;
 import org.apache.ignite.tcignited.history.IRunHistory;
 import org.apache.ignite.tcignited.history.RunStatus;
 
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 /**
  *
  */
-public class RunHistCompacted implements  IRunHistory {
+public class RunHistCompacted implements IRunHistory {
     /** Data. */
     private InvocationData data = new InvocationData();
 
@@ -98,6 +101,11 @@ public class RunHistCompacted implements  IRunHistory {
         return data.criticalFailuresCount();
     }
 
+    @Override
+    public Set<Integer> buildIds() {
+        return data.buildIds();
+    }
+
     private static int[] concatArr(int[] arr1, int[] arr2) {
         int[] arr1and2 = new int[arr1.length + arr2.length];
         System.arraycopy(arr1, 0, arr1and2, 0, arr1.length);
@@ -197,4 +205,24 @@ public class RunHistCompacted implements  IRunHistory {
     public void sort() {
         data.sort();
     }
+
+    public RunHistCompacted filterSuiteInvByParms(Map<Integer, Integer> requireParameters) {
+        RunHistCompacted copy = new RunHistCompacted();
+
+        data.invocations()
+                .filter(invocation -> invocation.containsParameterValue(requireParameters))
+                .forEach(invocation -> copy.data.add(invocation));
+
+        return copy;
+    }
+
+    public RunHistCompacted filterByBuilds(Set<Integer> builds) {
+        RunHistCompacted copy = new RunHistCompacted();
+
+        data.invocations()
+                .filter(invocation -> builds.contains(invocation.buildId()))
+                .forEach(invocation -> copy.data.add(invocation));
+
+        return copy;
+    }
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java
index c6b10c4..e924558 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java
@@ -427,7 +427,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
         if (buildTypeId < 0 || normalizedBaseBranch < 0)
             return null;
 
-        return histCollector.getSuiteRunHist(srvIdMaskHigh, buildTypeId, normalizedBaseBranch);
+        return histCollector.getSuiteRunHist(srvCode, buildTypeId, normalizedBaseBranch);
     }
 
     /** {@inheritDoc} */
@@ -439,7 +439,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
         if (testName < 0 || buildTypeId < 0 || normalizedBaseBranch < 0)
             return null;
 
-        return histCollector.getTestRunHist(srvIdMaskHigh, testName, buildTypeId, normalizedBaseBranch);
+        return histCollector.getTestRunHist(srvCode, testName, buildTypeId, normalizedBaseBranch);
     }
 
     /** {@inheritDoc} */
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedModule.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedModule.java
index cc4762b..0f39f7a 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedModule.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedModule.java
@@ -37,7 +37,6 @@ import org.apache.ignite.tcignited.mute.MuteDao;
 import org.apache.ignite.tcignited.mute.MuteSync;
 import org.apache.ignite.tcignited.buildlog.BuildLogProcessorModule;
 import org.apache.ignite.tcignited.history.BuildStartTimeStorage;
-import org.apache.ignite.tcignited.history.RunHistSync;
 import org.apache.ignite.tcservice.TcRealConnectionModule;
 import org.apache.ignite.tcservice.http.ITeamcityHttpConnection;
 
@@ -65,7 +64,6 @@ public class TeamcityIgnitedModule extends AbstractModule {
         bind(BuildTypeDao.class).in(new SingletonScope());
         bind(BuildTypeSync.class).in(new SingletonScope());
         bind(BuildStartTimeStorage.class).in(new SingletonScope());
-        bind(RunHistSync.class).in(new SingletonScope());
         bind(MuteDao.class).in(new SingletonScope());
         bind(MuteSync.class).in(new SingletonScope());
         bind(BuildLogCheckResultDao.class).in(new SingletonScope());
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
index 1702013..489ef59 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ProactiveFatBuildSync.java
@@ -50,7 +50,6 @@ import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.tcignited.buildref.BuildRefDao;
-import org.apache.ignite.tcignited.history.RunHistSync;
 import org.apache.ignite.tcservice.ITeamcityConn;
 import org.apache.ignite.tcservice.model.changes.ChangesList;
 import org.apache.ignite.tcservice.model.result.Build;
@@ -81,9 +80,6 @@ public class ProactiveFatBuildSync {
     /** Change sync. */
     @Inject private ChangeSync changeSync;
 
-    /** Run history sync. */
-    @Inject private RunHistSync runHistSync;
-
     @GuardedBy("this")
     private Map<String, SyncTask> buildToLoad = new HashMap<>();
 
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
index 9d5f0e8..7d1b24f 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
@@ -19,6 +19,7 @@ package org.apache.ignite.tcignited.build;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.ignite.Ignite;
 import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
@@ -42,6 +43,8 @@ public class SuiteHistory implements ISuiteRunHistory {
         finalizeInvocations();
     }
 
+    private SuiteHistory() {}
+
     private void finalizeInvocations() {
         //todo add missing status to tests
         //  testsHistory.values().registerMissing(suiteHist.buildIds());
@@ -59,6 +62,19 @@ public class SuiteHistory implements ISuiteRunHistory {
         return testsHistory.get(testName);
     }
 
+    @Override
+    public ISuiteRunHistory filter(Map<Integer, Integer> requireParameters) {
+        RunHistCompacted suitesFiltered = this.suiteHist.filterSuiteInvByParms(requireParameters);
+        Set<Integer> builds = suitesFiltered.buildIds();
+
+        SuiteHistory res = new SuiteHistory();
+
+        res.suiteHist = suitesFiltered;
+        this.testsHistory.forEach((tName,invList)-> res.testsHistory.put(tName, invList.filterByBuilds(builds)));
+
+        return res;
+    }
+
     private RunHistCompacted getOrAddTestsHistory(Integer tName) {
         return testsHistory.computeIfAbsent(tName, k_ -> new RunHistCompacted());
     }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/TestCompactedV2.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/TestCompactedV2.java
index 39b2d04..8241b3f 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/TestCompactedV2.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/TestCompactedV2.java
@@ -20,11 +20,8 @@ package org.apache.ignite.tcignited.build;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 import java.util.Objects;
-import java.util.TreeMap;
-import java.util.function.BiPredicate;
 import javax.annotation.Nullable;
 import org.apache.ignite.ci.tcbot.common.StringFieldCompacted;
-import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 import org.apache.ignite.ci.teamcity.ignited.runhist.InvocationData;
@@ -380,40 +377,25 @@ public class TestCompactedV2 implements ITest {
 
     /**
      * @param build
-     * @param paramsFilter parameters filter to find out parameters to be saved in RunHistory (for future filtering).
      * @param successStatusStrId
      * @return
      */
     public static Invocation toInvocation(
-        ITest test,
-        FatBuildCompacted build,
-        BiPredicate<Integer, Integer> paramsFilter, int successStatusStrId) {
+            ITest test,
+            FatBuildCompacted build,
+            int successStatusStrId) {
         final boolean failedTest = successStatusStrId != test.status();
 
+        //todo implement IGNORED, MUTED_FAILURE, MUTED_SUCCESS
         final int failCode = failedTest
             ? (test.isIgnoredTest() || test.isMutedTest())
             ? InvocationData.MUTED
             : InvocationData.FAILURE
             : InvocationData.OK;
 
-        Invocation invocation = new Invocation(build.getId())
+        return new Invocation(build.getId())
             .withStatus(failCode)
             .withChanges(build.changes());
-
-        java.util.Map<Integer, Integer> importantParms = new TreeMap<>();
-
-        ParametersCompacted parameters = build.parameters();
-        if (parameters == null)
-            return invocation;
-
-        parameters.forEach((k, v) -> {
-            if (paramsFilter.test(k, v))
-                importantParms.put(k, v);
-        });
-
-        //todo implement parameter filter and save to parms compacted
-        // return invocation.withParameters(importantParms);
-        return invocation;
     }
 
     /**
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BranchEquivalence.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BranchEquivalence.java
index ab5f0b9..37eb8ca 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BranchEquivalence.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BranchEquivalence.java
@@ -19,6 +19,7 @@ package org.apache.ignite.tcignited.buildref;
 import com.google.common.collect.Lists;
 import java.util.Collections;
 import java.util.List;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.apache.ignite.tcservice.ITeamcity;
 
@@ -28,6 +29,22 @@ public class BranchEquivalence {
         = Collections.unmodifiableList(
         Lists.newArrayList(ITeamcity.DEFAULT, ITeamcity.REFS_HEADS_MASTER, ITeamcity.MASTER));
 
+    /**
+     * @param branchName Branch name.
+     */
+    @Nonnull
+    public static String normalizeBranch(@Nullable String branchName) {
+        String branch = branchName == null ? ITeamcity.DEFAULT : branchName;
+
+        if (ITeamcity.REFS_HEADS_MASTER.equals(branch))
+            return ITeamcity.DEFAULT;
+
+        if (ITeamcity.MASTER.equals(branch))
+            return ITeamcity.DEFAULT;
+
+        return branch;
+    }
+
 
     public List<String> branchForQuery(@Nullable String branchName) {
         if (ITeamcity.DEFAULT.equals(branchName))
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/HistoryCollector.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/HistoryCollector.java
index bfb7bea..0bdea46 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/HistoryCollector.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/HistoryCollector.java
@@ -26,14 +26,12 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.BiPredicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import javax.annotation.Nonnull;
 import javax.cache.Cache;
 import javax.inject.Inject;
 import javax.inject.Provider;
@@ -46,6 +44,8 @@ import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistKey;
 import org.apache.ignite.tcbot.common.TcBotConst;
+import org.apache.ignite.tcbot.common.conf.IBuildParameterSpec;
+import org.apache.ignite.tcbot.common.conf.IDataSourcesConfigSupplier;
 import org.apache.ignite.tcbot.common.conf.TcBotSystemProperties;
 import org.apache.ignite.tcbot.common.exeption.ExceptionUtil;
 import org.apache.ignite.tcbot.common.exeption.ServicesStartingException;
@@ -91,6 +91,8 @@ public class HistoryCollector {
     /** Run history DAO. */
     @Inject private BuildStartTimeStorage buildStartTimeStorage;
 
+    @Inject private IDataSourcesConfigSupplier cfg;
+
     /**
      * Non persistence cache for all suite RunHistory for particular branch. RunHistKey(ServerId||BranchId||suiteId)->
      * Build reference
@@ -103,28 +105,29 @@ public class HistoryCollector {
         .build();
 
     /**
-     * @param srvIdMaskHigh Server id mask to be placed at high bits in the key.
+     * @param srvCode Server id mask to be placed at high bits in the key.
      * @param testName Test name.
      * @param buildTypeId Suite (Build type) id.
      * @param normalizedBaseBranch Branch name.
      */
-    public IRunHistory getTestRunHist(int srvIdMaskHigh, int testName, int buildTypeId,
-        int normalizedBaseBranch) {
+    public IRunHistory getTestRunHist(String srvCode, int testName, int buildTypeId,
+                                      int normalizedBaseBranch) {
 
-        SuiteHistory hist = getSuiteHist(srvIdMaskHigh, buildTypeId, normalizedBaseBranch);
+        SuiteHistory hist = getSuiteHist(srvCode, buildTypeId, normalizedBaseBranch);
 
         return hist.getTestRunHist(testName);
     }
 
     @SuppressWarnings("WeakerAccess")
     @AutoProfiling
-    protected SuiteHistory getSuiteHist(int srvIdMaskHigh, int buildTypeId, int normalizedBaseBranch) {
-        RunHistKey runHistKey = new RunHistKey(srvIdMaskHigh, buildTypeId, normalizedBaseBranch);
+    protected SuiteHistory getSuiteHist(String srvCode, int buildTypeId, int normalizedBaseBranch) {
+        int srvId = ITeamcityIgnited.serverIdToInt(srvCode);
+        RunHistKey runHistKey = new RunHistKey(srvId, buildTypeId, normalizedBaseBranch);
 
         SuiteHistory hist;
         try {
             hist = runHistInMemCache.get(runHistKey,
-                () -> loadSuiteHistory(srvIdMaskHigh, buildTypeId, normalizedBaseBranch));
+                () -> loadSuiteHistory(srvCode, buildTypeId, normalizedBaseBranch));
         }
         catch (ExecutionException e) {
             throw ExceptionUtil.propagateException(e);
@@ -217,9 +220,10 @@ public class HistoryCollector {
     }
 
     @AutoProfiling
-    protected SuiteHistory loadSuiteHistory(int srvId,
-        int buildTypeId,
-        int normalizedBaseBranch) {
+    protected SuiteHistory loadSuiteHistory(String srvCode,
+                                            int buildTypeId,
+                                            int normalizedBaseBranch) {
+        int srvId = ITeamcityIgnited.serverIdToInt(srvCode);
         Map<Integer, SuiteInvocation> suiteRunHist = histDao.getSuiteRunHist(srvId, buildTypeId, normalizedBaseBranch);
 
         logger.info("***** Found history for suite "
@@ -233,7 +237,7 @@ public class HistoryCollector {
         missedBuildsIds.removeAll(suiteRunHist.keySet());
 
         if (!missedBuildsIds.isEmpty()) {
-            Map<Integer, SuiteInvocation> addl = addSuiteInvocationsToHistory(srvId, missedBuildsIds, normalizedBaseBranch);
+            Map<Integer, SuiteInvocation> addl = addSuiteInvocationsToHistory(srvCode, missedBuildsIds, normalizedBaseBranch);
 
             suiteRunHist.putAll(addl);
         }
@@ -260,30 +264,46 @@ public class HistoryCollector {
         runHistInMemCache.invalidate(inv);
     }
 
+    @Nonnull
+    private Set<Integer> getFilteringParameters(String srvCode) {
+        Set<String> importantParameters = new HashSet<>();
+
+        cfg.getTeamcityConfig(srvCode)
+                .filteringParameters()
+                .stream()
+                .map(IBuildParameterSpec::name)
+                .forEach(importantParameters::add);
+
+        return importantParameters.stream().map(k -> compactor.getStringId(k)).collect(Collectors.toSet());
+    }
 
     @AutoProfiling
-    protected Map<Integer, SuiteInvocation> addSuiteInvocationsToHistory(int srvId,
-        HashSet<Integer> missedBuildsIds, int normalizedBaseBranch) {
+    protected Map<Integer, SuiteInvocation> addSuiteInvocationsToHistory(String srvCode,
+                                                                         HashSet<Integer> missedBuildsIds,
+                                                                         int normalizedBaseBranch) {
+
+        Set<Integer> filteringParameters = getFilteringParameters(srvCode);
+        BiPredicate<Integer, Integer> paramsFilter = (k, v) -> filteringParameters.contains(k);
+
         Map<Integer, SuiteInvocation> suiteRunHist = new HashMap<>();
         int successStatusStrId = compactor.getStringId(TestOccurrence.STATUS_SUCCESS);
 
         logger.info(Thread.currentThread().getName() + "addSuiteInvocationsToHistory: getAll: " + missedBuildsIds.size());
 
+        int srvId = ITeamcityIgnited.serverIdToInt(srvCode);
         Iterables.partition(missedBuildsIds, 32 * 10).forEach(
             chunk -> {
                 fatBuildDao.getAllFatBuilds(srvId, chunk).forEach((buildCacheKey, fatBuildCompacted) -> {
                     if (!applicableForHistory(fatBuildCompacted))
                         return;
 
-                    BiPredicate<Integer, Integer> paramsFilter = (k, v) -> false;
-
                     SuiteInvocation sinv = new SuiteInvocation(srvId, normalizedBaseBranch, fatBuildCompacted, compactor, paramsFilter);
 
                     Stream<ITest> tests = fatBuildCompacted.getAllTests();
                     tests.forEach(
                         testCompacted -> {
                             Invocation invocation = TestCompactedV2.toInvocation(testCompacted,
-                                fatBuildCompacted, paramsFilter, successStatusStrId);
+                                fatBuildCompacted, successStatusStrId);
 
                             sinv.addTest(testCompacted.testName(), invocation);
                         }
@@ -305,12 +325,12 @@ public class HistoryCollector {
     }
 
     /**
-     * @param srvId Server id.
+     * @param srvCode Server code.
      * @param buildTypeId Build type id.
      * @param normalizedBaseBranch Normalized base branch.
      */
-    public ISuiteRunHistory getSuiteRunHist(int srvId, int buildTypeId,  int  normalizedBaseBranch) {
-        return getSuiteHist(srvId, buildTypeId, normalizedBaseBranch);
+    public ISuiteRunHistory getSuiteRunHist(String srvCode, int buildTypeId,  int  normalizedBaseBranch) {
+        return getSuiteHist(srvCode, buildTypeId, normalizedBaseBranch);
     }
 
 
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistory.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistory.java
index cfd3ce4..7b2faac 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistory.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistory.java
@@ -18,6 +18,7 @@ package org.apache.ignite.tcignited.history;
 
 import javax.annotation.Nullable;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Test or Build run statistics.
@@ -58,4 +59,6 @@ public interface IRunHistory extends IRunStat, IRunHistSummary {
 
         return 1.0f * getFailuresCount() / runs;
     }
+
+    Set<Integer> buildIds();
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/ISuiteRunHistory.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/ISuiteRunHistory.java
index 38dff1c..a3223b9 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/ISuiteRunHistory.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/ISuiteRunHistory.java
@@ -16,7 +16,11 @@
  */
 package org.apache.ignite.tcignited.history;
 
+import java.util.Map;
+
 public interface ISuiteRunHistory {
     IRunHistory self();
     IRunHistory getTestRunHist(int testName);
+
+    ISuiteRunHistory filter(Map<Integer, Integer> requireParameters);
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistSync.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistSync.java
deleted file mode 100644
index 3b3ed9c..0000000
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistSync.java
+++ /dev/null
@@ -1,77 +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.tcignited.history;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-import javax.inject.Inject;
-
-import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
-import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistKey;
-import org.apache.ignite.tcbot.common.conf.IDataSourcesConfigSupplier;
-import org.apache.ignite.tcservice.ITeamcity;
-import org.apache.ignite.tcbot.common.conf.IBuildParameterSpec;
-import org.apache.ignite.tcbot.persistence.IStringCompactor;
-
-/**
- * Calculate required statistic for build if was not already calculated.
- */
-public class RunHistSync {
-    /** Compactor. */
-    @Inject private IStringCompactor compactor;
-
-    /** Config. */
-    @Inject private IDataSourcesConfigSupplier cfg;
-
-    /**
-     * @param branchName Branch name.
-     */
-    @Nonnull
-    public static String normalizeBranch(@Nullable String branchName) {
-        String branch = branchName == null ? ITeamcity.DEFAULT : branchName;
-
-        if (ITeamcity.REFS_HEADS_MASTER.equals(branch))
-            return ITeamcity.DEFAULT;
-
-        if (ITeamcity.MASTER.equals(branch))
-            return ITeamcity.DEFAULT;
-
-        return branch;
-    }
-
-    @Nonnull public Set<Integer> getFilteringParameters(String srvCode) {
-        Set<String> importantParameters = new HashSet<>();
-
-        cfg.getTeamcityConfig(srvCode)
-            .filteringParameters()
-            .stream()
-            .map(IBuildParameterSpec::name)
-            .forEach(importantParameters::add);
-
-        return importantParameters.stream().map(k -> compactor.getStringId(k)).collect(Collectors.toSet());
-    }
-}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocation.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocation.java
index 7342af7..e904bae 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocation.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocation.java
@@ -25,6 +25,7 @@ import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
+import org.apache.ignite.tcbot.persistence.IVersionedEntity;
 import org.apache.ignite.tcbot.persistence.Persisted;
 
 /**
@@ -32,7 +33,14 @@ import org.apache.ignite.tcbot.persistence.Persisted;
  * has time limitation of MAX_DAYS, may have TTL.
  */
 @Persisted
-public class SuiteInvocation {
+public class SuiteInvocation implements IVersionedEntity {
+    /** Latest version. */
+    private static final int LATEST_VERSION = 1;
+
+    /** Entity fields version. */
+    @SuppressWarnings("FieldCanBeLocal")
+    private short _ver = LATEST_VERSION;
+
     /** Server ID for queries */
     @QuerySqlField(orderedGroups = {@QuerySqlField.Group(name = "serverSuiteBranch", order = 0)})
     private int srvId;
@@ -50,7 +58,7 @@ public class SuiteInvocation {
 
     private Map<Integer, Invocation> tests = new HashMap<>();
 
-    Long buildStartTime;
+    private Long buildStartTime;
 
     public SuiteInvocation() {}
 
@@ -63,6 +71,17 @@ public class SuiteInvocation {
         this.buildTypeId = buildCompacted.buildTypeId();
     }
 
+
+    /** {@inheritDoc} */
+    @Override public int version() {
+        return _ver;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int latestVersion() {
+        return LATEST_VERSION;
+    }
+
     public void addTest(int testName, Invocation invocation) {
         tests.put(testName, invocation);
     }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocationHistoryDao.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocationHistoryDao.java
index dd93c5e..e62a4e5 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocationHistoryDao.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteInvocationHistoryDao.java
@@ -45,7 +45,7 @@ public class SuiteInvocationHistoryDao {
     private Provider<Ignite> igniteProvider;
 
     /** Suite history cache. */
-    private IgniteCache<Long, SuiteInvocation> suiteHistory;
+    private IgniteCache<Long, SuiteInvocation> suiteHist;
 
     public void init() {
         CacheConfiguration<Long , SuiteInvocation> ccfg = CacheConfigs.getCacheV2Config("teamcitySuiteHistory");
@@ -56,20 +56,27 @@ public class SuiteInvocationHistoryDao {
 
         Ignite ignite = igniteProvider.get();
 
-        suiteHistory = ignite.getOrCreateCache(ccfg);
+        suiteHist = ignite.getOrCreateCache(ccfg);
     }
 
     @AutoProfiling
     public Map<Integer, SuiteInvocation> getSuiteRunHist(int srvId, int buildTypeId, int normalizedBranchName) {
-        java.util.Map<Integer, SuiteInvocation> map = new HashMap<>();
-        try (QueryCursor<Cache.Entry<Long, SuiteInvocation>> qryCursor = suiteHistory.query(
+        Map<Integer, SuiteInvocation> map = new HashMap<>();
+
+        try (QueryCursor<Cache.Entry<Long, SuiteInvocation>> qryCursor = suiteHist.query(
             new SqlQuery<Long, SuiteInvocation>(SuiteInvocation.class, "srvId = ? and buildTypeId = ? and normalizedBranchName = ?")
                 .setArgs(srvId, buildTypeId, normalizedBranchName))) {
 
             for (Cache.Entry<Long, SuiteInvocation> next : qryCursor) {
                 Long key = next.getKey();
                 int buildId = BuildRefDao.cacheKeyToBuildId(key);
-                map.put(buildId, next.getValue());
+
+                SuiteInvocation invocation = next.getValue();
+
+                if(invocation.isOutdatedEntityVersion())
+                    continue;
+
+                map.put(buildId, invocation);
             }
         }
 
@@ -82,6 +89,6 @@ public class SuiteInvocationHistoryDao {
 
         addl.forEach((k, v) -> data.put(BuildRefDao.buildIdToCacheKey(srvId, k), v));
 
-        suiteHistory.putAll(data);
+        suiteHist.putAll(data);
     }
 }