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:29 UTC
[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.
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;
+ }
+ }
+}