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/09 11:45:28 UTC

[ignite-teamcity-bot] branch master updated (d5c757b -> 41bb328)

This is an automated email from the ASF dual-hosted git repository.

dpavlov pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git.


    from d5c757b  Board: Summary of non-fixed failures as new screen (phase 1) - Fixes #140.
     new a96c97d  Compacted history for tests: byte array introduced instead of objects with primitives, caching constants compactor IDs to reduce map get count, unit tests fixed - Fixes #147.
     new 41bb328  Version update

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/ignite/ci/web/model/Version.java    |   2 +-
 .../ci/tcbot/chain/BuildChainProcessorTest.java    |   9 +
 .../ignite/ci/tcbot/issue/IssueDetectorTest.java   |  48 +++--
 .../ci/teamcity/ignited/TeamcityIgnitedMock.java   |   2 +-
 .../IgnitedTcInMemoryIntegrationTest.java          |  83 ++++++++
 .../ignite/tcbot/engine/chain/MultBuildRunCtx.java |   8 +-
 .../tcbot/engine/chain/TestCompactedMult.java      |  26 +--
 .../ci/teamcity/ignited/BuildRefCompacted.java     |  83 +++++++-
 .../ignited/fatbuild/FatBuildCompacted.java        |   2 +-
 .../ci/teamcity/ignited/runhist/Invocation.java    |  24 ++-
 .../ignite/tcignited/build/SuiteHistory.java       |  98 ---------
 .../ignite/tcignited/build/TestCompactedV2.java    |  14 +-
 .../ignite/tcignited/buildref/BuildRefDao.java     |   1 -
 .../history/AbstractRunHist.java}                  | 178 +++++-----------
 .../ignite/tcignited/history/HistoryCollector.java |  10 +-
 .../ignite/tcignited/history/IRunHistSummary.java  |  32 ---
 .../ignite/tcignited/history/IRunHistory.java      |  30 ++-
 .../apache/ignite/tcignited/history/IRunStat.java  |  47 -----
 .../ignite/tcignited/history/ISuiteRunHistory.java |   3 +-
 .../history}/InvocationData.java                   |  82 +++-----
 .../ignite/tcignited/history/RunHistCompacted.java | 122 +++++++++++
 .../ignite/tcignited/history/SuiteHistory.java     | 232 +++++++++++++++++++++
 22 files changed, 707 insertions(+), 429 deletions(-)
 delete mode 100644 tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
 rename tcbot-teamcity-ignited/src/main/java/org/apache/ignite/{ci/teamcity/ignited/runhist/RunHistCompacted.java => tcignited/history/AbstractRunHist.java} (54%)
 delete mode 100644 tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistSummary.java
 delete mode 100644 tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunStat.java
 rename tcbot-teamcity-ignited/src/main/java/org/apache/ignite/{ci/teamcity/ignited/runhist => tcignited/history}/InvocationData.java (65%)
 create mode 100644 tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistCompacted.java
 create mode 100644 tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteHistory.java


[ignite-teamcity-bot] 01/02: Compacted history for tests: byte array introduced instead of objects with primitives, caching constants compactor IDs to reduce map get count, unit tests fixed - Fixes #147.

Posted by dp...@apache.org.
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

commit a96c97db4c04f6121061ba43e2d79298436f3957
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Fri Aug 9 14:44:47 2019 +0300

    Compacted history for tests: byte array introduced instead of objects with primitives, caching constants compactor IDs to reduce map get count, unit tests fixed - Fixes #147.
    
    Signed-off-by: Dmitriy Pavlov <dp...@apache.org>
---
 .../ci/tcbot/chain/BuildChainProcessorTest.java    |   9 +
 .../ignite/ci/tcbot/issue/IssueDetectorTest.java   |  48 +++--
 .../ci/teamcity/ignited/TeamcityIgnitedMock.java   |   2 +-
 .../IgnitedTcInMemoryIntegrationTest.java          |  83 ++++++++
 .../ignite/tcbot/engine/chain/MultBuildRunCtx.java |   8 +-
 .../tcbot/engine/chain/TestCompactedMult.java      |  26 +--
 .../ci/teamcity/ignited/BuildRefCompacted.java     |  83 +++++++-
 .../ignited/fatbuild/FatBuildCompacted.java        |   2 +-
 .../ci/teamcity/ignited/runhist/Invocation.java    |  24 ++-
 .../ignite/tcignited/build/SuiteHistory.java       |  98 ---------
 .../ignite/tcignited/build/TestCompactedV2.java    |  14 +-
 .../ignite/tcignited/buildref/BuildRefDao.java     |   1 -
 .../history/AbstractRunHist.java}                  | 178 +++++-----------
 .../ignite/tcignited/history/HistoryCollector.java |  10 +-
 .../ignite/tcignited/history/IRunHistSummary.java  |  32 ---
 .../ignite/tcignited/history/IRunHistory.java      |  30 ++-
 .../apache/ignite/tcignited/history/IRunStat.java  |  47 -----
 .../ignite/tcignited/history/ISuiteRunHistory.java |   3 +-
 .../history}/InvocationData.java                   |  82 +++-----
 .../ignite/tcignited/history/RunHistCompacted.java | 122 +++++++++++
 .../ignite/tcignited/history/SuiteHistory.java     | 232 +++++++++++++++++++++
 21 files changed, 706 insertions(+), 428 deletions(-)

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 78eeb25..bffaa89 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
@@ -26,7 +26,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
 import org.apache.ignite.tcbot.engine.chain.*;
+import org.apache.ignite.tcignited.build.TestCompactedV2;
 import org.apache.ignite.tcignited.buildlog.IBuildLogProcessor;
 import org.apache.ignite.tcservice.ITeamcity;
 import org.apache.ignite.tcservice.model.hist.BuildRef;
@@ -39,6 +41,7 @@ import org.apache.ignite.tcignited.SyncMode;
 import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedMock;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -69,6 +72,12 @@ public class BuildChainProcessorTest {
         }
     });
 
+    @Before
+    public void resetCaches() {
+        BuildRefCompacted.resetCached();
+        TestCompactedV2.resetCached();
+        TestCompactedMult.resetCached();
+    }
     /**
      *
      */
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/issue/IssueDetectorTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/issue/IssueDetectorTest.java
index 55b9113..bc5e4c9 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/issue/IssueDetectorTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/issue/IssueDetectorTest.java
@@ -21,25 +21,24 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.OptionalInt;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Stream;
-import org.apache.ignite.tcservice.ITeamcity;
+import org.apache.ignite.ci.tcbot.chain.MockBasedTcBotModule;
+import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedProviderMock;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.ci.user.ITcBotUserCreds;
 import org.apache.ignite.tcbot.engine.conf.BranchTracked;
 import org.apache.ignite.tcbot.engine.conf.ChainAtServerTracked;
-import org.apache.ignite.ci.tcbot.chain.MockBasedTcBotModule;
 import org.apache.ignite.tcbot.engine.conf.TcBotJsonConfig;
-import org.apache.ignite.tcservice.model.result.tests.TestOccurrenceFull;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
 import org.apache.ignite.tcignited.TeamcityIgnitedImpl;
-import org.apache.ignite.ci.teamcity.ignited.TeamcityIgnitedProviderMock;
-import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
-import org.apache.ignite.ci.user.ITcBotUserCreds;
+import org.apache.ignite.tcservice.ITeamcity;
+import org.apache.ignite.tcservice.model.result.tests.TestOccurrenceFull;
 import org.jetbrains.annotations.NotNull;
 import org.junit.Before;
 import org.junit.Test;
