This is an automated email from the ASF dual-hosted git repository.
dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/master by this push:
new 460e5f8 IGNITE-10030 statistics done in prod: Background upload of
changes, problems, and statistics - Fixes #49.
460e5f8 is described below
commit 460e5f89add920612c884852ac6a24d821d749b3
Author: Dmitriy Pavlov <[email protected]>
AuthorDate: Sat Oct 27 20:14:58 2018 +0300
IGNITE-10030 statistics done in prod: Background upload of changes,
problems, and statistics - Fixes #49.
Signed-off-by: Dmitriy Pavlov <[email protected]>
---
.../main/java/org/apache/ignite/ci/ITeamcity.java | 23 +--
.../apache/ignite/ci/IgnitePersistentTeamcity.java | 70 +++------
.../apache/ignite/ci/IgniteTeamcityConnection.java | 49 +++----
.../apache/ignite/ci/analysis/FullChainRunCtx.java | 12 --
.../apache/ignite/ci/analysis/MultBuildRunCtx.java | 79 ++++------
.../ignite/ci/analysis/SingleBuildRunCtx.java | 37 ++---
.../java/org/apache/ignite/ci/db/DbMigrations.java | 27 ++--
.../ci/tcbot/builds/CompareBuildsService.java | 4 +-
.../ignite/ci/tcbot/chain/BuildChainProcessor.java | 12 +-
.../ignite/ci/tcmodel/conf/bt/Parameters.java | 5 +
.../apache/ignite/ci/tcmodel/conf/bt/Property.java | 4 +
.../tcmodel/result/problems/ProblemOccurrence.java | 8 +
.../ignite/ci/tcmodel/result/stat/Statistics.java | 8 +-
.../ci/teamcity/ignited/TeamcityIgnitedImpl.java | 4 +-
.../ignited/fatbuild/FatBuildCompacted.java | 57 ++++++-
.../ci/teamcity/ignited/fatbuild/FatBuildDao.java | 25 ++--
.../ignited/fatbuild/ProactiveFatBuildSync.java | 33 +++--
.../ignited/fatbuild/ProblemCompacted.java | 163 +++++++++++++++++++++
.../ignited/fatbuild/StatisticsCompacted.java | 101 +++++++++++++
.../teamcity/ignited/fatbuild/TestCompacted.java | 2 +-
.../ignite/ci/teamcity/pure/ITeamcityConn.java | 8 +-
.../ignited/IgnitedTcInMemoryIntegrationTest.java | 19 ++-
.../src/test/resources/problemList.xml | 20 +++
23 files changed, 534 insertions(+), 236 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 12446b9..dac1546 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
@@ -59,16 +59,6 @@ public interface ITeamcity extends ITeamcityConn {
CompletableFuture<List<BuildType>> getProjectSuites(String projectId);
-
- /**
- * @param projectId Suite ID (string without spaces).
- * @param branch Branch in TC identification.
- * @return List of builds in historical order, recent builds coming last.
- */
- default List<BuildRef> getFinishedBuilds(String projectId, String branch) {
- return getFinishedBuilds(projectId, branch, null, null, null);
- };
-
/**
* @param projectId suite ID (string without spaces).
* @param branch Branch name in TC identification.
@@ -77,6 +67,7 @@ public interface ITeamcity extends ITeamcityConn {
* @param sinceBuildId Some build ID in the past to to use as minimal
build to export.
* @return list of builds in historical order, recent builds coming last.
*/
+ @Deprecated
List<BuildRef> getFinishedBuilds(String projectId, String branch, Date
sinceDate, Date untilDate, Integer sinceBuildId);
/**
@@ -105,10 +96,6 @@ public interface ITeamcity extends ITeamcityConn {
/** */
@Deprecated
- CompletableFuture<List<BuildRef>> getRunningBuilds(@Nullable String
branch);
-
- /** */
- @Deprecated
CompletableFuture<List<BuildRef>> getQueuedBuilds(@Nullable String branch);
/**
@@ -118,6 +105,7 @@ public interface ITeamcity extends ITeamcityConn {
* @param untilDate Until date.
* @return List of build numbers in historical order in date interval,
recent builds coming last.
*/
+ @Deprecated
default int[] getBuildNumbersFromHistory(String projectId, String
branchNameForHist, Date sinceDate, Date untilDate) {
return getFinishedBuilds(projectId, branchNameForHist, sinceDate,
untilDate, null).stream().mapToInt(BuildRef::getId).toArray();
}
@@ -137,10 +125,7 @@ public interface ITeamcity extends ITeamcityConn {
return "app/rest/latest/builds/id:" + Integer.toString(id);
}
- /**
- * @param build
- * @return
- */
+ @Deprecated
ProblemOccurrences getProblems(BuildRef build);
@Deprecated
@@ -149,8 +134,6 @@ public interface ITeamcity extends ITeamcityConn {
@Deprecated
TestOccurrences getFailedTests(String href, int count, String
normalizedBranch);
- Statistics getBuildStatistics(String href);
-
@Deprecated
CompletableFuture<TestOccurrenceFull> getTestFull(String href);
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 3487566..043154c 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
@@ -106,7 +106,6 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
@Deprecated
private static final String TEST_FULL = "testFull";
private static final String BUILD_PROBLEMS = "buildProblems";
- private static final String BUILD_STATISTICS = "buildStatistics";
private static final String BUILD_HIST_FINISHED = "buildHistFinished";
private static final String BUILD_HIST_FINISHED_OR_FAILED =
"buildHistFinishedOrFailed";
public static final String BOT_DETECTED_ISSUES = "botDetectedIssues";
@@ -142,12 +141,6 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
/** cached loads of queued builds for branch. */
private ConcurrentMap<String, CompletableFuture<List<BuildRef>>>
queuedBuildsFuts = new ConcurrentHashMap<>();
- /** cached running builds for branch. */
- private ConcurrentMap<String, Expirable<List<BuildRef>>> runningBuilds =
new ConcurrentHashMap<>();
-
- /** cached loads of running builds for branch. */
- private ConcurrentMap<String, CompletableFuture<List<BuildRef>>>
runningBuildsFuts = new ConcurrentHashMap<>();
-
/** */
private ConcurrentMap<SuiteInBranch, Long> lastQueuedHistory = new
ConcurrentHashMap<>();
@@ -171,10 +164,8 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
buildsFailureRunStatCache(), testRunStatCache(),
testFullCache(),
buildProblemsCache(),
- buildStatisticsCache(),
buildHistCache(),
- buildHistIncFailedCache(),
- testRefsCache());
+ buildHistIncFailedCache());
}
@Override
@@ -255,12 +246,6 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
return getOrCreateCacheV2(ignCacheNme(BUILD_PROBLEMS));
}
- /**
- * @return Build {@link Statistics} instances cache, 32 parts.
- */
- private IgniteCache<String, Statistics> buildStatisticsCache() {
- return getOrCreateCacheV2(ignCacheNme(BUILD_STATISTICS));
- }
/**
@@ -667,20 +652,6 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
}
- /** {@inheritDoc} */
- @Override public CompletableFuture<List<BuildRef>> getRunningBuilds(String
branch) {
- int defaultSecs = 60;
- int secondsUseCached = getTriggerRelCacheValidSecs(defaultSecs);
-
- return loadAsyncIfAbsentOrExpired(
- runningBuilds,
- Strings.nullToEmpty(branch),
- runningBuildsFuts,
- teamcity::getRunningBuilds,
- secondsUseCached,
- secondsUseCached == defaultSecs);
- }
-
public static int getTriggerRelCacheValidSecs(int defaultSecs) {
long msSinceTrigger = System.currentTimeMillis() - lastTriggerMs;
long secondsSinceTrigger =
TimeUnit.MILLISECONDS.toSeconds(msSinceTrigger);
@@ -873,26 +844,6 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
/** {@inheritDoc} */
@AutoProfiling
- @Override public Statistics getBuildStatistics(String href) {
- return loadIfAbsent(buildStatisticsCache(),
- href,
- href1 -> {
- try {
- return teamcity.getBuildStatistics(href1);
- }
- catch (Exception e) {
- if (Throwables.getRootCause(e) instanceof
FileNotFoundException) {
- e.printStackTrace();
- return new Statistics();// save null result, because
persistence may refer to some unexistent build on TC
- }
- else
- throw e;
- }
- });
- }
-
- /** {@inheritDoc} */
- @AutoProfiling
@Override public CompletableFuture<TestOccurrenceFull> getTestFull(String
href) {
return CacheUpdateUtil.loadAsyncIfAbsent(
testFullCache(),
@@ -1142,6 +1093,9 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
/** {@inheritDoc} */
@AutoProfiling
@Override public void calculateBuildStatistic(SingleBuildRunCtx ctx) {
+ if (ctx.buildId() == null)
+ return;
+
if (calculatedStatistic().containsKey(ctx.buildId()))
return;
@@ -1191,12 +1145,22 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
/** {@inheritDoc} */
@AutoProfiling
- @Override public Build triggerBuild(String buildTypeId, String branchName,
boolean cleanRebuild, boolean queueAtTop) {
+ @Override public Build triggerBuild(String buildTypeId, @NotNull String
branchName, boolean cleanRebuild, boolean queueAtTop) {
lastTriggerMs = System.currentTimeMillis();
return teamcity.triggerBuild(buildTypeId, branchName, cleanRebuild,
queueAtTop);
}
+ @Override
+ public ProblemOccurrences getProblems(int buildId) {
+ return teamcity.getProblems(buildId);
+ }
+
+ @Override
+ public Statistics getStatistics(int buildId) {
+ return teamcity.getStatistics(buildId);
+ }
+
/** {@inheritDoc} */
@Override public void setAuthToken(String tok) {
teamcity.setAuthToken(tok);
@@ -1238,8 +1202,8 @@ public class IgnitePersistentTeamcity implements
IAnalyticsEnabledTeamcity, ITea
}
/** {@inheritDoc} */
- @Override public List<BuildRef> getBuildRefs(String fullUrl,
AtomicReference<String> nextPage) {
- return teamcity.getBuildRefs(fullUrl, nextPage);
+ @Override public List<BuildRef> getBuildRefsPage(String fullUrl,
AtomicReference<String> nextPage) {
+ return teamcity.getBuildRefsPage(fullUrl, nextPage);
}
/** {@inheritDoc} */
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java
index 12810df..9435540 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/IgniteTeamcityConnection.java
@@ -272,10 +272,10 @@ public class IgniteTeamcityConnection implements
ITeamcity {
/** {@inheritDoc} */
@AutoProfiling
@Override public Build triggerBuild(
- String buildTypeId,
- @Nonnull String branchName,
- boolean cleanRebuild,
- boolean queueAtTop
+ String buildTypeId,
+ @NotNull @Nonnull String branchName,
+ boolean cleanRebuild,
+ boolean queueAtTop
) {
String triggeringOptions =
" <triggeringOptions" +
@@ -317,6 +317,20 @@ public class IgniteTeamcityConnection implements ITeamcity
{
}
}
+ @Override
+ @AutoProfiling
+ public ProblemOccurrences getProblems(int buildId) {
+ return getJaxbUsingHref("app/rest/latest/problemOccurrences" +
+ "?locator=build:(id:" + buildId + ")" +
+
"&fields=problemOccurrence(id,type,identity,href,details,build(id))",
ProblemOccurrences.class);
+ }
+
+ @Override
+ @AutoProfiling
+ public Statistics getStatistics(int buildId) {
+ return getJaxbUsingHref("app/rest/latest/builds/id:" + buildId +
"/statistics", Statistics.class);
+ }
+
private CompletableFuture<List<File>> unzip(CompletableFuture<File>
zipFileFut) {
return zipFileFut.thenApplyAsync(ZipUtil::unZipToSameFolder, executor);
}
@@ -451,12 +465,6 @@ public class IgniteTeamcityConnection implements ITeamcity
{
/** {@inheritDoc} */
@AutoProfiling
- @Override public Statistics getBuildStatistics(String href) {
- return getJaxbUsingHref(href, Statistics.class);
- }
-
- /** {@inheritDoc} */
- @AutoProfiling
@Override public CompletableFuture<TestOccurrenceFull> getTestFull(String
href) {
return supplyAsync(() -> getJaxbUsingHref(href,
TestOccurrenceFull.class), executor);
}
@@ -512,13 +520,6 @@ public class IgniteTeamcityConnection implements ITeamcity
{
/** {@inheritDoc} */
@AutoProfiling
- @Override public List<BuildRef> getFinishedBuilds(String projectId, String
branch) {
-
- return getFinishedBuilds(projectId, branch, null, null, null);
- }
-
- /** {@inheritDoc} */
- @AutoProfiling
@Override public List<BuildRef> getFinishedBuilds(String projectId,
String branch,
Date sinceDate,
@@ -549,16 +550,11 @@ public class IgniteTeamcityConnection implements
ITeamcity {
/** {@inheritDoc} */
@Override
- @AutoProfiling public CompletableFuture<List<BuildRef>>
getRunningBuilds(@Nullable String branch) {
- return supplyAsync(() -> getBuildsInState(null, branch,
BuildRef.STATE_RUNNING), executor);
- }
-
- /** {@inheritDoc} */
- @Override
@AutoProfiling public CompletableFuture<List<BuildRef>>
getQueuedBuilds(@Nullable String branch) {
return supplyAsync(() -> getBuildsInState(null, branch,
BuildRef.STATE_QUEUED), executor);
}
+ @Deprecated
private List<BuildRef> getBuildsInState(
@Nullable final String projectId,
@Nullable final String branch,
@@ -577,6 +573,7 @@ public class IgniteTeamcityConnection implements ITeamcity {
@SuppressWarnings("WeakerAccess")
@AutoProfiling
+ @Deprecated
protected List<BuildRef> getBuildsInState(
@Nullable final String projectId,
@Nullable final String branch,
@@ -655,7 +652,7 @@ public class IgniteTeamcityConnection implements ITeamcity {
/** {@inheritDoc} */
@AutoProfiling
- @Override public List<BuildRef> getBuildRefs(String fullUrl,
AtomicReference<String> outNextPage) {
+ @Override public List<BuildRef> getBuildRefsPage(String fullUrl,
AtomicReference<String> outNextPage) {
String relPath = "app/rest/latest/builds?locator=defaultFilter:false";
String relPathSelected = Strings.isNullOrEmpty(fullUrl) ? relPath :
fullUrl;
String url = host + (relPathSelected.startsWith("/") ?
relPathSelected.substring(1) : relPathSelected);
@@ -678,10 +675,12 @@ public class IgniteTeamcityConnection implements
ITeamcity {
* @param buildId Build id.
* @param testDtls request test details string
*/
- @NotNull public String testsStartHref(int buildId, boolean testDtls) {
+ @NotNull
+ private String testsStartHref(int buildId, boolean testDtls) {
String fieldList = "id,name," +
(testDtls ? "details," : "") +
"status,duration,muted,currentlyMuted,currentlyInvestigated,ignored,test(id),build(id)";
+
return "app/rest/latest/testOccurrences?locator=build:(id:" +
buildId + ")" +
"&fields=testOccurrence(" + fieldList + ")";
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/FullChainRunCtx.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/FullChainRunCtx.java
index 0e04ccb..0d01506 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/FullChainRunCtx.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/FullChainRunCtx.java
@@ -40,18 +40,6 @@ public class FullChainRunCtx {
fakeStub = chainResults.isFakeStub();
}
- @Deprecated
- public int buildProblems() {
- return
(int)buildCfgsResults.stream().filter(MultBuildRunCtx::hasNontestBuildProblem).count();
- }
-
- public int timeoutsOomeCrashBuildProblems() {
- return (int)buildCfgsResults.stream().filter(context ->
- context.hasJvmCrashProblem()
- || context.hasTimeoutProblem()
- || context.hasOomeProblem()).count();
- }
-
public List<MultBuildRunCtx> suites() {
return buildCfgsResults;
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
index 0411fe2..c79ab3b 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/MultBuildRunCtx.java
@@ -17,36 +17,24 @@
package org.apache.ignite.ci.analysis;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
+import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
-import org.apache.ignite.ci.tcmodel.conf.BuildType;
+
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
-import org.apache.ignite.ci.tcmodel.result.Build;
-import org.apache.ignite.ci.tcmodel.result.TestOccurrencesRef;
import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
-import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrence;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull;
+import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.ProblemCompacted;
import org.apache.ignite.ci.util.CollectionUtil;
-import org.apache.ignite.ci.util.FutureUtil;
-import org.apache.ignite.ci.util.TimeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import static java.util.stream.Stream.concat;
-
/**
* Run configuration execution results loaded from different API URLs.
* Includes tests and problem occurrences; if logs processing is done also
contains last started test
@@ -55,6 +43,8 @@ public class MultBuildRunCtx implements ISuiteResults {
/** First build info. */
@Nonnull private final BuildRef firstBuildInfo;
+ private IStringCompactor compactor;
+
/** Builds: Single execution. */
private List<SingleBuildRunCtx> builds = new CopyOnWriteArrayList<>();
@@ -62,11 +52,6 @@ public class MultBuildRunCtx implements ISuiteResults {
@Deprecated
private final Map<String, MultTestFailureOccurrences> tests = new
ConcurrentSkipListMap<>();
- /**
- * Statistics for last build.
- */
- @Nullable private Statistics stat;
-
public void addBuild(SingleBuildRunCtx ctx) {
builds.add(ctx);
}
@@ -77,8 +62,9 @@ public class MultBuildRunCtx implements ISuiteResults {
/** Currently scheduled builds */
private Integer queuedBuildCount;
- public MultBuildRunCtx(@Nonnull final BuildRef buildInfo) {
+ public MultBuildRunCtx(@Nonnull final BuildRef buildInfo, IStringCompactor
compactor) {
this.firstBuildInfo = buildInfo;
+ this.compactor = compactor;
}
public Stream<String> getCriticalFailLastStartedTest() {
@@ -106,23 +92,13 @@ public class MultBuildRunCtx implements ISuiteResults {
return firstBuildInfo.buildTypeId;
}
-
- @Deprecated
- //currently used only in old metrics
- public boolean hasNontestBuildProblem() {
- return allProblemsInAllBuilds().anyMatch(problem ->
- !problem.isFailedTests()
- && !problem.isSnapshotDepProblem()
- &&
!ProblemOccurrence.BUILD_FAILURE_ON_MESSAGE.equals(problem.type));
- //todo what to do with BuildFailureOnMessage, now it is ignored
- }
-
public boolean hasAnyBuildProblemExceptTestOrSnapshot() {
return allProblemsInAllBuilds()
- .anyMatch(p -> !p.isFailedTests() && !p.isSnapshotDepProblem());
+ .anyMatch(p -> !p.isFailedTests(compactor) &&
!p.isSnapshotDepProblem(compactor));
}
- @NotNull public Stream<ProblemOccurrence> allProblemsInAllBuilds() {
+ @NotNull
+ private Stream<ProblemCompacted> allProblemsInAllBuilds() {
return buildsStream().flatMap(SingleBuildRunCtx::getProblemsStream);
}
@@ -184,21 +160,21 @@ public class MultBuildRunCtx implements ISuiteResults {
addKnownProblemCnt(res, "Exit Code", getExitCodeProblemsCount());
{
- Stream<ProblemOccurrence> stream =
+ Stream<ProblemCompacted> stream =
allProblemsInAllBuilds().filter(p ->
- !p.isFailedTests()
- && !p.isSnapshotDepProblem()
- && !p.isExecutionTimeout()
- && !p.isJvmCrash()
- && !p.isExitCode()
- && !p.isJavaLevelDeadlock()
- && !p.isOome());
- Optional<ProblemOccurrence> bpOpt = stream.findAny();
+ !p.isFailedTests(compactor)
+ && !p.isSnapshotDepProblem(compactor)
+ && !p.isExecutionTimeout(compactor)
+ && !p.isJvmCrash(compactor)
+ && !p.isExitCode(compactor)
+ //&& !p.isJavaLevelDeadlock(compactor)
+ && !p.isOome(compactor));
+ Optional<ProblemCompacted> bpOpt = stream.findAny();
if (bpOpt.isPresent()) {
if (res.length() > 0)
res.append(", ");
- res.append(bpOpt.get().type).append(" ");
+ res.append(bpOpt.get().type(compactor)).append(" ");
}
}
@@ -279,16 +255,19 @@ public class MultBuildRunCtx implements ISuiteResults {
return firstBuildInfo.branchName;
}
- public void setStat(@Nullable Statistics stat) {
- this.stat = stat;
- }
-
/**
* @return last build duration.
*/
@Nullable
public Long getBuildDuration() {
- return stat == null ? null : stat.getBuildDuration();
+ final OptionalDouble average = buildsStream()
+ .mapToLong(SingleBuildRunCtx::getBuildDuration)
+ .filter(Objects::nonNull)
+ .average();
+ if(average.isPresent())
+ return (long) average.getAsDouble();
+
+ return null;
}
@Nullable public String suiteName() {
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/SingleBuildRunCtx.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/SingleBuildRunCtx.java
index f34a53d..a471a8a 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/SingleBuildRunCtx.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/analysis/SingleBuildRunCtx.java
@@ -26,12 +26,10 @@ import java.util.concurrent.Future;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import org.apache.ignite.ci.tcmodel.changes.Change;
-import org.apache.ignite.ci.tcmodel.result.Build;
-import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
-import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrence;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull;
import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.ProblemCompacted;
import org.apache.ignite.ci.util.FutureUtil;
import org.jetbrains.annotations.Nullable;
@@ -41,26 +39,22 @@ import org.jetbrains.annotations.Nullable;
public class SingleBuildRunCtx implements ISuiteResults {
/** Build compacted. */
private FatBuildCompacted buildCompacted;
+
/** Compactor. */
private IStringCompactor compactor;
/** Logger check result future. */
private CompletableFuture<LogCheckResult> logCheckResFut;
- /** Build problems occurred during single build run. */
- @Nullable private List<ProblemOccurrence> problems;
-
/** Changes. */
private List<Change> changes = new ArrayList<>();
/**
- * @param build Build.
* @param buildCompacted Build compacted.
* @param compactor Compactor.
*/
- public SingleBuildRunCtx(Build build,
- FatBuildCompacted buildCompacted,
- IStringCompactor compactor) {
+ public SingleBuildRunCtx(FatBuildCompacted buildCompacted,
+ IStringCompactor compactor) {
this.buildCompacted = buildCompacted;
this.compactor = compactor;
}
@@ -78,26 +72,23 @@ public class SingleBuildRunCtx implements ISuiteResults {
}
private long getExecutionTimeoutCount() {
- return
getProblemsStream().filter(ProblemOccurrence::isExecutionTimeout).count();
+ return getProblemsStream().filter(p ->
p.isExecutionTimeout(compactor)).count();
}
- Stream<ProblemOccurrence> getProblemsStream() {
- if (problems == null)
- return Stream.empty();
-
- return problems.stream().filter(Objects::nonNull);
+ Stream<ProblemCompacted> getProblemsStream() {
+ return buildCompacted.problems().stream();
}
@Override public boolean hasJvmCrashProblem() {
- return getProblemsStream().anyMatch(ProblemOccurrence::isJvmCrash);
+ return getProblemsStream().anyMatch(p -> p.isJvmCrash(compactor));
}
@Override public boolean hasOomeProblem() {
- return getProblemsStream().anyMatch(ProblemOccurrence::isOome);
+ return getProblemsStream().anyMatch(p -> p.isOome(compactor));
}
@Override public boolean hasExitCodeProblem() {
- return getProblemsStream().anyMatch(ProblemOccurrence::isExitCode);
+ return getProblemsStream().anyMatch(p -> p.isExitCode(compactor));
}
@Override public String suiteId() {
@@ -149,10 +140,6 @@ public class SingleBuildRunCtx implements ISuiteResults {
return logCheckRes;
}
- public void setProblems(@Nullable List<ProblemOccurrence> problems) {
- this.problems = problems;
- }
-
public void addChange(Change change) {
if (change.isFakeStub())
return;
@@ -206,4 +193,8 @@ public class SingleBuildRunCtx implements ISuiteResults {
public String projectId() {
return buildCompacted.projectId(compactor);
}
+
+ public Long getBuildDuration() {
+ return buildCompacted.buildDuration(compactor);
+ }
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
index 8b06abb..6441ab1 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/DbMigrations.java
@@ -42,7 +42,6 @@ import
org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrences;
import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrences;
-import org.apache.ignite.ci.tcmodel.result.tests.TestRef;
import org.apache.ignite.ci.web.rest.build.GetBuildTestFailures;
import org.apache.ignite.ci.web.rest.pr.GetPrTestFailures;
import org.apache.ignite.ci.web.rest.tracked.GetTrackedBranchTestResults;
@@ -64,6 +63,9 @@ public class DbMigrations {
public static final String TESTS = "tests";
@Deprecated
private static final String BUILD_RESULTS = "buildResults";
+
+ private static final String BUILD_STATISTICS = "buildStatistics";
+
public static final String TESTS_COUNT_7700 = ",count:7700";
//V1 caches, 1024 parts
@@ -108,17 +110,15 @@ public class DbMigrations {
}
public void dataMigration(
- IgniteCache<String, TestOccurrences> testOccurrencesCache,
Consumer<TestOccurrences> saveTestToStat,
- Consumer<TestOccurrences> saveTestToLatest,
- Cache<String, Build> buildCache, Consumer<Build> saveBuildToStat,
- IgniteCache<SuiteInBranch, RunStat> suiteHistCache,
- IgniteCache<TestInBranch, RunStat> testHistCache,
- Cache<String, TestOccurrenceFull> testFullCache,
- Cache<String, ProblemOccurrences> problemsCache,
- Cache<String, Statistics> buildStatCache,
- Cache<SuiteInBranch, Expirable<List<BuildRef>>> buildHistCache,
- Cache<SuiteInBranch, Expirable<List<BuildRef>>> buildHistInFailedCache,
- Cache<String, TestRef> testRefsCache) {
+ IgniteCache<String, TestOccurrences> testOccurrencesCache,
Consumer<TestOccurrences> saveTestToStat,
+ Consumer<TestOccurrences> saveTestToLatest,
+ Cache<String, Build> buildCache, Consumer<Build> saveBuildToStat,
+ IgniteCache<SuiteInBranch, RunStat> suiteHistCache,
+ IgniteCache<TestInBranch, RunStat> testHistCache,
+ Cache<String, TestOccurrenceFull> testFullCache,
+ Cache<String, ProblemOccurrences> problemsCache,
+ Cache<SuiteInBranch, Expirable<List<BuildRef>>> buildHistCache,
+ Cache<SuiteInBranch, Expirable<List<BuildRef>>>
buildHistInFailedCache) {
doneMigrations = doneMigrationsCache();
@@ -346,7 +346,6 @@ public class DbMigrations {
}
});
applyV1toV2Migration(PROBLEMS, problemsCache);
- applyV1toV2Migration(STAT, buildStatCache);
applyV1toV2Migration(FINISHED_BUILDS, buildHistCache);
applyV1toV2Migration(FINISHED_BUILDS_INCLUDE_FAILED,
buildHistInFailedCache);
@@ -407,6 +406,8 @@ public class DbMigrations {
applyDestroyCacheMigration(TEAMCITY_BUILD_CACHE_NAME_OLD,
TEAMCITY_BUILD_CACHE_NAME_OLD);
applyDestroyIgnCacheMigration(TESTS);
+ applyDestroyIgnCacheMigration(STAT);
+ applyDestroyIgnCacheMigration(BUILD_STATISTICS);
}
private void applyDestroyIgnCacheMigration(String cacheName) {
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
index b383dc5..da17398 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/builds/CompareBuildsService.java
@@ -26,6 +26,7 @@ import org.apache.ignite.ci.analysis.MultBuildRunCtx;
import org.apache.ignite.ci.tcbot.chain.BuildChainProcessor;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
import org.apache.ignite.ci.tcmodel.result.Build;
+import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited;
import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnitedProvider;
import org.apache.ignite.ci.teamcity.restcached.ITcServerProvider;
@@ -41,6 +42,7 @@ public class CompareBuildsService {
@Inject ICredentialsProv prov;
@Inject BuildChainProcessor bcp;
@Inject ITeamcityIgnitedProvider tcIgnitedProv;
+ @Inject IStringCompactor compactor;
public List<String> tests0(String srvId, Integer buildId ) {
IAnalyticsEnabledTeamcity teamcity = helper.server(srvId, prov);
@@ -74,7 +76,7 @@ public class CompareBuildsService {
else {
logger.info("Loading tests for build {}.", build.getId());
- MultBuildRunCtx buildCtx = new MultBuildRunCtx(build);
+ MultBuildRunCtx buildCtx = new MultBuildRunCtx(build, compactor);
buildCtx.addBuild(bcp.loadTestsAndProblems(tc, build, buildCtx,
server));
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 cb7a886..8318fa1 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
@@ -23,7 +23,6 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@@ -158,7 +157,8 @@ public class BuildChainProcessor {
ITeamcityIgnited teamcityIgnited, Map<String, MultBuildRunCtx>
buildsCtxMap,
Stream<? extends BuildRef> list) {
list.forEach((BuildRef ref) -> {
- MultBuildRunCtx ctx =
buildsCtxMap.computeIfAbsent(ref.buildTypeId, k -> new MultBuildRunCtx(ref));
+ MultBuildRunCtx ctx = buildsCtxMap.computeIfAbsent(ref.buildTypeId,
+ k -> new MultBuildRunCtx(ref, compactor));
ctx.addBuild(loadTestsAndProblems(teamcity, ref, ctx,
teamcityIgnited));
});
@@ -177,9 +177,8 @@ public class BuildChainProcessor {
@Deprecated MultBuildRunCtx mCtx, ITeamcityIgnited tcIgnited) {
FatBuildCompacted buildCompacted =
tcIgnited.getFatBuild(buildRef.getId());
- Build buildFromFat = buildCompacted.toBuild(compactor);
- SingleBuildRunCtx ctx = new SingleBuildRunCtx(buildFromFat,
buildCompacted, compactor);
+ SingleBuildRunCtx ctx = new SingleBuildRunCtx(buildCompacted,
compactor);
if (!buildCompacted.isComposite())
mCtx.addTests(buildCompacted.getTestOcurrences(compactor).getTests());
@@ -190,8 +189,6 @@ public class BuildChainProcessor {
if (build == null || build.isFakeStub())
return ctx;
- if (build.problemOccurrences != null)
- ctx.setProblems(teamcity.getProblems(build).getProblemsNonNull());
if (build.lastChanges != null) {
for (ChangeRef next : build.lastChanges.changes) {
@@ -215,9 +212,6 @@ public class BuildChainProcessor {
}
}
- if (build.statisticsRef != null)
-
mCtx.setStat(teamcity.getBuildStatistics(build.statisticsRef.href));
-
return ctx;
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Parameters.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Parameters.java
index 3f9393a..b0980a7 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Parameters.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Parameters.java
@@ -19,6 +19,7 @@ package org.apache.ignite.ci.tcmodel.conf.bt;
import org.jetbrains.annotations.Nullable;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -42,4 +43,8 @@ public class Parameters {
Objects.equals(property.name, key)).findAny();
return any.map(Property::getValue).orElse(null);
}
+
+ public List<Property> properties() {
+ return Collections.unmodifiableList(this.properties);
+ }
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Property.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Property.java
index 107cfed..a3ee651 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Property.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/conf/bt/Property.java
@@ -36,4 +36,8 @@ public class Property {
public String getValue() {
return value;
}
+
+ public String name() {
+ return name;
+ }
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/problems/ProblemOccurrence.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/problems/ProblemOccurrence.java
index 72433f4..efbd438 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/problems/ProblemOccurrence.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/problems/ProblemOccurrence.java
@@ -77,4 +77,12 @@ public class ProblemOccurrence {
public boolean isJavaLevelDeadlock() {
return JAVA_LEVEL_DEADLOCK.equals(type);
}
+
+ public String id() {
+ return id;
+ }
+
+ public void id(String fullStrId) {
+ this.id = fullStrId;
+ }
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/stat/Statistics.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/stat/Statistics.java
index 1a72247..2bbe6fb 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/stat/Statistics.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcmodel/result/stat/Statistics.java
@@ -29,11 +29,14 @@ import org.jetbrains.annotations.Nullable;
@XmlRootElement(name = "properties")
@XmlAccessorType(XmlAccessType.FIELD)
public class Statistics extends Parameters {
+ public static final String BUILD_DURATION = "BuildDuration";
+ public static final String BUILD_STAGE_DURATION_SOURCES_UPDATE =
"buildStageDuration:sourcesUpdate";
+
/**
* @return build duration in millis or null.
*/
@Nullable public Long getBuildDuration() {
- String duration = getParameter("BuildDuration");
+ String duration = getParameter(BUILD_DURATION);
if (duration == null)
return null;
@@ -44,11 +47,12 @@ public class Statistics extends Parameters {
* @return source update duration in millis.
*/
@Nullable public Long getSourceUpdateDuration() {
- String duration = getParameter( "buildStageDuration:sourcesUpdate");
+ String duration = getParameter(BUILD_STAGE_DURATION_SOURCES_UPDATE);
if (duration == null)
return null;
return Long.parseLong(duration);
}
+
}
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 5603b44..1762693 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
@@ -211,7 +211,7 @@ public class TeamcityIgnitedImpl implements
ITeamcityIgnited {
protected String runActualizeBuildRefs(String srvId, boolean fullReindex,
@Nullable Set<Integer>
mandatoryToReload) {
AtomicReference<String> outLinkNext = new AtomicReference<>();
- List<BuildRef> tcDataFirstPage = conn.getBuildRefs(null, outLinkNext);
+ List<BuildRef> tcDataFirstPage = conn.getBuildRefsPage(null,
outLinkNext);
Set<Long> buildsUpdated = buildRefDao.saveChunk(srvIdMaskHigh,
tcDataFirstPage);
int totalUpdated = buildsUpdated.size();
@@ -228,7 +228,7 @@ public class TeamcityIgnitedImpl implements
ITeamcityIgnited {
while (outLinkNext.get() != null) {
String nextPageUrl = outLinkNext.get();
outLinkNext.set(null);
- List<BuildRef> tcDataNextPage = conn.getBuildRefs(nextPageUrl,
outLinkNext);
+ List<BuildRef> tcDataNextPage = conn.getBuildRefsPage(nextPageUrl,
outLinkNext);
Set<Long> curChunkBuildsSaved =
buildRefDao.saveChunk(srvIdMaskHigh, tcDataNextPage);
totalUpdated += curChunkBuildsSaved.size();
buildSync.scheduleBuildsLoad(conn,
cacheKeysToBuildIds(curChunkBuildsSaved));
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
index 231ed5d..bbbeb9f 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildCompacted.java
@@ -19,7 +19,9 @@ package org.apache.ignite.ci.teamcity.ignited.fatbuild;
import com.google.common.base.Objects;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.ignite.ci.analysis.IVersionedEntity;
import org.apache.ignite.ci.db.Persisted;
@@ -27,10 +29,13 @@ import org.apache.ignite.ci.tcmodel.conf.BuildType;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
import org.apache.ignite.ci.tcmodel.result.Build;
import org.apache.ignite.ci.tcmodel.result.TestOccurrencesRef;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
+import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -39,7 +44,7 @@ import org.jetbrains.annotations.Nullable;
@Persisted
public class FatBuildCompacted extends BuildRefCompacted implements
IVersionedEntity {
/** Latest version. */
- private static final int LATEST_VERSION = 2;
+ private static final int LATEST_VERSION = 4;
/** Default branch flag offset. */
public static final int DEF_BR_F = 0;
@@ -74,6 +79,10 @@ public class FatBuildCompacted extends BuildRefCompacted
implements IVersionedEn
private BitSet flags = new BitSet();
+ @Nullable private List<ProblemCompacted> problems;
+
+ @Nullable private StatisticsCompacted statistics;
+
/** {@inheritDoc} */
@Override public int version() {
return _ver;
@@ -101,7 +110,6 @@ public class FatBuildCompacted extends BuildRefCompacted
implements IVersionedEn
finishDate = build.getFinishDate() == null ? -1L :
build.getFinishDate().getTime();
queuedDate = build.getQueuedDate() == null ? -1L :
build.getQueuedDate().getTime();
-
BuildType type = build.getBuildType();
if (type != null) {
projectId = compactor.getStringId(type.getProjectId());
@@ -194,7 +202,6 @@ public class FatBuildCompacted extends BuildRefCompacted
implements IVersionedEn
}
}
-
/**
* @param off Offset.
* @param val Value.
@@ -257,12 +264,15 @@ public class FatBuildCompacted extends BuildRefCompacted
implements IVersionedEn
name == that.name &&
Objects.equal(tests, that.tests) &&
Objects.equal(snapshotDeps, that.snapshotDeps) &&
- Objects.equal(flags, that.flags);
+ Objects.equal(flags, that.flags) &&
+ Objects.equal(problems, that.problems) &&
+ Objects.equal(statistics, that.statistics);
}
/** {@inheritDoc} */
@Override public int hashCode() {
- return Objects.hashCode(super.hashCode(), _ver, startDate, finishDate,
queuedDate, projectId, name, tests, snapshotDeps, flags);
+ return Objects.hashCode(super.hashCode(), _ver, startDate, finishDate,
queuedDate, projectId, name, tests,
+ snapshotDeps, flags, problems, statistics);
}
/**
@@ -297,4 +307,41 @@ public class FatBuildCompacted extends BuildRefCompacted
implements IVersionedEn
public String projectId(IStringCompactor compactor) {
return compactor.getStringFromId(projectId);
}
+
+ public List<ProblemOccurrence> problems(IStringCompactor compactor) {
+ if (this.problems == null)
+ return Collections.emptyList();
+
+ return this.problems.stream()
+ .map(pc -> pc.toProblemOccurrence(compactor, id()))
+ .collect(Collectors.toList());
+ }
+
+ public List<ProblemCompacted> problems() {
+ if (this.problems == null)
+ return Collections.emptyList();
+
+ return Collections.unmodifiableList(this.problems);
+ }
+
+ public void addProblems(IStringCompactor compactor,
+ @NotNull List<ProblemOccurrence> occurrences) {
+ if (occurrences.isEmpty())
+ return;
+
+ if (this.problems == null)
+ this.problems = new ArrayList<>();
+
+ occurrences.stream()
+ .map(p -> new ProblemCompacted(compactor, p))
+ .forEach(this.problems::add);
+ }
+
+ public Long buildDuration(IStringCompactor compactor) {
+ return statistics == null ? null : statistics.buildDuration(compactor);
+ }
+
+ public void statistics(IStringCompactor compactor, Statistics statistics) {
+ this.statistics = new StatisticsCompacted(compactor, statistics);
+ }
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
index afe4812..da8c789 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/FatBuildDao.java
@@ -24,20 +24,17 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-import javax.cache.Cache;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.validation.constraints.NotNull;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.ci.db.TcHelperDb;
-import org.apache.ignite.ci.di.AutoProfiling;
import org.apache.ignite.ci.tcmodel.result.Build;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
+import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
-import org.apache.ignite.ci.teamcity.ignited.BuildRefDao;
import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
-import org.apache.ignite.internal.util.GridIntList;
import org.jetbrains.annotations.Nullable;
/**
@@ -68,14 +65,18 @@ public class FatBuildDao {
* @param buildId
* @param build Build data.
* @param tests TestOccurrences one or several pages.
+ * @param problems
+ * @param statistics
* @param existingBuild existing version of build in the DB.
* @return Fat Build saved (if modifications detected), otherwise null.
*/
public FatBuildCompacted saveBuild(long srvIdMaskHigh,
- int buildId,
- @NotNull Build build,
- List<TestOccurrencesFull> tests,
- @Nullable FatBuildCompacted existingBuild) {
+ int buildId,
+ @NotNull Build build,
+ @NotNull List<TestOccurrencesFull>
tests,
+ @Nullable List<ProblemOccurrence>
problems,
+ @Nullable Statistics statistics,
+ @Nullable FatBuildCompacted
existingBuild) {
Preconditions.checkNotNull(buildsCache, "init() was not called");
Preconditions.checkNotNull(build, "build can't be null");
@@ -84,6 +85,12 @@ public class FatBuildDao {
for (TestOccurrencesFull next : tests)
newBuild.addTests(compactor, next.getTests());
+ if (problems != null)
+ newBuild.addProblems(compactor, problems);
+
+ if (statistics != null)
+ newBuild.statistics(compactor, statistics);
+
if (existingBuild == null || !existingBuild.equals(newBuild)) {
buildsCache.put(buildIdToCacheKey(srvIdMaskHigh, buildId),
newBuild);
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
index 8eac870..a99463d 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProactiveFatBuildSync.java
@@ -22,6 +22,8 @@ import org.apache.ignite.ci.di.AutoProfiling;
import org.apache.ignite.ci.di.MonitoredTask;
import org.apache.ignite.ci.di.scheduler.IScheduler;
import org.apache.ignite.ci.tcmodel.result.Build;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
+import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
import org.apache.ignite.ci.teamcity.ignited.BuildRefDao;
import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
@@ -213,18 +215,28 @@ public class ProactiveFatBuildSync {
Build build;
List<TestOccurrencesFull> tests = new ArrayList<>();
+ List<ProblemOccurrence> problems = null;
+ Statistics statistics = null;
try {
build = conn.getBuild(buildId);
- String nextHref = null;
- do {
- boolean testDtls = !build.isComposite(); // don't query test
details for compoite
- TestOccurrencesFull page = conn.getTestsPage(buildId,
nextHref, testDtls);
- nextHref = page.nextHref();
+ if(build.testOccurrences!=null) {
+ String nextHref = null;
+ do {
+ boolean testDtls = !build.isComposite(); // don't query
test details for compoite
+ TestOccurrencesFull page = conn.getTestsPage(buildId,
nextHref, testDtls);
+ nextHref = page.nextHref();
- tests.add(page);
+ tests.add(page);
+ }
+ while (!Strings.isNullOrEmpty(nextHref));
}
- while (!Strings.isNullOrEmpty(nextHref));
+
+ if (build.problemOccurrences != null)
+ problems = conn.getProblems(buildId).getProblemsNonNull();
+
+ if(build.statisticsRef!=null)
+ statistics = conn.getStatistics(buildId);
}
catch (Exception e) {
if (Throwables.getRootCause(e) instanceof FileNotFoundException) {
@@ -237,9 +249,12 @@ public class ProactiveFatBuildSync {
build.setCancelled();
tests =
Collections.singletonList(existingBuild.getTestOcurrences(compactor));
+
+ problems = existingBuild.problems(compactor);
}
- else
+ else {
build = Build.createFakeStub();
+ }
} else {
logger.error("Loading build [" + buildId + "] for server [" +
srvNme + "] failed:" + e.getMessage(), e);
@@ -251,6 +266,6 @@ public class ProactiveFatBuildSync {
//if we are here because of some sort of outdated version of build,
// new save will be performed with new entity version for compacted
build
- return fatBuildDao.saveBuild(srvIdMask, buildId, build, tests,
existingBuild);
+ return fatBuildDao.saveBuild(srvIdMask, buildId, build, tests,
problems, statistics, existingBuild);
}
}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProblemCompacted.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProblemCompacted.java
new file mode 100644
index 0000000..961dbe8
--- /dev/null
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/ProblemCompacted.java
@@ -0,0 +1,163 @@
+/*
+ * 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.ci.teamcity.ignited.fatbuild;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+import org.apache.ignite.ci.analysis.RunStat;
+import org.apache.ignite.ci.tcmodel.hist.BuildRef;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
+import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrence;
+import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrenceFull;
+import org.apache.ignite.ci.tcmodel.result.tests.TestRef;
+import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xerial.snappy.Snappy;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.BitSet;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import static org.apache.ignite.ci.analysis.RunStat.extractIdPrefixed;
+
+/**
+ *
+ */
+public class ProblemCompacted {
+ /** Logger. */
+ private static final Logger logger =
LoggerFactory.getLogger(ProblemCompacted.class);
+
+ /** Id */
+ private int id = -1;
+ private int type = -1;
+ private int identity = -1;
+
+ /** Actual build id. */
+ private int actualBuildId = -1;
+
+ // later details may be needed @Nullable private byte[] details;
+
+ /**
+ * Default constructor.
+ */
+ public ProblemCompacted() {
+ }
+
+ /**
+ * @param compactor Compactor.
+ * @param problemOccurrence TestOccurrence.
+ */
+ public ProblemCompacted(IStringCompactor compactor, ProblemOccurrence
problemOccurrence) {
+ String problemIdStr = problemOccurrence.id();
+ if (!Strings.isNullOrEmpty(problemIdStr)) {
+ try {
+ final Integer problemId = extractIdPrefixed(problemIdStr,
"problem:(id:", ")");
+ if (problemId != null)
+ id = problemId;
+ } catch (Exception e) {
+ logger.error("Failed to handle TC response: " + problemIdStr,
e);
+ }
+ }
+
+ type = compactor.getStringId(problemOccurrence.type);
+ identity = compactor.getStringId(problemOccurrence.identity);
+
+
+ if (problemOccurrence.buildRef != null &&
problemOccurrence.buildRef.getId() != null)
+ actualBuildId = problemOccurrence.buildRef.getId();
+
+ }
+
+
+ public ProblemOccurrence toProblemOccurrence(IStringCompactor compactor,
int buildId) {
+ ProblemOccurrence occurrence = new ProblemOccurrence();
+
+ String fullStrId =
+ "problem:(id:" + id + ")," +
+ " build:(id:" + buildId + ")";
+ occurrence.id(fullStrId);
+ occurrence.type = compactor.getStringFromId(type);
+ occurrence.identity = compactor.getStringFromId(identity);
+ occurrence.href = "problemOccurrences?locator=" + fullStrId;
+
+ if (actualBuildId > 0) {
+ BuildRef buildRef = new BuildRef();
+
+ buildRef.setId(actualBuildId);
+
+ occurrence.buildRef = buildRef;
+ }
+
+ return occurrence;
+ }
+
+ private int id() {
+ return id;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ProblemCompacted that = (ProblemCompacted) o;
+ return id == that.id &&
+ type == that.type &&
+ identity == that.identity &&
+ actualBuildId == that.actualBuildId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(id, type, identity, actualBuildId);
+ }
+
+ public boolean isExecutionTimeout(IStringCompactor compactor) {
+ return compactor.getStringId(ProblemOccurrence.TC_EXECUTION_TIMEOUT)
== type;
+ }
+
+ public String type(IStringCompactor compactor) {
+ return compactor.getStringFromId(type);
+ }
+
+ public boolean isJvmCrash(IStringCompactor compactor) {
+ return compactor.getStringId(ProblemOccurrence.TC_JVM_CRASH) == type;
+ }
+
+ public boolean isOome(IStringCompactor compactor) {
+ return compactor.getStringId(ProblemOccurrence.TC_OOME) == type;
+ }
+
+ public boolean isExitCode(IStringCompactor compactor) {
+ return compactor.getStringId(ProblemOccurrence.TC_EXIT_CODE) == type;
+ }
+
+ public boolean isFailedTests(IStringCompactor compactor) {
+ return compactor.getStringId(ProblemOccurrence.TC_FAILED_TESTS) ==
type;
+ }
+
+ public boolean isSnapshotDepProblem(IStringCompactor compactor) {
+ return
compactor.getStringId(ProblemOccurrence.SNAPSHOT_DEPENDENCY_ERROR) == type
+ ||
compactor.getStringId(ProblemOccurrence.SNAPSHOT_DEPENDENCY_ERROR_BUILD_PROCEEDS_TYPE)
== type;
+ }
+}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/StatisticsCompacted.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/StatisticsCompacted.java
new file mode 100644
index 0000000..52f1e91
--- /dev/null
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/StatisticsCompacted.java
@@ -0,0 +1,101 @@
+/*
+ * 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.ci.teamcity.ignited.fatbuild;
+
+import com.google.common.base.Strings;
+import org.apache.ignite.ci.tcmodel.conf.bt.Property;
+import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
+import org.apache.ignite.ci.teamcity.ignited.IStringCompactor;
+import org.apache.ignite.internal.util.GridIntList;
+import org.apache.ignite.internal.util.GridLongList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class StatisticsCompacted {
+ /** Logger. */
+ private static final Logger logger =
LoggerFactory.getLogger(StatisticsCompacted.class);
+
+ private GridIntList keys;
+ private GridLongList values;
+
+ public StatisticsCompacted() {
+ }
+
+ public StatisticsCompacted(IStringCompactor compactor, Statistics
statistics) {
+ final List<Property> properties = statistics.properties();
+ final int size = properties.size();
+ keys = new GridIntList(size);
+ values = new GridLongList(size);
+ int idx = 0;
+ for (Property next : properties) {
+ final String name = next.name();
+ if (Strings.isNullOrEmpty(name))
+ continue;
+
+ final String value = next.getValue();
+ if (Strings.isNullOrEmpty(value))
+ continue;
+ final long val;
+ try {
+ val = Long.parseLong(value);
+ } catch (Exception e) {
+ logger.error("Statistics value is not numeric " + name + "
skipped " + e.getMessage(), e);
+ continue;
+ }
+
+ final int stringId = compactor.getStringId(name);
+
+ keys.add(stringId);
+ values.add(val);
+ idx++;
+ }
+ }
+
+ public Long buildDuration(IStringCompactor compactor) {
+ final Integer buildDurationId =
compactor.getStringIdIfPresent(Statistics.BUILD_DURATION);
+ if (buildDurationId == null)
+ return null;
+
+ long value = findPropertyValue(buildDurationId);
+
+ if (value < 0) return null;
+
+ return value;
+ }
+
+ private long findPropertyValue(int propertyCode) {
+ final int size = keys.size();
+
+ long value = -1;
+ for (int i = 0; i < size; i++) {
+ final int nameid = keys.get(i);
+
+ if (nameid != propertyCode)
+ continue;
+
+ if (i >= values.size())
+ break;
+
+ value = values.get(i);
+ }
+
+ return value;
+ }
+}
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
index 37a32bc..573b87c 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/ignited/fatbuild/TestCompacted.java
@@ -55,7 +55,7 @@ public class TestCompacted {
public static final int COMPRESS_TYPE_RFU3 = 10;
public static final int COMPRESS_TYPE_RFU4 = 11;
- /** Id in this build only. Does not idenfity test for its history */
+ /** Id in this build only. Does not identify test for its history */
private int idInBuild = -1;
private int name = -1;
diff --git
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
index f832088..27f6fe9 100644
---
a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
+++
b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/teamcity/pure/ITeamcityConn.java
@@ -23,6 +23,8 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
import org.apache.ignite.ci.tcmodel.result.Build;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrences;
+import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
/**
@@ -41,7 +43,7 @@ public interface ITeamcityConn {
public Build getBuild(int buildId);
- public List<BuildRef> getBuildRefs(String fullUrl, AtomicReference<String>
nextPage);
+ public List<BuildRef> getBuildRefsPage(String fullUrl,
AtomicReference<String> nextPage);
/**
* @param buildId Build id.
@@ -59,4 +61,8 @@ public interface ITeamcityConn {
* @param queueAtTop Put at the top of the build queue.
*/
public Build triggerBuild(String buildTypeId, @Nonnull String branchName,
boolean cleanRebuild, boolean queueAtTop);
+
+ ProblemOccurrences getProblems(int buildId);
+
+ Statistics getStatistics(int buildId);
}
diff --git
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
index 173a959..e2649a5 100644
---
a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
+++
b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/teamcity/ignited/IgnitedTcInMemoryIntegrationTest.java
@@ -40,6 +40,9 @@ import org.apache.ignite.ci.di.scheduler.NoOpSheduler;
import org.apache.ignite.ci.tcmodel.conf.BuildType;
import org.apache.ignite.ci.tcmodel.hist.BuildRef;
import org.apache.ignite.ci.tcmodel.result.Build;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence;
+import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrences;
+import org.apache.ignite.ci.tcmodel.result.stat.Statistics;
import org.apache.ignite.ci.tcmodel.result.tests.TestOccurrencesFull;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildDao;
@@ -252,6 +255,8 @@ public class IgnitedTcInMemoryIntegrationTest {
public void testFatBuild() throws JAXBException, IOException {
Build refBuild = jaxbTestXml("/build.xml", Build.class);
TestOccurrencesFull testsRef = jaxbTestXml("/testList.xml",
TestOccurrencesFull.class);
+ ProblemOccurrences problemsList = jaxbTestXml("/problemList.xml",
ProblemOccurrences.class);
+ Statistics statistics = jaxbTestXml("/statistics.xml",
Statistics.class);
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
@@ -265,7 +270,8 @@ public class IgnitedTcInMemoryIntegrationTest {
int srvIdMaskHigh = ITeamcityIgnited.serverIdToInt(APACHE);
List<TestOccurrencesFull> occurrences =
Collections.singletonList(testsRef);
- FatBuildCompacted buildCompacted = stor.saveBuild(srvIdMaskHigh,
refBuild.getId(), refBuild, occurrences, null);
+ FatBuildCompacted buildCompacted = stor.saveBuild(srvIdMaskHigh,
refBuild.getId(), refBuild, occurrences,
+ problemsList.getProblemsNonNull(), statistics, null);
assertNotNull(buildCompacted);
FatBuildCompacted fatBuild = stor.getFatBuild(srvIdMaskHigh, 2153237);
@@ -300,6 +306,17 @@ public class IgnitedTcInMemoryIntegrationTest {
Set<String> testNamesRef = new TreeSet<>();
testsRef.getTests().forEach(testOccurrence ->
testNamesRef.add(testOccurrence.name));
assertEquals(testNamesRef, testNamesAct);
+
+ final List<ProblemOccurrence> problems =
buildCompacted.problems(compactor);
+ assertEquals(2, problems.size());
+
+
assertTrue(problems.stream().anyMatch(ProblemOccurrence::isFailedTests));
+ assertTrue(problems.stream().anyMatch(ProblemOccurrence::isExitCode));
+ assertTrue(problems.stream().noneMatch(ProblemOccurrence::isJvmCrash));
+
+ Long duration = buildCompacted.buildDuration(compactor);
+ assertNotNull(duration);
+ assertTrue(duration>10000L);
}
public void saveTmpFile(Object obj, String name) throws IOException,
JAXBException {
diff --git a/ignite-tc-helper-web/src/test/resources/problemList.xml
b/ignite-tc-helper-web/src/test/resources/problemList.xml
new file mode 100644
index 0000000..4a770f2
--- /dev/null
+++ b/ignite-tc-helper-web/src/test/resources/problemList.xml
@@ -0,0 +1,20 @@
+<!-- Syntetic list from:
+
https://ci.ignite.apache.org/app/rest/latest/problemOccurrences?locator=build:(id:2153237)&fields=problemOccurrence(id,type,identity,href,details,build(id))-->
+<problemOccurrences>
+ <problemOccurrence id="problem:(id:3481),build:(id:2136678)"
type="TC_EXIT_CODE" identity="Inspection1"
+
href="/app/rest/latest/problemOccurrences/problem:(id:3481),build:(id:2136678)">
+ <details>Process exited with code 1</details>
+
<additionalData>teamcity.process.flow.id=1200755009805251</additionalData>
+ <problem id="3481" type="TC_EXIT_CODE" identity="Inspection1"
href="/app/rest/latest/problems/id:3481"/>
+ <build id="2136678" buildTypeId="IgniteTests24Java8_InspectionsAop"
number="165" status="FAILURE"
+ state="finished" branchName="refs/heads/master"
defaultBranch="true"
+ href="/app/rest/latest/builds/id:2136678"
+
webUrl="http://ci.ignite.apache.org/viewLog.html?buildId=2136678&buildTypeId=IgniteTests24Java8_InspectionsAop"/>
+ </problemOccurrence>
+ <problemOccurrence id="problem:(id:3733),build:(id:2153237)"
type="TC_FAILED_TESTS"
+ identity="TC_FAILED_TESTS_bt1053"
+
href="/app/rest/latest/problemOccurrences/problem:(id:3733),build:(id:2153237)">
+ <details>1 failed test detected</details>
+ <build id="2153237"/>
+ </problemOccurrence>
+</problemOccurrences>
\ No newline at end of file