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 2018/11/28 16:18:18 UTC

[ignite-teamcity-bot] branch ignite-9542-new-run-stripe updated: IGNITE-9542 Different branches in builds problem fixed for test run statistics

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

dpavlov pushed a commit to branch ignite-9542-new-run-stripe
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git


The following commit(s) were added to refs/heads/ignite-9542-new-run-stripe by this push:
     new 831a89d  IGNITE-9542 Different branches in builds problem fixed for test run statistics
831a89d is described below

commit 831a89dbf359e3b12664f877d492547945f34304
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Wed Nov 28 19:18:13 2018 +0300

    IGNITE-9542 Different branches in builds problem fixed for test run statistics
---
 .../main/java/org/apache/ignite/ci/ITeamcity.java  |  1 +
 .../apache/ignite/ci/IgnitePersistentTeamcity.java | 17 +++++++---
 .../org/apache/ignite/ci/issue/IssueDetector.java  |  7 +---
 .../ignite/ci/tcbot/chain/BuildChainProcessor.java | 20 +++--------
 .../ci/teamcity/ignited/ITeamcityIgnited.java      |  3 +-
 .../ci/teamcity/ignited/TeamcityIgnitedImpl.java   |  6 ++--
 .../ignited/runhist/RunHistCompactedDao.java       |  8 +++--
 .../ci/teamcity/ignited/runhist/RunHistSync.java   | 18 +++++++++-
 .../model/current/ChainAtServerCurrentStatus.java  | 11 +++++-
 .../ci/web/model/current/SuiteCurrentStatus.java   | 39 +++++++++++-----------
 .../ignite/ci/web/model/current/TestFailure.java   | 14 ++++----
 11 files changed, 82 insertions(+), 62 deletions(-)

diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITeamcity.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITeamcity.java
index 75868d1..e442eb7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITeamcity.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/ITeamcity.java
@@ -43,6 +43,7 @@ import java.util.concurrent.ExecutorService;
 public interface ITeamcity extends ITeamcityConn {
 
     String DEFAULT = "<default>";
+    String REFS_HEADS_MASTER = "refs/heads/master";
 
     @Deprecated
     long DEFAULT_BUILDS_COUNT = 1000;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
index 6a85ddf..f7b3950 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgnitePersistentTeamcity.java
@@ -57,7 +57,7 @@ import java.util.function.Predicate;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
-import static org.apache.ignite.ci.tcbot.chain.BuildChainProcessor.normalizeBranch;
+import static org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync.normalizeBranch;
 
 /**
  * Apache Ignite based cache over teamcity responses (REST caches).
@@ -69,6 +69,7 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea
     //V2 caches, 32 parts (V1 caches were 1024 parts)
     @Deprecated
     private static final String TESTS_RUN_STAT = "testsRunStat";
+    @Deprecated
     private static final String CALCULATED_STATISTIC = "calculatedStatistic";
     private static final String LOG_CHECK_RESULT = "logCheckResult";
 
@@ -318,7 +319,7 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea
     }
 
     @NotNull private SuiteInBranch keyForBuild(Build loaded) {
-        return new SuiteInBranch(loaded.suiteId(), normalizeBranch(loaded));
+        return new SuiteInBranch(loaded.suiteId(), normalizeBranch(loaded.branchName));
     }
 
     private Build realLoadBuild(String href1) {
@@ -360,7 +361,7 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea
             return;
 
         if (buildId != null && !Strings.isNullOrEmpty(suiteId)) {
-            SuiteInBranch key = new SuiteInBranch(suiteId, normalizeBranch(build));
+            SuiteInBranch key = new SuiteInBranch(suiteId, normalizeBranch(build.branchName));
 
             buildsFailureRunStatCache().invoke(key, (entry, arguments) -> {
                 SuiteInBranch suiteInBranch = entry.getKey();
@@ -408,10 +409,12 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea
             .map(Cache.Entry::getValue);
     }
 
+    @Deprecated
     private IgniteCache<TestInBranch, RunStat> testRunStatCache() {
         return getOrCreateCacheV2(ignCacheNme(TESTS_RUN_STAT));
     }
 
+    @Deprecated
     private IgniteCache<Integer, Boolean> calculatedStatistic() {
         return getOrCreateCacheV2(ignCacheNme(CALCULATED_STATISTIC));
     }
@@ -445,6 +448,7 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea
         return getOrCreateCacheV2(ignCacheNme(LOG_CHECK_RESULT));
     }
 
+    @Deprecated
     private void addTestOccurrenceToStat(TestOccurrence next, String normalizedBranch, Boolean changesExist) {
         String name = next.getName();
         if (Strings.isNullOrEmpty(name))
@@ -516,8 +520,11 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea
         if (calculatedStatistic().containsKey(ctx.buildId()))
             return;
 
-        for (TestOccurrence testOccurrence : ctx.getTests())
-            addTestOccurrenceToStat(testOccurrence, normalizeBranch(ctx.getBranch()), !ctx.getChanges().isEmpty());
+        for (TestOccurrence testOccurrence : ctx.getTests()) {
+            String branch = normalizeBranch(ctx.getBranch());
+
+            addTestOccurrenceToStat(testOccurrence, branch, !ctx.getChanges().isEmpty());
+        }
 
         calculatedStatistic().put(ctx.buildId(), true);
     }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
index b11c87c..fbe54eb 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueDetector.java
@@ -50,10 +50,6 @@ import org.apache.ignite.ci.di.MonitoredTask;
 import org.apache.ignite.ci.jobs.CheckQueueJob;
 import org.apache.ignite.ci.mail.EmailSender;
 import org.apache.ignite.ci.mail.SlackSender;
-import org.apache.ignite.ci.tcmodel.changes.Change;
-import org.apache.ignite.ci.tcmodel.changes.ChangeRef;
-import org.apache.ignite.ci.tcmodel.changes.ChangesList;
-import org.apache.ignite.ci.tcmodel.result.Build;
 import org.apache.ignite.ci.user.ICredentialsProv;
 import org.apache.ignite.ci.user.TcHelperUser;
 import org.apache.ignite.ci.user.UserAndSessionsStorage;
@@ -65,8 +61,7 @@ import org.apache.ignite.ci.web.rest.parms.FullQueryParams;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.apache.ignite.ci.tcbot.chain.BuildChainProcessor.normalizeBranch;
+import static org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync.normalizeBranch;
 
 /**
  *
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java
index 315cef7..a24340b 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/BuildChainProcessor.java
@@ -38,7 +38,6 @@ import java.util.stream.Stream;
 import javax.annotation.Nonnull;
 import javax.inject.Inject;
 import org.apache.ignite.ci.IAnalyticsEnabledTeamcity;
-import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.analysis.FullChainRunCtx;
 import org.apache.ignite.ci.analysis.MultBuildRunCtx;
 import org.apache.ignite.ci.analysis.RunStat;
@@ -54,6 +53,7 @@ import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
 import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
 import org.apache.ignite.ci.teamcity.ignited.SyncMode;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync;
 import org.apache.ignite.ci.util.FutureUtil;
 import org.apache.ignite.ci.web.TcUpdatePool;
 import org.apache.ignite.ci.web.model.long_running.LRTest;
@@ -209,7 +209,7 @@ public class BuildChainProcessor {
         });
 
         Function<MultBuildRunCtx, Float> function = ctx -> {
-            SuiteInBranch key = new SuiteInBranch(ctx.suiteId(), normalizeBranch(failRateBranch));
+            SuiteInBranch key = new SuiteInBranch(ctx.suiteId(), RunHistSync.normalizeBranch(failRateBranch));
 
             //todo place RunStat into suite context to compare
             RunStat runStat = teamcity.getBuildFailureRunStatProvider().apply(key);
@@ -346,10 +346,6 @@ public class BuildChainProcessor {
         throw new UnsupportedOperationException("invalid mode " + includeLatestRebuild);
     }
 
-    @NotNull private static String getBranchOrDefault(@Nullable String branchName) {
-        return branchName == null ? ITeamcity.DEFAULT : branchName;
-    }
-
     @SuppressWarnings("WeakerAccess")
     @AutoProfiling
     protected void fillBuildCounts(MultBuildRunCtx outCtx,
@@ -388,17 +384,9 @@ public class BuildChainProcessor {
         }
     }
 
+    @Deprecated
     @NotNull public static String normalizeBranch(@NotNull final BuildRef build) {
-        return normalizeBranch(build.branchName);
-    }
-
-    @NotNull public static String normalizeBranch(@Nullable String branchName) {
-        String branch = getBranchOrDefault(branchName);
-
-        if ("refs/heads/master".equals(branch))
-            return ITeamcity.DEFAULT;
-
-        return branch;
+        return RunHistSync.normalizeBranch(build.branchName);
     }
 
     /**
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
index f1f6bb2..ac1877b 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/ITeamcityIgnited.java
@@ -124,5 +124,6 @@ public interface ITeamcityIgnited {
      */
     @NotNull public List<Integer> getLastNBuildsFromHistory(String btId, String branchForTc, int cnt);
 
-    @Nullable IRunHistory getTestRunHist(TestInBranch testInBranch);
+    @Nullable
+    IRunHistory getTestRunHist(TestInBranch testInBranch);
 }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