@@ -57,6 +56,8 @@ import static org.mockito.Mockito.when;
 public class IssueDetectorTest {
     /** Server id. */
     public static final String SRV_ID = "apacheTest";
+    public static final String PDS_1 = "PDS1";
+    public static final String PDS_2 = "PDS2_noChanges";
 
     /** Builds emulated storage. */
     private Map<Integer, FatBuildCompacted> apacheBuilds = new ConcurrentHashMap<>();
@@ -144,6 +145,15 @@ public class IssueDetectorTest {
         IStringCompactor c,
         Map<String, String> pds1Hist,
         Map<String, String> buildWoChanges) {
+        Map<Integer, FatBuildCompacted> builds = apacheBuilds;
+
+        emulateHistory(builds, chainId, c, PDS_1, pds1Hist, PDS_2, buildWoChanges);
+    }
+
+    public static void emulateHistory(Map<Integer, FatBuildCompacted> builds,
+        String chainId, IStringCompactor c,
+        String pds1, Map<String, String> pds1Hist,
+        String pds2, Map<String, String> buildWoChanges) {
         OptionalInt longestHist = Stream.concat(pds1Hist.values().stream(),
             buildWoChanges.values().stream()).mapToInt(String::length).max();
         Preconditions.checkState(longestHist.isPresent());
@@ -151,26 +161,26 @@ public class IssueDetectorTest {
 
         for (int i = 0; i < histLen; i++) {
             FatBuildCompacted pds1Build
-                = createFatBuild(c, "PDS1", ITeamcity.DEFAULT, 1100 + i, 100 * i, false)
+                = createFatBuild(c, pds1, ITeamcity.DEFAULT, 1100 + i, 100 * i, false)
                 .addTests(c, testsMapToXmlModel(pds1Hist, histLen, i), null)
                 .changes(new int[] {i});
 
-            apacheBuilds.put(pds1Build.id(), pds1Build);
+            builds.put(pds1Build.id(), pds1Build);
 
             FatBuildCompacted pds2Build
-                = createFatBuild(c, "PDS2_noChanges", ITeamcity.DEFAULT, 1200 + i, 100 * i, false)
+                = createFatBuild(c, pds2, ITeamcity.DEFAULT, 1200 + i, 100 * i, false)
                 .addTests(c, testsMapToXmlModel(buildWoChanges, histLen, i), null);
 
-            apacheBuilds.put(pds2Build.id(), pds2Build);
+            builds.put(pds2Build.id(), pds2Build);
 
             FatBuildCompacted chainBuild = createFatBuild(c, chainId, ITeamcity.DEFAULT, 1000 + i, 100 * i, false)
                 .snapshotDependencies(new int[] {pds1Build.id(), pds2Build.id()});
-            apacheBuilds.put(chainBuild.id(), chainBuild);
+            builds.put(chainBuild.id(), chainBuild);
         }
     }
 
     @NotNull
-    public List<TestOccurrenceFull> testsMapToXmlModel(
+    public static List<TestOccurrenceFull> testsMapToXmlModel(
         Map<String, String> pds1Hist,
         int histLen,
         int idx) {
@@ -184,9 +194,15 @@ public class IssueDetectorTest {
 
             char chState = stat.charAt(locIdx);
             boolean ok = '0' == chState;
-            boolean failed = '1' == chState;
-            if (ok || failed)
-                page.add(createTest(name.hashCode(), name, ok));
+            boolean failed = '1' == chState || '6' == chState;
+            boolean muted = '6' == chState;
+            if (ok || failed) {
+                TestOccurrenceFull test = createTest(name.hashCode(), name, ok);
+                if (muted)
+                    test.muted = true;
+
+                page.add(test);
+            }
         });
 
         return page;
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 b4484dd..2531792 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
@@ -20,7 +20,7 @@ package org.apache.ignite.ci.teamcity.ignited;
 import com.google.common.base.Preconditions;
 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.RunHistCompacted;
+import org.apache.ignite.tcignited.history.RunHistCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistKey;
 import org.apache.ignite.tcbot.common.TcBotConst;
 import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
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 3a19844..875627c 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
@@ -29,11 +29,14 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.time.Duration;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -50,6 +53,7 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
 import org.apache.ignite.ci.db.TcHelperDb;
 import org.apache.ignite.ci.tcbot.chain.PrChainsProcessorTest;
+import org.apache.ignite.ci.tcbot.issue.IssueDetectorTest;
 import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
 import org.apache.ignite.ci.teamcity.ignited.buildtype.BuildTypeRefCompacted;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
@@ -62,8 +66,10 @@ import org.apache.ignite.tcbot.common.conf.IDataSourcesConfigSupplier;
 import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
 import org.apache.ignite.tcbot.common.interceptor.GuavaCachedModule;
 import org.apache.ignite.tcbot.common.util.FutureUtil;
+import org.apache.ignite.tcbot.engine.chain.TestCompactedMult;
 import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
 import org.apache.ignite.tcbot.engine.conf.TcBotJsonConfig;
+import org.apache.ignite.tcbot.engine.issue.EventTemplates;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcbot.persistence.IgniteStringCompactor;
 import org.apache.ignite.tcbot.persistence.TcBotPersistenceModule;
@@ -71,11 +77,14 @@ import org.apache.ignite.tcbot.persistence.scheduler.DirectExecNoWaitScheduler;
 import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
 import org.apache.ignite.tcignited.build.FatBuildDao;
 import org.apache.ignite.tcignited.build.ProactiveFatBuildSync;
+import org.apache.ignite.tcignited.build.TestCompactedV2;
 import org.apache.ignite.tcignited.buildlog.ILogProductSpecific;
 import org.apache.ignite.tcignited.buildref.BuildRefDao;
 import org.apache.ignite.tcignited.history.BuildStartTimeStorage;
+import org.apache.ignite.tcignited.history.HistoryCollector;
 import org.apache.ignite.tcignited.history.IRunHistory;
 import org.apache.ignite.tcignited.history.ISuiteRunHistory;
+import org.apache.ignite.tcignited.history.SuiteInvocationHistoryDao;
 import org.apache.ignite.tcservice.ITeamcity;
 import org.apache.ignite.tcservice.TeamcityServiceConnection;
 import org.apache.ignite.tcservice.http.ITeamcityHttpConnection;
@@ -108,6 +117,7 @@ import static junit.framework.TestCase.assertFalse;
 import static junit.framework.TestCase.assertNotNull;
 import static junit.framework.TestCase.assertNull;
 import static junit.framework.TestCase.assertTrue;
+import static org.apache.ignite.ci.tcbot.issue.IssueDetectorTest.SRV_ID;
 import static org.apache.ignite.tcbot.common.conf.TcBotWorkDir.ensureDirExist;
 import static org.apache.ignite.tcbot.persistence.IgniteStringCompactor.STRINGS_CACHE;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -161,6 +171,10 @@ public class IgnitedTcInMemoryIntegrationTest {
     public void clearIgniteCaches() {
         clearCache(BuildRefDao.TEAMCITY_BUILD_CACHE_NAME);
         clearCache(FatBuildDao.TEAMCITY_FAT_BUILD_CACHE_NAME);
+
+        BuildRefCompacted.resetCached();
+        TestCompactedV2.resetCached();
+        TestCompactedMult.resetCached();
     }
 
     /**
@@ -810,7 +824,76 @@ public class IgnitedTcInMemoryIntegrationTest {
 
         FutureUtil.getResults(futures);
         svc.shutdown();
+    }
+
+    @Test
+    public void testTestHistoryPropagation() {
+        TeamcityIgnitedModule module = new TeamcityIgnitedModule();
+
+        Injector injector = Guice.createInjector(module, new GuavaCachedModule(), new IgniteAndSchedulerTestModule());
+
+        String chainId = TeamcityIgnitedImpl.DEFAULT_PROJECT_ID;
+        IStringCompactor c = injector.getInstance(IStringCompactor.class);
+
+        String testUnmuted = "testUnmuted";
+        Map<String, String> pds1Hist = new TreeMap<String, String>() {
+            {
+                put(testUnmuted, "66666611111");
+                put("testOk", "      0000");
+            }
+        };
+        String testFlakyStableFailure = "testFlakyStableFailure";
+
+        Map<String, String> pds2Hist = new TreeMap<String, String>() {
+            {
+                put("testFailedShoudlBeConsideredAsFlaky", "0000011111");
+                put(testFlakyStableFailure, "0000011111111111");
+            }
+        };
+
+        Map<Integer, FatBuildCompacted> builds = new HashMap<>();
+        String suite1 = IssueDetectorTest.PDS_1;
+        String suite2 = IssueDetectorTest.PDS_2;
+        IssueDetectorTest.emulateHistory(builds, chainId, c, suite1, pds1Hist, suite2, pds2Hist);
+
+        BuildRefDao buildRefDao = injector.getInstance(BuildRefDao.class).init();
+
+        FatBuildDao fatBuildDao = injector.getInstance(FatBuildDao.class).init();
+
+        injector.getInstance(SuiteInvocationHistoryDao.class).init();
+        injector.getInstance(BuildStartTimeStorage.class).init();
+
+        int srvId = ITeamcityIgnited.serverIdToInt(IssueDetectorTest.SRV_ID);
+        builds.forEach((k, v) -> {
+            buildRefDao.save(srvId, new BuildRefCompacted(v));
+            fatBuildDao.putFatBuild(srvId, k, v);
+        });
+
+        HistoryCollector histCollector = injector.getInstance(HistoryCollector.class);
+
+        IRunHistory hist = histCollector.getTestRunHist(SRV_ID,
+            c.getStringId(testUnmuted),
+            c.getStringId(suite1),
+            c.getStringId(ITeamcity.DEFAULT));
+
+        assertNotNull(hist);
+
+        assertEquals(Arrays.asList(4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1), hist.getLatestRunResults());
+
+        assertEquals(0, hist.getCriticalFailuresCount());
+
+        assertFalse(hist.isFlaky());
+        assertEquals(1.0, hist.getFailRate(), 0.05);
+
+        IRunHistory histFailedFlaky = histCollector.getTestRunHist(SRV_ID,
+            c.getStringId(testFlakyStableFailure),
+            c.getStringId(suite2),
+            c.getStringId(ITeamcity.DEFAULT));
+
+        assertTrue(histFailedFlaky.isFlaky());
 
+        Integer integer = histFailedFlaky.detectTemplate(EventTemplates.newFailureForFlakyTest);
+        assertNotNull(integer);
     }
 
     /**
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 7fb1a87..53d2486 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
@@ -697,14 +697,14 @@ public class MultBuildRunCtx implements ISuiteResults {
             return null;
 
         try {
-            ISuiteRunHistory suiteRunHistory = histCacheMap.get(baseBranchId,
+            ISuiteRunHistory suiteRunHist = histCacheMap.get(baseBranchId,
                 () -> Optional.ofNullable(tcIgn.getSuiteRunHist(buildTypeIdId, baseBranchId)))
                 .orElse(null);
 
-            if (suiteRunHistory != null && requireParameters != null && !requireParameters.isEmpty())
-                return suiteRunHistory.filter(requireParameters);
+            if (suiteRunHist != null && requireParameters != null && !requireParameters.isEmpty())
+                return suiteRunHist.filter(requireParameters);
 
-            return suiteRunHistory;
+            return suiteRunHist;
         }
         catch (ExecutionException 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 8e6b007..9863364 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
@@ -28,9 +28,7 @@ import org.apache.ignite.tcbot.common.TcBotConst;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.build.ITest;
-import org.apache.ignite.tcignited.history.IRunHistSummary;
 import org.apache.ignite.tcignited.history.IRunHistory;
-import org.apache.ignite.tcignited.history.IRunStat;
 import org.apache.ignite.tcignited.history.ISuiteRunHistory;
 import org.apache.ignite.tcservice.model.result.tests.TestOccurrence;
 
@@ -44,15 +42,19 @@ public class TestCompactedMult {
     private long avgDuration = -1;
 
     /** Status success. */
-    private static volatile int STATUS_SUCCESS = -1;
+    private static volatile int STATUS_SUCCESS_CID = -1;
 
     public TestCompactedMult(IStringCompactor compactor, MultBuildRunCtx ctx) {
         this.compactor = compactor;
         this.ctx = ctx;
 
         //Each time compactor should give same result
-        if (STATUS_SUCCESS == -1)
-            STATUS_SUCCESS = compactor.getStringId(TestOccurrence.STATUS_SUCCESS);
+        if (STATUS_SUCCESS_CID == -1)
+            STATUS_SUCCESS_CID = compactor.getStringId(TestOccurrence.STATUS_SUCCESS);
+    }
+
+    public static void resetCached() {
+        STATUS_SUCCESS_CID = -1;
     }
 
     @Nullable public Integer testName() {
@@ -71,7 +73,7 @@ public class TestCompactedMult {
     private int getFailedButNotMutedCount() {
         return (int)occurrences.stream()
             .filter(Objects::nonNull)
-            .filter(t -> t.isFailedButNotMuted(STATUS_SUCCESS)).count();
+            .filter(t -> t.isFailedButNotMuted(STATUS_SUCCESS_CID)).count();
     }
 
     public int failuresCount() {
@@ -102,7 +104,7 @@ public class TestCompactedMult {
       * @param baseBranchStat Base branch statistics.
       * @return non null comment in case test failure is a blocker for merge into base branch.
       */
-     public String getPossibleBlockerComment(IRunHistSummary baseBranchStat) {
+     public String getPossibleBlockerComment(IRunHistory baseBranchStat) {
          if (failuresCount() == 0) {
              if (baseBranchStat == null) {
                  long durationMs = getAvgDurationMs();
@@ -124,7 +126,7 @@ public class TestCompactedMult {
          boolean lowFailureRate = failRate * 100.0f < TcBotConst.NON_FLAKY_TEST_FAIL_RATE_BLOCKER_BORDER_PERCENTS;
 
          if (lowFailureRate && !flaky) {
-             String runStatPrintable = IRunStat.getPercentPrintable(failRate * 100.0f);
+             String runStatPrintable = IRunHistory.getPercentPrintable(failRate * 100.0f);
 
              return "Test has low fail rate in base branch "
                  + runStatPrintable
@@ -142,9 +144,9 @@ public class TestCompactedMult {
          return history(ignited, baseBranchId, null);
     }
 
-    public IRunHistory history(ITeamcityIgnited ignited,
-                               @Nullable Integer baseBranchId,
-                               @Nullable Map<Integer, Integer> requireParameters) {
+    @Nullable public IRunHistory history(ITeamcityIgnited ignited,
+        @Nullable Integer baseBranchId,
+        @Nullable Map<Integer, Integer> requireParameters) {
         Integer name = testName();
         if (name == null || baseBranchId == null)
             return null;
@@ -160,7 +162,7 @@ public class TestCompactedMult {
     /**
      */
     public boolean isFailedButNotMuted() {
-        return occurrences.stream().anyMatch(o -> o.isFailedButNotMuted(STATUS_SUCCESS));
+        return occurrences.stream().anyMatch(o -> o.isFailedButNotMuted(STATUS_SUCCESS_CID));
     }
 
     /**
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
index 50a367f..4766e77 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/BuildRefCompacted.java
@@ -18,16 +18,18 @@ package org.apache.ignite.ci.teamcity.ignited;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
-
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcbot.persistence.Persisted;
 import org.apache.ignite.tcservice.model.hist.BuildRef;
 
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import static org.apache.ignite.tcservice.model.hist.BuildRef.*;
+import static org.apache.ignite.tcservice.model.hist.BuildRef.STATE_FINISHED;
+import static org.apache.ignite.tcservice.model.hist.BuildRef.STATE_QUEUED;
+import static org.apache.ignite.tcservice.model.hist.BuildRef.STATE_RUNNING;
+import static org.apache.ignite.tcservice.model.hist.BuildRef.STATUS_SUCCESS;
+import static org.apache.ignite.tcservice.model.hist.BuildRef.STATUS_UNKNOWN;
 
 @Persisted
 public class BuildRefCompacted {
@@ -47,6 +49,19 @@ public class BuildRefCompacted {
     /** Compacter identifier for string 'State'. */
     private int state = -1;
 
+    /** Status Unknown: Compactor identifier. */
+    private static volatile int STATUS_UNKNOWN_CID = -1;
+    /** Status success: Compactor identifier. */
+    private static volatile int STATUS_SUCCESS_CID = -1;
+
+    /** State running: Compactor identifier. */
+    private static volatile int STATE_RUNNING_CID = -1;
+    /** State queued: Compactor identifier. */
+    private static volatile int STATE_QUEUED_CID = -1;
+    /** State finished: Compactor identifier. */
+    private static volatile int STATE_FINISHED_CID = -1;
+
+
     /**
      * Default constructor.
      */
@@ -61,6 +76,17 @@ public class BuildRefCompacted {
         fillFieldsFromBuildRef(compactor, ref);
     }
 
+    /**
+     * Reset cached Ids for tests
+     */
+    public static void resetCached() {
+        STATE_FINISHED_CID = -1;
+        STATE_QUEUED_CID = -1;
+        STATUS_UNKNOWN_CID = -1;
+        STATUS_SUCCESS_CID = -1;
+        STATE_RUNNING_CID = -1;
+    }
+
     public void fillFieldsFromBuildRef(IStringCompactor compactor, BuildRef ref) {
         setId(ref.getId());
         buildTypeId = compactor.getStringId(ref.buildTypeId());
@@ -185,6 +211,42 @@ public class BuildRefCompacted {
         return id() < 0;
     }
 
+
+    private int statusUnkown(IStringCompactor compactor) {
+        if (STATUS_UNKNOWN_CID == -1) //Each time compactor should give same result, so no locking applied
+            STATUS_UNKNOWN_CID = compactor.getStringId(STATUS_UNKNOWN);
+
+        return STATUS_UNKNOWN_CID;
+    }
+
+    public int statusSuccess(IStringCompactor compactor) {
+        if (STATUS_SUCCESS_CID == -1) //Each time compactor should give same result, so no locking applied
+            STATUS_SUCCESS_CID =  compactor.getStringId(STATUS_SUCCESS);
+
+        return STATUS_SUCCESS_CID;
+    }
+
+    public int stateRunning(IStringCompactor compactor) {
+        if (STATE_RUNNING_CID == -1) //Each time compactor should give same result, so no locking applied
+            STATE_RUNNING_CID = compactor.getStringId(STATE_RUNNING);
+
+        return STATE_RUNNING_CID;
+    }
+
+    public int stateFinished(IStringCompactor compactor) {
+        if (STATE_FINISHED_CID == -1) //Each time compactor should give same result, so no locking applied
+            STATE_FINISHED_CID =  compactor.getStringId(STATE_FINISHED);
+
+        return STATE_FINISHED_CID;
+    }
+
+    public int stateQueued(IStringCompactor compactor) {
+        if (STATE_QUEUED_CID == -1) //Each time compactor should give same result, so no locking applied
+            STATE_QUEUED_CID = compactor.getStringId(STATE_QUEUED);
+
+        return STATE_QUEUED_CID;
+    }
+
     public boolean isNotCancelled(IStringCompactor compactor) {
         return !isCancelled(compactor);
     }
@@ -194,25 +256,26 @@ public class BuildRefCompacted {
     }
 
     private boolean hasUnknownStatus(IStringCompactor compactor) {
-        return compactor.getStringId(STATUS_UNKNOWN) == status();
+        return statusUnkown(compactor) == status();
     }
 
     public boolean isRunning(IStringCompactor compactor) {
-        return compactor.getStringId(STATE_RUNNING) == state();
+        return stateRunning(compactor) == state();
     }
 
     public boolean isFinished(IStringCompactor compactor) {
-        return compactor.getStringId(STATE_FINISHED) == state();
+        return stateFinished(compactor) == state();
     }
 
     public boolean isQueued(IStringCompactor compactor) {
-        return compactor.getStringId(STATE_QUEUED) == state();
+        return stateQueued(compactor) == state();
     }
 
     public boolean isSuccess(IStringCompactor compactor) {
-        return compactor.getStringId(STATUS_SUCCESS) == status();
+        return statusSuccess(compactor) == status();
     }
 
+    /** {@inheritDoc} */
     @Override public String toString() {
         return MoreObjects.toStringHelper(this)
             .add("id", id)
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 42b36c4..ac11fb0 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
@@ -38,7 +38,7 @@ import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
 import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
 import org.apache.ignite.ci.teamcity.ignited.change.RevisionCompacted;
 import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
-import org.apache.ignite.ci.teamcity.ignited.runhist.InvocationData;
+import org.apache.ignite.tcignited.history.InvocationData;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcbot.persistence.IVersionedEntity;
 import org.apache.ignite.tcbot.persistence.Persisted;
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 bc8a89d..f4a1dea 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,15 +20,14 @@ 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;
-
+import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
+import org.apache.ignite.tcbot.persistence.Persisted;
+import org.apache.ignite.tcignited.history.ChangesState;
+import org.apache.ignite.tcignited.history.InvocationData;
 
 /**
  * Run history element: invocation of build or test.
@@ -152,4 +151,19 @@ public class Invocation {
     public boolean containsParameterValue(Map<Integer, Integer> requireParameters) {
         return hasAnyParameterValue(this.parameters, requireParameters);
     }
+
+    public Invocation withChangeState(ChangesState state) {
+        if (state == ChangesState.NONE)
+            changePresent = NO_CHANGES;
+        else if (state == ChangesState.EXIST)
+            changePresent = CHANGE_PRESENT;
+        else
+            changePresent = CHANGE_NOT_FILLED;
+
+        return this;
+    }
+
+    public static boolean isMutedOrIgnored(byte s) {
+        return s == InvocationData.MUTED || s == InvocationData.FAILURE_MUTED || s == InvocationData.OK_MUTED || s == InvocationData.IGNORED;
+    }
 }
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
deleted file mode 100644
index 508e94f..0000000
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
+++ /dev/null
@@ -1,98 +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.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;
-import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistCompacted;
-import org.apache.ignite.internal.binary.BinaryObjectExImpl;
-import org.apache.ignite.tcignited.history.IRunHistory;
-import org.apache.ignite.tcignited.history.ISuiteRunHistory;
-import org.apache.ignite.tcignited.history.SuiteInvocation;
-
-/**
- * Suite run history (in memory) summary with tests grouped by name.
- */
-public class SuiteHistory implements ISuiteRunHistory {
-    /** Tests history: Test name ID->RunHistory */
-    private Map<Integer, RunHistCompacted> testsHistory = new HashMap<>();
-
-    private RunHistCompacted suiteHist = new RunHistCompacted();
-
-    public SuiteHistory(Map<Integer, SuiteInvocation> suiteRunHist) {
-        suiteRunHist.forEach((buildId, suiteInv) -> addSuiteInvocation(suiteInv));
-        finalizeInvocations();
-    }
-
-    private SuiteHistory() {}
-
-    private void finalizeInvocations() {
-        Set<Integer> presentBuilds = suiteHist.buildIds();
-
-        testsHistory.forEach((k, t) -> t.registerMissing(k, presentBuilds));
-
-        suiteHist.sort();
-        testsHistory.values().forEach(RunHistCompacted::sort);
-    }
-
-    public int size(Ignite ignite) {
-        BinaryObjectExImpl binary = ignite.binary().toBinary(this);
-        return binary.length();
-    }
-
-    public IRunHistory getTestRunHist(int testName) {
-        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());
-    }
-
-    private void addTestInvocation(Integer tName, Invocation invocation) {
-        getOrAddTestsHistory(tName).addInvocation(invocation);
-    }
-
-    /**
-     * @param suiteInv suite invocation (build) to be added to history (summary).
-     */
-    private void addSuiteInvocation(SuiteInvocation suiteInv) {
-        suiteInv.tests().forEach(this::addTestInvocation);
-
-        suiteHist.addInvocation(suiteInv.suiteInvocation());
-    }
-
-    @Override public IRunHistory self() {
-        return suiteHist;
-    }
-}
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 15ec251..cfd64f8 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
@@ -24,7 +24,7 @@ import javax.annotation.Nullable;
 import org.apache.ignite.ci.tcbot.common.StringFieldCompacted;
 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;
+import org.apache.ignite.tcignited.history.InvocationData;
 import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcbot.persistence.Persisted;
 import org.apache.ignite.tcignited.buildlog.ILogProductSpecific;
@@ -49,7 +49,7 @@ public class TestCompactedV2 implements ITest {
     public static final int IGNORED_F = 6;
 
     /** Status success. */
-    private static volatile int STATUS_SUCCESS = -1;
+    private static volatile int STATUS_SUCCESS_CID = -1;
 
     /** Id in this build only. Does not identify test for its history */
     private int idInBuild = -1;
@@ -326,10 +326,14 @@ public class TestCompactedV2 implements ITest {
 
     public int statusSuccess(IStringCompactor compactor) {
         //Each time compactor should give same result, so no locking applied
-        if (STATUS_SUCCESS == -1)
-            STATUS_SUCCESS = compactor.getStringId(TestOccurrence.STATUS_SUCCESS);
+        if (STATUS_SUCCESS_CID == -1)
+            STATUS_SUCCESS_CID = compactor.getStringId(TestOccurrence.STATUS_SUCCESS);
 
-        return STATUS_SUCCESS;
+        return STATUS_SUCCESS_CID;
+    }
+
+    public static void resetCached() {
+        STATUS_SUCCESS_CID = -1;
     }
 
     public String testName(IStringCompactor compactor) {
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BuildRefDao.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BuildRefDao.java
index d942c12..74a91f9 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BuildRefDao.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildref/BuildRefDao.java
@@ -305,7 +305,6 @@ public class BuildRefDao {
         }
 
         if (!list.isEmpty()) {
-
             System.err.println(" Branch " + compactor.getStringFromId(branchNameId)
                 + " builds " + list.size() + " (Overall) ");
         }
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/tcignited/history/AbstractRunHist.java
similarity index 54%
rename from tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
rename to tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/AbstractRunHist.java
index c61a9a7..8c45088 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/tcignited/history/AbstractRunHist.java
@@ -14,73 +14,75 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.ignite.tcignited.history;
 
-package org.apache.ignite.ci.teamcity.ignited.runhist;
-
-import com.google.common.base.MoreObjects;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import javax.annotation.Nullable;
+import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 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;
 
 /**
- * In memory replacement of invocation history (RunHist/RunStat).
+ * Abstract in memory summary of suite or test execution history
  */
-public class RunHistCompacted implements IRunHistory {
-    /** Data. */
-    private InvocationData data = new InvocationData();
+public abstract class AbstractRunHist implements IRunHistory {
+    /**
+     *
+     */
+    public abstract Iterable<Invocation> invocations();
 
-    public RunHistCompacted() {
+    /**
+     *
+     */
+    public Stream<Invocation> getInvocations() {
+        return StreamSupport.stream(invocations().spliterator(), false);
     }
 
-    public RunHistCompacted(RunHistKey ignored) {
-
+    /** {@inheritDoc} */
+    @Override public int getCriticalFailuresCount() {
+        return (int)getInvocations().filter(inv -> inv.status() == InvocationData.CRITICAL_FAILURE).count();
     }
 
     /** {@inheritDoc} */
-    @Override public int getRunsCount() {
-        return data.notMutedAndNonMissingRunsCount();
+    @Override public int getFailuresCount() {
+        return (int)getInvocations().filter(inv ->
+            inv.status() == InvocationData.FAILURE
+                || inv.status() == InvocationData.CRITICAL_FAILURE).count();
     }
 
     /** {@inheritDoc} */
-    @Override public int getFailuresCount() {
-        return data.failuresCount();
+    @Override public int getRunsCount() {
+        return (int)getInvocations().filter(inv ->
+            inv.status() != InvocationData.MISSING && !Invocation.isMutedOrIgnored(inv.status())).count();
     }
 
     /** {@inheritDoc} */
-    @Nullable
-    @Override public List<Integer> getLatestRunResults() {
-        return data.getLatestRuns();
+    @Override public boolean isFlaky() {
+        return getStatusChangesWithoutCodeModification() >= TcBotConst.FLAKYNESS_STATUS_CHANGE_BORDER;
     }
 
     /** {@inheritDoc} */
-    @Override public String getFlakyComments() {
+    @Override public final String getFlakyComments() {
         int statusChange = getStatusChangesWithoutCodeModification();
 
         if (statusChange < TcBotConst.FLAKYNESS_STATUS_CHANGE_BORDER)
             return null;
 
         return "Test seems to be flaky: " +
-            "changed its status [" + statusChange + "/" + data.invocations().count() + "] without code modifications";
+            "changed its status [" + statusChange + "/" + getInvocations().count() + "] without code modifications";
     }
 
+    /**
+     * @return number of status change without code modifications for test to be considered as flaky
+     */
     public int getStatusChangesWithoutCodeModification() {
         int statusChange = 0;
 
         Invocation prev = null;
 
-        List<Invocation> latestRuns = data.invocations().collect(Collectors.toList());
-
-        for (Invocation cur : latestRuns) {
+        for (Invocation cur : invocations()) {
             if (cur == null)
                 continue;
 
@@ -88,7 +90,6 @@ public class RunHistCompacted implements IRunHistory {
                 continue;
 
             //todo here all previous MISSING invocations status could be checked
-            // (using outside build history)
             if (prev != null) {
                 if (prev.status() != cur.status()
                     && cur.changesState() == ChangesState.NONE
@@ -101,34 +102,8 @@ public class RunHistCompacted implements IRunHistory {
         return statusChange;
     }
 
-    /** {@inheritDoc} */
-    @Override public boolean isFlaky() {
-        return getStatusChangesWithoutCodeModification() >= TcBotConst.FLAKYNESS_STATUS_CHANGE_BORDER;
-    }
-
-    /** {@inheritDoc} */
-    @Override public int getCriticalFailuresCount() {
-        return data.criticalFailuresCount();
-    }
-
-    /** {@inheritDoc} */
-    @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);
-        System.arraycopy(arr2, 0, arr1and2, arr1.length, arr2.length);
-
-        return arr1and2;
-    }
-
     @Nullable
     public Integer detectTemplate(IEventTemplate t) {
-        if (data == null)
-            return null;
-
         int centralEvtBuild = t.beforeEvent().length;
 
         int[] template = concatArr(t.beforeEvent(), t.eventAndAfter());
@@ -137,7 +112,12 @@ public class RunHistCompacted implements IRunHistory {
         assert centralEvtBuild >= 0;
 
         boolean includeMissing = t.includeMissing();
-        List<Invocation> histAsArr = data.invocations(!includeMissing).collect(Collectors.toList());
+
+        List<Invocation> histAsArr = new ArrayList<>();
+        for (Invocation invocation : invocations()) {
+            if (includeMissing || invocation.status() != InvocationData.MISSING)
+                histAsArr.add(invocation);
+        }
 
         if (histAsArr.size() < template.length)
             return null;
@@ -153,17 +133,25 @@ public class RunHistCompacted implements IRunHistory {
         }
 
         if (detectedAt != null && t.shouldBeFirstNonMissing()) {
-            Optional<Invocation> first = data.invocations(true).findFirst();
-            if (!first.isPresent())
-                return null;
+            for (Invocation invocation : invocations()) {
+                if (invocation.status() != InvocationData.MISSING)
+                    return invocation.buildId() != detectedAt ? null : detectedAt;
+            }
 
-            if (first.get().buildId() != detectedAt)
-                return null;
+            return null;
         }
 
         return detectedAt;
     }
 
+    private static int[] concatArr(int[] arr1, int[] arr2) {
+        int[] arr1and2 = new int[arr1.length + arr2.length];
+        System.arraycopy(arr1, 0, arr1and2, 0, arr1.length);
+        System.arraycopy(arr2, 0, arr1and2, arr1.length, arr2.length);
+
+        return arr1and2;
+    }
+
     @Nullable
     private static Integer checkTemplateAtPos(int[] template, int centralEvtBuild, List<Invocation> histAsArr,
         int idx) {
@@ -186,66 +174,4 @@ public class RunHistCompacted implements IRunHistory {
 
         return null;
     }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        Stream<CharSequence> stream = data.getLatestRuns().stream().filter(Objects::nonNull).map(Object::toString);
-        String join = String.join("", stream::iterator);
-
-        return MoreObjects.toStringHelper(this)
-            .add("runs", join)
-            .add("failRate", getFailPercentPrintable())
-            .add("data", data)
-            .toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean equals(Object o) {
-        if (this == o)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-        RunHistCompacted compacted = (RunHistCompacted)o;
-        return Objects.equals(data, compacted.data);
-    }
-
-    /** {@inheritDoc} */
-    @Override public int hashCode() {
-        return Objects.hash(data);
-    }
-
-    /**
-     * @param v Invocation.
-     */
-    public void addInvocation(Invocation v) {
-        data.add(v);
-    }
-
-    public void sort() {
-        data.sort();
-    }
-
-    public void registerMissing(Integer testId, Set<Integer> buildIds) {
-        data.registerMissing(testId, buildIds);
-    }
-
-    public RunHistCompacted filterSuiteInvByParms(Map<Integer, Integer> requireParameters) {
-        RunHistCompacted cp = new RunHistCompacted();
-
-        data.invocations()
-            .filter(invocation -> invocation.containsParameterValue(requireParameters))
-            .forEach(invocation -> cp.data.add(invocation));
-
-        return cp;
-    }
-
-    public RunHistCompacted filterByBuilds(Set<Integer> builds) {
-        RunHistCompacted cp = new RunHistCompacted();
-
-        data.invocations()
-            .filter(invocation -> builds.contains(invocation.buildId()))
-            .forEach(invocation -> cp.data.add(invocation));
-
-        return cp;
-    }
 }
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 3695cb6..63a2c14 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
@@ -34,8 +34,6 @@ import java.util.stream.Stream;
 import javax.annotation.Nonnull;
 import javax.cache.Cache;
 import javax.inject.Inject;
-import javax.inject.Provider;
-import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.cache.query.QueryCursor;
@@ -54,7 +52,6 @@ import org.apache.ignite.tcbot.persistence.IStringCompactor;
 import org.apache.ignite.tcignited.ITeamcityIgnited;
 import org.apache.ignite.tcignited.build.FatBuildDao;
 import org.apache.ignite.tcignited.build.ITest;
-import org.apache.ignite.tcignited.build.SuiteHistory;
 import org.apache.ignite.tcignited.build.TestCompactedV2;
 import org.apache.ignite.tcignited.buildref.BranchEquivalence;
 import org.apache.ignite.tcignited.buildref.BuildRefDao;
@@ -82,9 +79,6 @@ public class HistoryCollector {
     /** Compactor. */
     @Inject private IStringCompactor compactor;
 
-    /** Ignite provider. */
-    @Inject private Provider<Ignite> igniteProvider;
-
     /** Branch equivalence. */
     @Inject private BranchEquivalence branchEquivalence;
 
@@ -113,7 +107,6 @@ public class HistoryCollector {
      */
     public IRunHistory getTestRunHist(String srvCode, int testName, int buildTypeId,
                                       int normalizedBaseBranch) {
-
         SuiteHistory hist = getSuiteHist(srvCode, buildTypeId, normalizedBaseBranch);
 
         return hist.getTestRunHist(testName);
@@ -248,8 +241,7 @@ public class HistoryCollector {
         if (logger.isDebugEnabled()) {
             logger.debug("***** History for suite "
                 + compactor.getStringFromId(buildTypeId)
-                + " branch" + compactor.getStringFromId(normalizedBaseBranch) + " requires " +
-                summary.size(igniteProvider.get()) + " bytes");
+                + " branch" + compactor.getStringFromId(normalizedBaseBranch) + "   ");
         }
 
         return summary;
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistSummary.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistSummary.java
deleted file mode 100644
index 1d33f73..0000000
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunHistSummary.java
+++ /dev/null
@@ -1,32 +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;
-
-/**
- *
- */
-public interface IRunHistSummary {
-    /**
-     *
-     */
-    public float getFailRate();
-
-    /**
-     *
-     */
-    public boolean isFlaky();
-}
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 7b2faac..b54bc53 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,12 +18,16 @@ package org.apache.ignite.tcignited.history;
 
 import javax.annotation.Nullable;
 import java.util.List;
-import java.util.Set;
 
 /**
  * Test or Build run statistics.
  */
-public interface IRunHistory extends IRunStat, IRunHistSummary {
+public interface IRunHistory {
+    /**
+     *
+     */
+    public boolean isFlaky();
+
     @Nullable
     List<Integer> getLatestRunResults();
 
@@ -33,7 +37,7 @@ public interface IRunHistory extends IRunStat, IRunHistSummary {
     public Integer detectTemplate(IEventTemplate t);
 
     public default String getCriticalFailPercentPrintable() {
-        return IRunStat.getPercentPrintable(getCriticalFailRate() * 100.0f);
+        return getPercentPrintable(getCriticalFailRate() * 100.0f);
     }
 
     /**
@@ -48,10 +52,16 @@ public interface IRunHistory extends IRunStat, IRunHistSummary {
         return 1.0f * getCriticalFailuresCount() / runs;
     }
 
-
     public int getCriticalFailuresCount();
 
-    @Override default float getFailRate() {
+    public int getRunsCount();
+    public int getFailuresCount();
+
+    /**
+     * Recent runs fail rate.
+     * @return fail rate as float: 0.0...1.0
+     */
+    public default float getFailRate() {
         int runs = getRunsCount();
 
         if (runs == 0)
@@ -60,5 +70,13 @@ public interface IRunHistory extends IRunStat, IRunHistSummary {
         return 1.0f * getFailuresCount() / runs;
     }
 
-    Set<Integer> buildIds();
+    public default String getFailPercentPrintable() {
+        return getPercentPrintable(getFailRate() * 100.0f);
+    }
+
+
+    public static String getPercentPrintable(float percent) {
+        return String.format("%.1f", percent).replace(".", ",");
+    }
+
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunStat.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunStat.java
deleted file mode 100644
index 7596400..0000000
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IRunStat.java
+++ /dev/null
@@ -1,47 +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;
-
-/**
- * Abstract runs statistics,
- */
-public interface IRunStat {
-    public int getRunsCount();
-    public int getFailuresCount();
-
-    /**
-     * Recent runs fail rate.
-     * @return fail rate as float: 0.0...1.0
-     */
-    public default float getFailRate() {
-        int runs = getRunsCount();
-
-        if (runs == 0)
-            return 0.0f;
-
-        return 1.0f * getFailuresCount() / runs;
-    }
-
-    public default String getFailPercentPrintable() {
-        return getPercentPrintable(getFailRate() * 100.0f);
-    }
-
-
-    public static String getPercentPrintable(float percent) {
-        return String.format("%.1f", percent).replace(".", ",");
-    }
-}
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 a3223b9..1fae99a 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
@@ -17,10 +17,11 @@
 package org.apache.ignite.tcignited.history;
 
 import java.util.Map;
+import javax.annotation.Nullable;
 
 public interface ISuiteRunHistory {
     IRunHistory self();
-    IRunHistory getTestRunHist(int testName);
+    @Nullable IRunHistory getTestRunHist(int testName);
 
     ISuiteRunHistory filter(Map<Integer, Integer> 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/tcignited/history/InvocationData.java
similarity index 65%
rename from tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
rename to tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/InvocationData.java
index 68bc7af..5b5f1da 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/tcignited/history/InvocationData.java
@@ -15,19 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.ci.teamcity.ignited.runhist;
+package org.apache.ignite.tcignited.history;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.annotation.Nonnull;
-import org.apache.ignite.tcignited.history.RunStatus;
+import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 
 /**
  *
@@ -63,42 +65,9 @@ public class InvocationData {
     /**
      *
      */
-    public int notMutedAndNonMissingRunsCount() {
-        return (int)
-            invocations(true)
-                .filter(invocation -> {
-                    byte s = invocation.status();
-                    return s != MUTED && s != FAILURE_MUTED && s != OK_MUTED && s != IGNORED;
-                })
-                .count();
-    }
-
-    /**
-     *
-     */
     @Nonnull
     Stream<Invocation> invocations() {
-        return invocations(false);
-    }
-
-
-    /**
-     * @param skipMissing Skip missing (absent) invocations.
-     */
-    @Nonnull Stream<Invocation> invocations(boolean skipMissing) {
-        Stream<Invocation> stream = invocationList.stream();
-
-        if (skipMissing)
-            stream = stream.filter(invocation -> invocation.status() != MISSING);
-
-        return stream;
-    }
-
-    /**
-     *
-     */
-    int failuresCount() {
-        return (int)invocations().filter(inv -> inv.status() == FAILURE || inv.status() == CRITICAL_FAILURE).count();
+        return invocationList.stream();
     }
 
     /** {@inheritDoc} */
@@ -133,28 +102,33 @@ public class InvocationData {
             .collect(Collectors.toList());
     }
 
-    /**
-     *
-     */
-    public int criticalFailuresCount() {
-        return (int)invocations().filter(inv -> inv.status() == CRITICAL_FAILURE).count();
-    }
-
     public void sort() {
         invocationList.sort(Comparator.comparing(Invocation::buildId));
     }
 
-    public Set<Integer> buildIds() {
-        return invocationList.stream().map(Invocation::buildId).collect(Collectors.toSet());
+    /**
+     * Build ID - index mapping should be always called after sort.
+     */
+    public Map<Integer, Integer> buildIdsMapping() {
+        Map<Integer, Integer> buildIdToIdx = new HashMap<>();
+        int idx = 0;
+
+        for (Invocation next : invocationList) {
+            buildIdToIdx.put(next.buildId(), idx);
+            idx++;
+        }
+
+        return buildIdToIdx;
     }
 
-    public void registerMissing(Integer testId, Set<Integer> suiteBuildIds) {
-        Set<Integer> idsPresent = buildIds();
-        HashSet<Integer> toAdd = new HashSet<>(suiteBuildIds);
-        toAdd.removeAll(idsPresent);
+    public Iterable<Invocation> invocationsIterable() {
+        return Collections.unmodifiableList(invocationList);
+    }
 
-        toAdd.forEach(id -> {
-            add(new Invocation(id).withStatus(MISSING));
-        });
+    public Invocation getInvocationAt(int idx) {
+        int size = invocationList.size();
+        Preconditions.checkState(idx < size,
+            "Requested invocation outside suite history [" + idx + "] size [" + size + "]");
+        return invocationList.get(idx);
     }
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistCompacted.java
new file mode 100644
index 0000000..ad66f2c
--- /dev/null
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunHistCompacted.java
@@ -0,0 +1,122 @@
+/*
+ * 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 com.google.common.base.MoreObjects;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Stream;
+import javax.annotation.Nullable;
+import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
+import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistKey;
+
+/**
+ * In memory replacement of invocation history (RunHist/RunStat).
+ */
+public class RunHistCompacted extends AbstractRunHist {
+    /** Data. */
+    private InvocationData data = new InvocationData();
+
+    public RunHistCompacted() {
+    }
+
+    public RunHistCompacted(RunHistKey ignored) {
+
+    }
+
+    /** {@inheritDoc} */
+    @Nullable
+    @Override public List<Integer> getLatestRunResults() {
+        return data.getLatestRuns();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Stream<Invocation> getInvocations() {
+        return data.invocations();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Iterable<Invocation> invocations() {
+        return data.invocationsIterable();
+    }
+
+    public Set<Integer> buildIds() {
+        return data.buildIdsMapping().keySet();
+    }
+
+    public Map<Integer, Integer> buildIdsMapping() {
+        return data.buildIdsMapping();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        Stream<CharSequence> stream = data.getLatestRuns().stream().filter(Objects::nonNull).map(Object::toString);
+        String join = String.join("", stream::iterator);
+
+        return MoreObjects.toStringHelper(this)
+            .add("runs", join)
+            .add("failRate", getFailPercentPrintable())
+            .add("data", data)
+            .toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        RunHistCompacted compacted = (RunHistCompacted)o;
+        return Objects.equals(data, compacted.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return Objects.hash(data);
+    }
+
+    /**
+     * @param v Invocation.
+     */
+    public void addInvocation(Invocation v) {
+        data.add(v);
+    }
+
+    public void sort() {
+        data.sort();
+    }
+
+    public RunHistCompacted filterSuiteInvByParms(Map<Integer, Integer> requireParameters) {
+        RunHistCompacted cp = new RunHistCompacted();
+
+        getInvocations()
+            .filter(invocation -> invocation.containsParameterValue(requireParameters))
+            .forEach(invocation -> cp.data.add(invocation));
+
+        return cp;
+    }
+
+    /**
+     * @param idx Index.
+     */
+    public Invocation getInvocationAt(int idx) {
+        return data.getInvocationAt(idx);
+    }
+}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteHistory.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteHistory.java
new file mode 100644
index 0000000..51b40a6
--- /dev/null
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/SuiteHistory.java
@@ -0,0 +1,232 @@
+/*
+ * 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 com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
+
+/**
+ * Suite run history (in memory) summary with tests grouped by name.
+ */
+public class SuiteHistory implements ISuiteRunHistory {
+    /** Tests history: Test name ID->statuses for invocations */
+    private Map<Integer, byte[]> testsInvStatues = new HashMap<>();
+
+    /** Suite history. */
+    private RunHistCompacted suiteHist = new RunHistCompacted();
+
+    public SuiteHistory(Map<Integer, SuiteInvocation> suiteRunHist) {
+        //filling data for tests invoked.
+        Map<Integer, RunHistCompacted> testsHist = new HashMap<>();
+
+        suiteRunHist.forEach((buildId, suiteInv) -> addSuiteInvocation(suiteInv, testsHist));
+
+        suiteHist.sort();
+
+        Map<Integer, Integer> buildIdToIdx = suiteHist.buildIdsMapping();
+        int buildsCnt = buildIdToIdx.size();
+
+        byte missingCode = (byte)RunStatus.RES_MISSING.getCode();
+        testsHist.forEach((k, testHist) -> {
+            byte[] testStatusesUltraComp = new byte[buildsCnt];
+
+            for (int i = 0; i < testStatusesUltraComp.length; i++)
+                testStatusesUltraComp[i] = missingCode;
+
+            testHist.getInvocations().forEach(
+                invocation -> {
+                    int i = invocation.buildId();
+                    Integer idx = buildIdToIdx.get(i);
+                    if (idx == null)
+                        return;
+
+                    Preconditions.checkState(idx < testStatusesUltraComp.length);
+
+                    testStatusesUltraComp[idx] = invocation.status();
+                }
+            );
+
+            testsInvStatues.put(k, testStatusesUltraComp);
+        });
+    }
+
+    private SuiteHistory() {}
+
+    /**
+     * @param suiteInv suite invocation (build) to be added to history (summary).
+     * @param testsHist tests map.
+     */
+    private void addSuiteInvocation(SuiteInvocation suiteInv, Map<Integer, RunHistCompacted> testsHist) {
+        suiteInv.tests().forEach(
+            (tName, invocation) -> {
+                testsHist.computeIfAbsent(tName, k_ -> new RunHistCompacted())
+                    .addInvocation(invocation);
+            });
+
+        suiteHist.addInvocation(suiteInv.suiteInvocation());
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public IRunHistory getTestRunHist(int testName) {
+        byte[] testInvStatuses = testsInvStatues.get(testName);
+
+        if(testInvStatuses == null)
+            return null;
+
+        return new TestUltraCompactRunHist(testInvStatuses, suiteHist);
+    }
+
+    /** {@inheritDoc} */
+    @Override public ISuiteRunHistory filter(Map<Integer, Integer> requireParameters) {
+        RunHistCompacted suitesFiltered = suiteHist.filterSuiteInvByParms(requireParameters);
+
+        Map<Integer, Integer> buildIdToIdx = suiteHist.buildIdsMapping();
+
+        Set<Integer> indexesToKeep = suitesFiltered.buildIds().stream().map(buildIdToIdx::get).collect(Collectors.toSet());
+
+        SuiteHistory res = new SuiteHistory();
+
+        res.suiteHist = suitesFiltered;
+
+        testsInvStatues.forEach((tName, invList) -> {
+            byte[] buildsFiltered = new byte[indexesToKeep.size()];
+
+            int j = 0;
+            for (int i = 0; i < invList.length; i++) {
+                if (!indexesToKeep.contains(i))
+                    continue;
+
+                buildsFiltered[j] = invList[i];
+                j++;
+            }
+
+            res.testsInvStatues.put(tName, buildsFiltered);
+        });
+
+        return res;
+    }
+    @Override public IRunHistory self() {
+        return suiteHist;
+    }
+
+    private static class TestUltraCompactRunHist extends AbstractRunHist {
+        @Nonnull private final byte[] testInvStatuses;
+        @Nonnull private final RunHistCompacted suiteHist;
+
+        public TestUltraCompactRunHist(@Nonnull byte[] testInvStatuses, @Nonnull RunHistCompacted suiteHist) {
+            this.testInvStatuses = testInvStatuses;
+            this.suiteHist = suiteHist;
+
+            Preconditions.checkState(testInvStatuses.length == suiteHist.getInvocations().count());
+        }
+
+        /** {@inheritDoc} */
+        @Nullable @Override public List<Integer> getLatestRunResults() {
+            List<Integer> res = new ArrayList<>();
+            for (int i = 0; i < testInvStatuses.length; i++)
+                res.add((int)testInvStatuses[i]);
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int getCriticalFailuresCount() {
+            int res = 0;
+            for (int i = 0; i < testInvStatuses.length; i++) {
+                if (testInvStatuses[i] == InvocationData.CRITICAL_FAILURE)
+                    res++;
+            }
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int getRunsCount() {
+            int res = 0;
+            for (int i = 0; i < testInvStatuses.length; i++) {
+                byte status = testInvStatuses[i];
+                if (status != InvocationData.MISSING && !Invocation.isMutedOrIgnored(status))
+                    res++;
+            }
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int getFailuresCount() {
+            int res = 0;
+            for (int i = 0; i < testInvStatuses.length; i++) {
+                byte status = testInvStatuses[i];
+                if (status == InvocationData.FAILURE || status == InvocationData.CRITICAL_FAILURE)
+                    res++;
+            }
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Iterable<Invocation> invocations() {
+            return () -> new TestUltraCompactRunHistIterator(testInvStatuses, suiteHist);
+        }
+    }
+
+
+    private static class TestUltraCompactRunHistIterator implements Iterator<Invocation> {
+        /** Cur index: index of element to be returned in case next is called now. */
+        private int curIdx = 0;
+        @Nonnull private final byte[] testInvStatuses;
+        @Nonnull private final RunHistCompacted suiteHist;
+
+        public TestUltraCompactRunHistIterator(@Nonnull byte[] testInvStatuses,
+            @Nonnull RunHistCompacted suiteHist) {
+            this.testInvStatuses = testInvStatuses;
+            this.suiteHist = suiteHist;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean hasNext() {
+            return curIdx < testInvStatuses.length;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Invocation next() {
+            if (!hasNext())
+                throw new NoSuchElementException();
+
+            Invocation suiteInv = suiteHist.getInvocationAt(curIdx);
+
+            Invocation invocation = new Invocation(suiteInv.buildId())
+                .withChangeState(suiteInv.changesState())
+                .withStatus(testInvStatuses[curIdx]);
+
+            curIdx++;
+
+            return invocation;
+        }
+    }
+}


[ignite-teamcity-bot] 02/02: Version update

Posted by dp...@apache.org.
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

commit 41bb32842ecda17c4f4fb864aadd428ddae280d6
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Fri Aug 9 14:45:22 2019 +0300

    Version update
---
 .../src/main/java/org/apache/ignite/ci/web/model/Version.java           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 32536a9..46507c1 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 = "20190806";
+    public static final String VERSION = "20190809";
 
     /** Java version, where Web App is running. */
     public String javaVer;