index 4962f4c..2b61c54 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/TeamcityIgnitedImpl.java
@@ -318,14 +318,14 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
         return chains;
     }
 
-    @Override
-    public IRunHistory getTestRunHist(TestInBranch testInBranch) {
+    @Nullable
+    @Override public IRunHistory getTestRunHist(TestInBranch testInBranch) {
          return runHistCompactedDao.getTestRunHist(srvIdMaskHigh, testInBranch.name, testInBranch.branch);
     }
 
     public List<String> branchForQuery(@Nullable String branchName) {
         if (ITeamcity.DEFAULT.equals(branchName))
-            return Lists.newArrayList(branchName, "refs/heads/master", "master");
+            return Lists.newArrayList(branchName, ITeamcity.REFS_HEADS_MASTER, "master");
         else
             return Collections.singletonList(branchName);
     }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompactedDao.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompactedDao.java
index 612249a..8d4e333 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompactedDao.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompactedDao.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.ci.teamcity.ignited.runhist;
 
-import java.util.Iterator;
 import java.util.List;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
@@ -26,13 +25,14 @@ import org.apache.ignite.ci.db.TcHelperDb;
 import org.apache.ignite.ci.di.AutoProfiling;
 import org.apache.ignite.ci.teamcity.ignited.IRunHistory;
 import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
-import org.apache.ignite.ci.teamcity.ignited.fatbuild.TestCompacted;
 import org.apache.ignite.configuration.CacheConfiguration;
 
 import javax.inject.Inject;
 import javax.inject.Provider;
 import java.util.Collections;
 
+import static org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync.normalizeBranch;
+
 public class RunHistCompactedDao {
     /** Cache name.*/
     public static final String TEST_HIST_CACHE_NAME = "testRunHistV0";
@@ -73,7 +73,9 @@ public class RunHistCompactedDao {
         if (testName == null)
             return null;
 
-        final Integer branchId = compactor.getStringIdIfPresent(branch);
+        String normalizeBranch = normalizeBranch(branch);
+
+        final Integer branchId = compactor.getStringIdIfPresent(normalizeBranch);
         if (branchId == null)
             return null;
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistSync.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistSync.java
index ade23df..49f136e 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistSync.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistSync.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import javax.annotation.concurrent.GuardedBy;
 import javax.inject.Inject;
+import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.di.AutoProfiling;
 import org.apache.ignite.ci.di.MonitoredTask;
 import org.apache.ignite.ci.di.scheduler.IScheduler;
@@ -37,6 +38,7 @@ import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
 import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildDao;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,6 +70,18 @@ public class RunHistSync {
     @GuardedBy("this")
     private final Map<String, SyncTask> buildToSave = new HashMap<>();
 
+    @NotNull 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 ("master".equals(branch))
+            return ITeamcity.DEFAULT;
+
+        return branch;
+    }
+
     /**
      * @param srvVame Server id.
      * @param buildId Build id.
@@ -85,7 +99,9 @@ public class RunHistSync {
 
         Map<RunHistKey, List<Invocation>> data = new HashMap<>();
         build.getAllTests().forEach(t -> {
-            RunHistKey histKey = new RunHistKey(srvId, t.testName(), build.branchName());
+            int branchNameNormalized = compactor.getStringId(normalizeBranch(build.branchName(compactor)));
+
+            RunHistKey histKey = new RunHistKey(srvId, t.testName(), branchNameNormalized);
             List<Invocation> list = data.computeIfAbsent(histKey, k -> new ArrayList<>());
             Invocation inv = t.toInvocation(compactor, build);
             list.add(inv);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java
index 7dcff6d..ee05245 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/ChainAtServerCurrentStatus.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import org.apache.ignite.ci.ITcAnalytics;
@@ -29,6 +30,8 @@ import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.analysis.FullChainRunCtx;
 import org.apache.ignite.ci.analysis.IMultTestOccurrence;
 import org.apache.ignite.ci.analysis.MultBuildRunCtx;
+import org.apache.ignite.ci.analysis.TestInBranch;
+import org.apache.ignite.ci.teamcity.ignited.IRunHistory;
 import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
 import org.apache.ignite.ci.util.CollectionUtil;
 import org.apache.ignite.internal.util.typedef.T2;
@@ -132,7 +135,13 @@ public class ChainAtServerCurrentStatus {
                 MultBuildRunCtx suite = pairCtxAndOccur.get1();
                 IMultTestOccurrence longRunningOccur = pairCtxAndOccur.get2();
 
-                TestFailure failure = createOrrucForLongRun(tcIgnited, teamcity, suite, tcAnalytics, longRunningOccur, baseBranchTc);
+                Function<TestInBranch, ? extends IRunHistory> function = SuiteCurrentStatus.NEW_RUN_STAT
+                    ? tcIgnited::getTestRunHist
+                    : tcAnalytics.getTestRunStatProvider();
+
+                TestFailure failure = createOrrucForLongRun(tcIgnited, suite, tcAnalytics, longRunningOccur,
+                    baseBranchTc,
+                    function);
 
                 failure.testName = "[" + suite.suiteName() + "] " + failure.testName; //may be separate field
 
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java
index 3348e8d..d5f85db 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/SuiteCurrentStatus.java
@@ -44,7 +44,7 @@ import org.apache.ignite.ci.web.model.hist.FailureSummary;
 import org.apache.ignite.ci.web.rest.GetBuildLog;
 import org.jetbrains.annotations.NotNull;
 
-import static org.apache.ignite.ci.tcbot.chain.BuildChainProcessor.normalizeBranch;
+import static org.apache.ignite.ci.teamcity.ignited.runhist.RunHistSync.normalizeBranch;
 import static org.apache.ignite.ci.util.TimeUtil.millisToDurationPrintable;
 import static org.apache.ignite.ci.util.UrlUtil.escape;
 
@@ -132,8 +132,12 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
 
         name = suite.suiteName();
 
-        String failRateNormalizedBranch = normalizeBranch(baseBranch);
-        String curBranchNormalized = normalizeBranch(suite.branchName());
+        String failRateNormalizedBranch = NEW_RUN_STAT ? baseBranch : normalizeBranch(baseBranch);
+        String curBranchNormalized = NEW_RUN_STAT ? suite.branchName() : normalizeBranch(suite.branchName());
+
+        Function<TestInBranch, ? extends IRunHistory> testStatProv = NEW_RUN_STAT
+            ? tcIgnited::getTestRunHist
+            : tcAnalytics.getTestRunStatProvider();
 
         String suiteId = suite.suiteId();
         initSuiteStat(tcAnalytics, failRateNormalizedBranch, curBranchNormalized, suiteId);
@@ -152,11 +156,12 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
         webToHistBaseBranch = buildWebLink(teamcity, suite, baseBranch);
         webToBuild = buildWebLinkToBuild(teamcity, suite);
 
+
         List<IMultTestOccurrence> tests = suite.getFailedTests();
         Function<IMultTestOccurrence, Float> function = foccur -> {
             TestInBranch testInBranch = new TestInBranch(foccur.getName(), failRateNormalizedBranch);
 
-            IRunHistory apply = tcIgnited.getTestRunHist(testInBranch);
+            IRunHistory apply = testStatProv.apply(testInBranch);
 
             return apply == null ? 0f : apply.getFailRate();
         };
@@ -165,17 +170,15 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
 
         tests.forEach(occurrence -> {
             final TestFailure failure = new TestFailure();
-            failure.initFromOccurrence(occurrence, teamcity, suite.projectId(), suite.branchName(), baseBranch);
-            failure.initStat(
-                    NEW_RUN_STAT
-                            ? tcIgnited::getTestRunHist
-                            : tcAnalytics.getTestRunStatProvider(), failRateNormalizedBranch, curBranchNormalized);
+            failure.initFromOccurrence(occurrence, tcIgnited, suite.projectId(), suite.branchName(), baseBranch);
+            failure.initStat(testStatProv, failRateNormalizedBranch, curBranchNormalized);
 
             testFailures.add(failure);
         });
 
         suite.getTopLongRunning().forEach(occurrence -> {
-            final TestFailure failure = createOrrucForLongRun(tcIgnited, teamcity, suite, tcAnalytics, occurrence, baseBranch);
+            final TestFailure failure = createOrrucForLongRun(tcIgnited, suite, tcAnalytics,
+                occurrence, baseBranch, testStatProv);
 
             topLongRunning.add(failure);
         });
@@ -275,19 +278,17 @@ import static org.apache.ignite.ci.util.UrlUtil.escape;
     }
 
     @NotNull public static TestFailure createOrrucForLongRun(ITeamcityIgnited tcIgnited,
-                                                             @Nonnull ITeamcity teamcity,
-                                                             @Nonnull MultBuildRunCtx suite,
-                                                             @Nullable final ITcAnalytics tcAnalytics,
-                                                             final IMultTestOccurrence occurrence,
-                                                             @Nullable final String failRateBranch) {
+        @Nonnull MultBuildRunCtx suite,
+        @Nullable final ITcAnalytics tcAnalytics,
+        final IMultTestOccurrence occurrence,
+        @Nullable final String failRateBranch,
+        Function<TestInBranch, ? extends IRunHistory> supplier) {
         final TestFailure failure = new TestFailure();
 
-        failure.initFromOccurrence(occurrence, teamcity, suite.projectId(), suite.branchName(), failRateBranch);
+        failure.initFromOccurrence(occurrence, tcIgnited, suite.projectId(), suite.branchName(), failRateBranch);
 
         if (tcAnalytics != null) {
-            failure.initStat(NEW_RUN_STAT
-                            ? tcIgnited::getTestRunHist
-                            : tcAnalytics.getTestRunStatProvider(),
+            failure.initStat(supplier,
                 normalizeBranch(failRateBranch),
                 normalizeBranch(suite.branchName()));
         }
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java
index c8b67e0..e98e143 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/current/TestFailure.java
@@ -26,7 +26,6 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.apache.ignite.ci.ITeamcity;
 import org.apache.ignite.ci.analysis.IMultTestOccurrence;
 import org.apache.ignite.ci.analysis.RunStat;
 import org.apache.ignite.ci.analysis.TestInBranch;
@@ -34,6 +33,7 @@ import org.apache.ignite.ci.issue.EventTemplates;
 import org.apache.ignite.ci.issue.ProblemRef;
 import org.apache.ignite.ci.logs.LogMsgToWarn;
 import org.apache.ignite.ci.teamcity.ignited.IRunHistory;
+import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
 import org.apache.ignite.ci.web.model.hist.FailureSummary;
 import org.apache.ignite.ci.web.model.hist.TestHistory;
 import org.jetbrains.annotations.NotNull;
@@ -93,13 +93,13 @@ import static org.apache.ignite.ci.web.model.current.SuiteCurrentStatus.branchFo
 
     /**
      * @param failure
-     * @param teamcity
+     * @param tcIgn
      * @param projectId
      * @param branchName
      * @param baseBranchName base branch name (e.g. master).
      */
     public void initFromOccurrence(@Nonnull final IMultTestOccurrence failure,
-        @Nonnull final ITeamcity teamcity,
+        @Nonnull final ITeamcityIgnited tcIgn,
         @Nullable final String projectId,
         @Nullable final String branchName,
         @Nullable final String baseBranchName) {
@@ -138,11 +138,11 @@ import static org.apache.ignite.ci.web.model.current.SuiteCurrentStatus.branchFo
             }
             if (webUrl == null)
                 if (full.test != null && full.test.id != null)
-                    webUrl = buildWebLink(teamcity, full.test.id, projectId, branchName);
+                    webUrl = buildWebLink(tcIgn, full.test.id, projectId, branchName);
 
             if (webUrlBaseBranch == null)
                 if (full.test != null && full.test.id != null)
-                    webUrlBaseBranch = buildWebLink(teamcity, full.test.id, projectId, baseBranchName);
+                    webUrlBaseBranch = buildWebLink(tcIgn, full.test.id, projectId, baseBranchName);
         });
 
     }
@@ -174,12 +174,12 @@ import static org.apache.ignite.ci.web.model.current.SuiteCurrentStatus.branchFo
         }
     }
 
-    private static String buildWebLink(ITeamcity teamcity, Long id,
+    private static String buildWebLink(ITeamcityIgnited tcIgn, Long id,
         @Nullable String projectId, @Nullable String branchName) {
         if (projectId == null)
             return null;
         final String branch = branchForLink(branchName);
-        return teamcity.host() + "project.html"
+        return tcIgn.host() + "project.html"
             + "?projectId=" + projectId
             + "&testNameId=" + id
             + "&branch=" + escape(branch)