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/06 17:54:58 UTC
[ignite-teamcity-bot] branch master updated: Board: Summary of
non-fixed failures as new screen (phase 1) - Fixes #140.
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 d5c757b Board: Summary of non-fixed failures as new screen (phase 1) - Fixes #140.
d5c757b is described below
commit d5c757b86fddd58ad53ee593d60087e3e92ce1e4
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Tue Aug 6 20:54:32 2019 +0300
Board: Summary of non-fixed failures as new screen (phase 1) - Fixes #140.
Signed-off-by: Dmitriy Pavlov <dp...@apache.org>
---
.../java/org/apache/ignite/ci/db/DbMigrations.java | 2 +-
.../java/org/apache/ignite/ci/db/TcHelperDb.java | 5 -
.../apache/ignite/ci/observer/package-info.java | 2 +-
.../apache/ignite/ci/runners/ClientTmpHelper.java | 2 +-
.../ignite/ci/runners/RemoteClientTmpHelper.java | 5 +-
.../apache/ignite/ci/tcbot/TcBotWebAppModule.java | 5 +-
.../ignite/ci/tcbot/issue/IssueDetector.java | 3 +-
.../ci/tcbot/user/UserAndSessionsStorage.java | 6 +-
.../ignite/ci/web/rest/board/BoardRestService.java | 55 ++++++
.../apache/ignite/ci/web/rest/issues/TcIssues.java | 8 +-
.../ignite/ci/web/rest/login/UserService.java | 2 +-
.../src/main/webapp/board/index.html | 204 +++++++++++++++++++++
ignite-tc-helper-web/src/main/webapp/trends.html | 2 +-
.../ci/tcbot/chain/MockBasedTcBotModule.java | 2 +-
.../ci/tcbot/chain/PrChainsProcessorTest.java | 2 +-
.../java/org/apache/ignite/ci/issue/ChangeUi.java | 6 +
.../java/org/apache/ignite/ci/issue/Issue.java | 2 +
.../java/org/apache/ignite/ci/issue/IssueKey.java | 1 +
.../ignite/tcbot/engine/TcBotEngineModule.java | 7 +
.../ignite/tcbot/engine/board/BoardService.java | 201 ++++++++++++++++++++
.../tcbot/engine/buildtime/BuildTimeService.java | 30 +--
.../tcbot/engine/chain/BuildChainProcessor.java | 17 +-
.../tcbot/engine/chain/SingleBuildRunCtx.java | 32 ++--
.../ignite/tcbot/engine/defect/BlameCandidate.java | 26 +--
.../tcbot/engine/defect/CommitCompacted.java | 77 ++++++++
.../tcbot/engine/defect/DefectCompacted.java | 164 +++++++++++++++++
.../tcbot/engine/defect/DefectFirstBuild.java | 44 ++---
.../ignite/tcbot/engine/defect/DefectIssue.java | 47 +++--
.../DefectKey.java} | 15 +-
.../ignite/tcbot/engine/defect/DefectsStorage.java | 155 ++++++++++++++++
.../ignite/tcbot/engine}/issue/IIssuesStorage.java | 2 +-
.../ignite/tcbot/engine}/issue/IssueType.java | 2 +-
.../ignite/tcbot/engine}/issue/IssuesStorage.java | 9 +-
.../tcbot/engine/ui/BoardDefectSummaryUi.java | 94 ++++++++++
...{BuildTimeRecordUi.java => BoardSummaryUi.java} | 19 +-
.../ignite/tcbot/engine/ui/BuildTimeRecordUi.java | 11 ++
.../apache/ignite/tcbot/engine/ui/IssueListUi.java | 8 +-
.../ignite/tcbot/persistence/CacheConfigs.java | 7 +
.../teamcity/ignited/change/ChangeCompacted.java | 17 +-
.../ci/teamcity/ignited/change/ChangeDao.java | 15 +-
.../ignited/fatbuild/FatBuildCompacted.java | 6 +-
.../ignite/tcignited/TeamcityIgnitedImpl.java | 13 +-
.../apache/ignite/tcignited/build/FatBuildDao.java | 2 +-
.../org/apache/ignite/tcignited/build/ITest.java | 8 +-
.../ignite/tcignited/build/TestCompactedV2.java | 4 +
.../ignite/tcignited/buildlog/LogMsgToWarn.java | 2 +-
.../ignite/tcignited/buildref/BuildRefDao.java | 4 +
.../tcignited/buildtime/BuildTimeRecord.java | 4 +
.../tcignited/buildtime/BuildTimeResult.java | 8 +-
49 files changed, 1199 insertions(+), 165 deletions(-)
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 1bbb8fe..6781920 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
@@ -25,7 +25,7 @@ import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.ci.issue.Issue;
import org.apache.ignite.ci.issue.IssueKey;
-import org.apache.ignite.ci.issue.IssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssuesStorage;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.tcservice.model.result.Build;
import org.jetbrains.annotations.NotNull;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java
index e706b33..6850194 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/db/TcHelperDb.java
@@ -106,11 +106,6 @@ public class TcHelperDb {
return TcHelperDb.<K, V>getCacheV3Config(name).setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
}
- public static <K, V> CacheConfiguration<K, V> getCacheV2TxConfig(String name) {
- return CacheConfigs.<K, V>getCacheV2Config(name).setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-
- }
-
public static class LocalOnlyTcpDiscoveryIpFinder implements TcpDiscoveryIpFinder {
/** Port. */
private int port;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/package-info.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/package-info.java
index f7e1a1c..d0b2ec3 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/package-info.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/observer/package-info.java
@@ -35,7 +35,7 @@
* list for specific {@link org.apache.ignite.ci.web.model.ContributionKey}.
* It's needed for proper changing of status and result of
* {@link org.apache.ignite.ci.web.model.VisaRequest} by {@link org.apache.ignite.ci.observer.ObserverTask}.
- * If happens an attempt to add observation
+ * If happens an attempt to addBuild observation
* for {@link org.apache.ignite.ci.web.model.ContributionKey} while current
* observation is not finished, then current observation will be marked as
* cancelled and overwritten by the new one.
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/ClientTmpHelper.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/ClientTmpHelper.java
index 75774d2..0541e80 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/ClientTmpHelper.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/ClientTmpHelper.java
@@ -22,7 +22,7 @@ import org.apache.ignite.IgniteCache;
import org.apache.ignite.ci.db.TcHelperDb;
import org.apache.ignite.githubignited.IGitHubConnIgnited;
import org.apache.ignite.ci.issue.Issue;
-import org.apache.ignite.ci.issue.IssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssuesStorage;
import org.apache.ignite.jiraignited.JiraTicketDao;
/**
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java
index ec9c219..ad01803 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/runners/RemoteClientTmpHelper.java
@@ -35,8 +35,8 @@ import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.ci.issue.Issue;
import org.apache.ignite.ci.issue.IssueKey;
-import org.apache.ignite.ci.issue.IssueType;
-import org.apache.ignite.ci.issue.IssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssueType;
+import org.apache.ignite.tcbot.engine.issue.IssuesStorage;
import org.apache.ignite.ci.tcbot.user.UserAndSessionsStorage;
import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
@@ -49,7 +49,6 @@ import org.apache.ignite.tcbot.persistence.IgniteStringCompactor;
import org.apache.ignite.tcignited.ITeamcityIgnited;
import org.apache.ignite.tcignited.build.FatBuildDao;
import org.apache.ignite.tcignited.buildref.BuildRefDao;
-import org.apache.ignite.tcignited.history.BuildStartTimeStorage;
import org.apache.ignite.tcservice.model.hist.BuildRef;
import org.apache.ignite.tcservice.model.result.Build;
import org.apache.ignite.tcservice.util.XmlUtil;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotWebAppModule.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotWebAppModule.java
index e613ccf..bb1bbd5 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotWebAppModule.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/TcBotWebAppModule.java
@@ -26,15 +26,15 @@ import java.util.concurrent.TimeoutException;
import javax.inject.Provider;
import org.apache.ignite.Ignite;
import org.apache.ignite.ci.db.Ignite1Init;
-import org.apache.ignite.ci.issue.IssuesStorage;
import org.apache.ignite.ci.tcbot.conf.LocalFilesBasedConfig;
-import org.apache.ignite.ci.tcbot.issue.IIssuesStorage;
import org.apache.ignite.ci.tcbot.trends.MasterTrendsService;
import org.apache.ignite.ci.tcbot.user.IUserStorage;
import org.apache.ignite.ci.tcbot.user.UserAndSessionsStorage;
import org.apache.ignite.tcbot.common.conf.IDataSourcesConfigSupplier;
import org.apache.ignite.tcbot.engine.TcBotEngineModule;
import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
+import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssuesStorage;
import org.apache.ignite.tcbot.notify.TcBotNotificationsModule;
import org.apache.ignite.tcbot.persistence.scheduler.SchedulerModule;
import org.apache.ignite.githubignited.GitHubIgnitedModule;
@@ -93,7 +93,6 @@ public class TcBotWebAppModule extends AbstractModule {
//todo remove duplication of instances for base and for overriden class
bind(IDataSourcesConfigSupplier.class).to(LocalFilesBasedConfig.class).in(new SingletonScope());
bind(IUserStorage.class).to(UserAndSessionsStorage.class).in(new SingletonScope());
- bind(IIssuesStorage.class).to(IssuesStorage.class).in(new SingletonScope());
bind(MasterTrendsService.class).in(new SingletonScope());
bind(ITcBotBgAuth.class).to(TcBotBgAuthImpl.class).in(new SingletonScope());
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
index f6027c5..807b63d 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IssueDetector.java
@@ -35,7 +35,8 @@ import javax.inject.Inject;
import javax.inject.Provider;
import org.apache.ignite.ci.issue.Issue;
import org.apache.ignite.ci.issue.IssueKey;
-import org.apache.ignite.ci.issue.IssueType;
+import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssueType;
import org.apache.ignite.ci.jobs.CheckQueueJob;
import org.apache.ignite.tcbot.engine.tracked.DisplayMode;
import org.apache.ignite.tcbot.notify.ISlackSender;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/user/UserAndSessionsStorage.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/user/UserAndSessionsStorage.java
index 2380f8c..43a7b7a 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/user/UserAndSessionsStorage.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/user/UserAndSessionsStorage.java
@@ -24,9 +24,9 @@ import javax.inject.Inject;
import javax.inject.Provider;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
-import org.apache.ignite.ci.db.TcHelperDb;
import org.apache.ignite.ci.user.TcHelperUser;
import org.apache.ignite.ci.user.UserSession;
+import org.apache.ignite.tcbot.persistence.CacheConfigs;
import org.jetbrains.annotations.Nullable;
public class UserAndSessionsStorage implements IUserStorage {
@@ -38,7 +38,7 @@ public class UserAndSessionsStorage implements IUserStorage {
private volatile Ignite ignite;
public IgniteCache<String, TcHelperUser> users() {
- return getIgnite().getOrCreateCache(TcHelperDb.getCacheV2TxConfig(USERS));
+ return getIgnite().getOrCreateCache(CacheConfigs.<String, TcHelperUser>getCacheV2TxConfig(USERS));
}
public Ignite getIgnite() {
@@ -56,7 +56,7 @@ public class UserAndSessionsStorage implements IUserStorage {
}
private IgniteCache<String, UserSession> sessions() {
- return getIgnite().getOrCreateCache(TcHelperDb.getCacheV2TxConfig(USER_SESSIONS));
+ return getIgnite().getOrCreateCache(CacheConfigs.<String, UserSession>getCacheV2TxConfig(USER_SESSIONS));
}
/** {@inheritDoc} */
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java
new file mode 100644
index 0000000..d8550a4
--- /dev/null
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/board/BoardRestService.java
@@ -0,0 +1,55 @@
+/*
+ * 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.web.rest.board;
+
+import com.google.inject.Injector;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import org.apache.ignite.ci.user.ITcBotUserCreds;
+import org.apache.ignite.ci.web.CtxListener;
+import org.apache.ignite.tcbot.engine.board.BoardService;
+import org.apache.ignite.tcbot.engine.ui.BoardSummaryUi;
+
+@Path(BoardRestService.BOARD)
+@Produces(MediaType.APPLICATION_JSON)
+public class BoardRestService {
+ public static final String BOARD = "board";
+
+ /** Servlet Context. */
+ @Context
+ private ServletContext ctx;
+
+ /** Current Request. */
+ @Context
+ private HttpServletRequest req;
+
+ @GET
+ @Path("summary")
+ public BoardSummaryUi getSummary() {
+
+ final ITcBotUserCreds creds = ITcBotUserCreds.get(req);
+ final Injector injector = CtxListener.getInjector(ctx);
+ final BoardService boardSvc = injector.getInstance(BoardService.class);
+
+ return boardSvc.summary(creds);
+ }
+}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java
index f62d867..4ed7b79 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/issues/TcIssues.java
@@ -27,8 +27,8 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
-import org.apache.ignite.ci.issue.IssueList;
-import org.apache.ignite.ci.tcbot.issue.IIssuesStorage;
+import org.apache.ignite.tcbot.engine.ui.IssueListUi;
+import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
import org.apache.ignite.ci.web.CtxListener;
import org.apache.ignite.ci.web.model.SimpleResult;
import org.apache.ignite.tcbot.engine.ui.UpdateInfo;
@@ -58,7 +58,7 @@ public class TcIssues {
@GET
@Path("list")
- public IssueList listIssues(@Nullable @QueryParam("branch") String branchOpt,
+ public IssueListUi listIssues(@Nullable @QueryParam("branch") String branchOpt,
@Nullable @QueryParam("count") Integer count,
@Nullable @QueryParam("checkAllLogs") Boolean checkAllLogs) {
Injector injector = CtxListener.getInjector(ctx);
@@ -67,7 +67,7 @@ public class TcIssues {
IIssuesStorage issues = injector.getInstance(IIssuesStorage.class);
- IssueList issueList = new IssueList(issues.allIssues().collect(Collectors.toList()));
+ IssueListUi issueList = new IssueListUi(issues.allIssues().collect(Collectors.toList()));
issueList.branch = branch;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/login/UserService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/login/UserService.java
index dfaf340..fb6229a 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/login/UserService.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/login/UserService.java
@@ -140,7 +140,7 @@ public class UserService {
tcHelperUserUi.data.add(credsUi);
}
- //todo if user is not current disable add creds
+ //todo if user is not current disable addBuild creds
return tcHelperUserUi;
}
diff --git a/ignite-tc-helper-web/src/main/webapp/board/index.html b/ignite-tc-helper-web/src/main/webapp/board/index.html
new file mode 100644
index 0000000..02e4f3d
--- /dev/null
+++ b/ignite-tc-helper-web/src/main/webapp/board/index.html
@@ -0,0 +1,204 @@
+<html>
+<head>
+ <title>Apache Ignite Teamcity Bot - Tracked branch - Detailed status of failures</title>
+ <link rel="icon" href="/img/leaf-icon-png-7066.png">
+
+ <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
+ <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
+
+ <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
+ <!-- production version, optimized for size and speed -->
+ <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>-->
+
+ <script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
+ <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
+
+ <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
+ <link href="https://cdn.jsdelivr.net/npm/@mdi/font@3.x/css/materialdesignicons.min.css" rel="stylesheet">
+
+ <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
+ <link rel="stylesheet" href="/css/style-1.5.css">
+
+ <script src="/js/common-1.6.js"></script>
+</head>
+<body>
+<script>
+ var g_shownDataHashCodeHex = "";
+ let gVue, g_Loading, g_TcBotVersion;
+
+ $(document).ready(function() {
+ $.getScript("/js/testfails-2.2.js", function(data, textStatus, jqxhr){ });
+
+ $( document ).tooltip();
+ showQueryForm();
+
+ loadData();
+
+ setInterval(loadDataSilent, 3000);
+
+ $.ajax({ url: "/rest/branches/version", success: showVersionInfo, error: showErrInLoadStatus });
+ });
+
+ function showQueryForm() {
+ gVue = new Vue({
+ el: '#vueQueryForm',
+ vuetify: new Vuetify(),
+ data: {
+ baseBranchSelected: '',
+ defects: [],
+ expanded: [],
+ headers: [
+ {text: "Branch", value: 'branch'},
+ {text: 'Tags', value: 'tags'},
+ {text: 'Suites', value: 'suites'},
+ {text: "Issues", value: 'cntissues'},
+ {text: "Fixed", value: 'fixedissues'},
+ {text: "Not Fixed", value: 'notfixedissues'}
+ ]
+ },
+ methods: {
+ formChanged: function () {
+ }
+ }
+ });
+ }
+
+
+ function parmsForRest() {
+ var curReqParms = "";
+ var branch = findGetParameter("branch");
+ if (branch != null) {
+ curReqParms += "?branch=" + branch;
+ }
+
+ if (gVue.$data.baseBranchSelected != null) {
+ curReqParms += "?baseBranch=" + gVue.$data.baseBranchSelected;
+ }
+
+ return curReqParms;
+ }
+
+ function loadDataFromServer(silent) {
+ g_Loading = true;
+ if (!silent) $("#loadStatus").html("<img src='https://www.wallies.com/filebin/images/loading_apple.gif' width=20px height=20px> Please wait");
+
+ var curFailuresUrl = "/rest/board/summary" + parmsForRest();
+ $.ajax({
+ url: curFailuresUrl,
+ success: function (result) {
+ if (!silent) $("#loadStatus").html("");
+
+ showData(result);
+ g_shownDataHashCodeHex = isDefinedAndFilled(result.hashCodeHex) ? result.hashCodeHex : "";
+
+ g_Loading = false;
+ },
+ error: function (jqXHR, exception) {
+ g_Loading = false;
+ showErrInLoadStatus(jqXHR, exception);
+ }
+ });
+ }
+
+ function loadData() {
+ loadDataFromServer(false);
+ }
+
+ function validateVersionsConsistency() {
+ $.ajax({
+ url: "/rest/branches/version", success: function (result) {
+ if (g_TcBotVersion == null)
+ g_TcBotVersion = result.version;
+ else if (g_TcBotVersion !== result.version)
+ window.location.reload(true);
+
+ }, error: showErrInLoadStatus
+ });
+ }
+
+ function loadDataSilent() {
+ if(g_Loading)
+ return;
+
+ try {
+ loadDataFromServer(true);
+ validateVersionsConsistency();
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
+ function showData(result) {
+ gVue.$data.defects = result.defects;
+ }
+
+</script>
+
+<div id="loadStatus"></div>
+<div id="vueQueryForm" class="h-25">
+ <v-app id="queryForm" class="h-25">
+ <!-- <select v-model="baseBranchSelected" @change="formChanged">
+ <option disabled value="">Please select one</option>
+ <option>A</option>
+ <option>B</option>
+ <option>C</option>
+ </select>
+ <span>Base branch: {{ baseBranchSelected }}</span> -->
+
+
+ <v-data-table
+ :headers="headers"
+ :items="defects"
+ itrackedBranchtem-key="id"
+ class="elevation-1"
+ group-by="branch"
+ :expanded.sync="expanded"
+ show-expand
+ dense
+ >
+ <!-- expand item/row -->
+ <template v-slot:expanded-item="{ headers, item }">
+ <td :colspan="headers.length">
+ Branch: <a :href="'/current.html?branch=' + item.trackedBranch">{{item.trackedBranch}}</a>
+ Commits from:
+ <div v-for="(candidate) in item.blameCandidates">
+ {{ candidate }}
+ </div>
+
+ <div v-for="(test) in item.testOrSuitesAffected">
+ {{ test }}
+ </div>
+ </td>
+ </template>
+
+ <template v-slot:item.tags="{ item }">
+ <span v-for="(tag) in item.tags">
+ {{ tag }}
+ </span>
+ </template>
+
+ <template v-slot:item.suites="{ item }">
+ <span v-for="(suite) in item.suites">
+ {{ suite }}
+ </span>
+ </template>
+
+ <template v-slot:item.cntIssues="{ item }">
+ {{ item.cntIssues }}
+ </template>
+ <template v-slot:item.fixedIssues="{ item }">
+ <span class='visaStage' style="background: #12AD5E"> {{ item.fixedIssues }} </span>
+ </template>
+ <template v-slot:item.notFixedIssues="{ item }">
+ <span class='visaStage' style="background: red"> {{ item.notFixedIssues }} </span>
+ </template>
+
+ </v-data-table>
+
+ </v-app>
+</div>
+
+<div id="version"></div>
+<div style="visibility:hidden;"><div id="triggerConfirm" title="Trigger Confirmation"></div><div id="triggerDialog" title="Trigger Result"></div></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/ignite-tc-helper-web/src/main/webapp/trends.html b/ignite-tc-helper-web/src/main/webapp/trends.html
index e89a61e..9b8e660 100644
--- a/ignite-tc-helper-web/src/main/webapp/trends.html
+++ b/ignite-tc-helper-web/src/main/webapp/trends.html
@@ -581,7 +581,7 @@
/**
*
- * @param result list of {@link org.apache.ignite.ci.tcbot.conf.ChainAtServer} objects as JSON.
+ * @param result list of {@link org.apache.ignite.ci.tcbot.conf.ChainAtServer} testOrSuitesAffected as JSON.
*/
function printSuites(result) {
let selectHtml = "<select id='selectSuite'>";
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/MockBasedTcBotModule.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/MockBasedTcBotModule.java
index 4db0af0..6f54189 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/MockBasedTcBotModule.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/MockBasedTcBotModule.java
@@ -39,7 +39,7 @@ import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
import org.apache.ignite.tcbot.engine.conf.ITrackedBranchesConfig;
import org.apache.ignite.tcbot.engine.conf.NotificationsConfig;
import org.apache.ignite.tcbot.engine.conf.TcServerConfig;
-import org.apache.ignite.ci.tcbot.issue.IIssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
import org.apache.ignite.ci.tcbot.user.IUserStorage;
import org.apache.ignite.tcbot.notify.IEmailSender;
import org.apache.ignite.tcbot.notify.ISlackSender;
diff --git a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java
index f467daa..d166c50 100644
--- a/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java
+++ b/ignite-tc-helper-web/src/test/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessorTest.java
@@ -255,7 +255,7 @@ public class PrChainsProcessorTest {
createTest(1L, TEST_RARE_FAILED_WITHOUT_CHANGES, !failNoChanges),
createTest(2L, TEST_RARE_FAILED_WITH_CHANGES, !failWithChanges)), null);
- if (failWithChanges || i == 56) // add change to test status change after failure.
+ if (failWithChanges || i == 56) // addBuild change to test status change after failure.
fatBuild.changes(new int[] {1000000 + i, 1000020 + i});
addBuildsToEmulatedStor(fatBuild);
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/ChangeUi.java b/tcbot-engine/src/main/java/org/apache/ignite/ci/issue/ChangeUi.java
similarity index 93%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/ChangeUi.java
rename to tcbot-engine/src/main/java/org/apache/ignite/ci/issue/ChangeUi.java
index 5b433b5..41b644e 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/ChangeUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/ci/issue/ChangeUi.java
@@ -18,7 +18,9 @@
package org.apache.ignite.ci.issue;
import com.google.common.base.MoreObjects;
+import org.apache.ignite.tcbot.persistence.Persisted;
+@Persisted
public class ChangeUi {
public final String username;
public final String webUrl;
@@ -51,4 +53,8 @@ public class ChangeUi {
.add("webUrl", webUrl)
.toString();
}
+
+ public String username() {
+ return username;
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/Issue.java b/tcbot-engine/src/main/java/org/apache/ignite/ci/issue/Issue.java
similarity index 98%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/Issue.java
rename to tcbot-engine/src/main/java/org/apache/ignite/ci/issue/Issue.java
index 2e99c52..6923122 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/Issue.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/ci/issue/Issue.java
@@ -29,11 +29,13 @@ import java.util.Map;
import java.util.TreeSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.ignite.tcbot.engine.issue.IssueType;
import org.apache.ignite.tcbot.persistence.Persisted;
import org.apache.ignite.tcbot.common.util.TimeUtil;
/**
* Issue used both for saving into DB and in UI (in issue history).
+ * Issue is any detected failure of test or suite.
*/
@SuppressWarnings({"WeakerAccess", "PublicField"})
@Persisted
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java b/tcbot-engine/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
similarity index 98%
copy from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
copy to tcbot-engine/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
index 348a623..28c0102 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
@@ -44,6 +44,7 @@ public class IssueKey {
return testOrBuildName;
}
+ /** {@inheritDoc} */
@Override public String toString() {
return MoreObjects.toStringHelper(this)
.add("server", server)
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java
index 44a9465..948c002 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/TcBotEngineModule.java
@@ -21,8 +21,11 @@ import com.google.inject.AbstractModule;
import com.google.inject.internal.SingletonScope;
import org.apache.ignite.tcbot.common.TcBotCommonModule;
import org.apache.ignite.tcbot.common.interceptor.MonitoredTaskInterceptorModule;
+import org.apache.ignite.tcbot.engine.board.BoardService;
import org.apache.ignite.tcbot.engine.buildtime.BuildTimeService;
import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssuesStorage;
import org.apache.ignite.tcbot.engine.tracked.IDetailedStatusForTrackedBranch;
import org.apache.ignite.tcbot.engine.tracked.TrackedBranchChainsProcessor;
@@ -37,6 +40,10 @@ public class TcBotEngineModule extends AbstractModule {
bind(BuildTimeService.class).in(new SingletonScope());
+ bind(IIssuesStorage.class).to(IssuesStorage.class).in(new SingletonScope());
+
+ bind(BoardService.class).in(new SingletonScope());
+
install(new TcBotCommonModule());
}
}
\ No newline at end of file
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java
new file mode 100644
index 0000000..d7ff93e
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/BoardService.java
@@ -0,0 +1,201 @@
+/*
+ * 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.tcbot.engine.board;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.inject.Inject;
+import org.apache.ignite.ci.issue.Issue;
+import org.apache.ignite.ci.issue.IssueKey;
+import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
+import org.apache.ignite.ci.teamcity.ignited.change.ChangeDao;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.tcbot.common.conf.ITcServerConfig;
+import org.apache.ignite.tcbot.common.interceptor.MonitoredTask;
+import org.apache.ignite.tcbot.common.util.FutureUtil;
+import org.apache.ignite.tcbot.engine.chain.BuildChainProcessor;
+import org.apache.ignite.tcbot.engine.chain.SingleBuildRunCtx;
+import org.apache.ignite.tcbot.engine.defect.BlameCandidate;
+import org.apache.ignite.tcbot.engine.defect.DefectCompacted;
+import org.apache.ignite.tcbot.engine.defect.DefectFirstBuild;
+import org.apache.ignite.tcbot.engine.defect.DefectIssue;
+import org.apache.ignite.tcbot.engine.defect.DefectsStorage;
+import org.apache.ignite.tcbot.engine.issue.IIssuesStorage;
+import org.apache.ignite.tcbot.engine.issue.IssueType;
+import org.apache.ignite.tcbot.engine.ui.BoardDefectSummaryUi;
+import org.apache.ignite.tcbot.engine.ui.BoardSummaryUi;
+import org.apache.ignite.tcbot.persistence.IStringCompactor;
+import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
+import org.apache.ignite.tcignited.ITeamcityIgnited;
+import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
+import org.apache.ignite.tcignited.build.FatBuildDao;
+import org.apache.ignite.tcignited.build.ITest;
+import org.apache.ignite.tcignited.creds.ICredentialsProv;
+
+public class BoardService {
+ @Inject IIssuesStorage issuesStorage;
+ @Inject FatBuildDao fatBuildDao;
+ @Inject ChangeDao changeDao;
+ @Inject ITeamcityIgnitedProvider tcProv;
+ @Inject DefectsStorage defectStorage;
+ @Inject IScheduler scheduler;
+ @Inject IStringCompactor compactor;
+
+ @Inject BuildChainProcessor buildChainProcessor;
+
+ /**
+ * @param creds Credentials.
+ */
+ public BoardSummaryUi summary(ICredentialsProv creds) {
+ issuesToDefectsLater();
+
+ Map<Integer, Future<FatBuildCompacted>> allBuildsMap = new HashMap<>();
+
+ List<DefectCompacted> defects = defectStorage.loadAllDefects();
+
+ BoardSummaryUi res = new BoardSummaryUi();
+ for (DefectCompacted next : defects) {
+ BoardDefectSummaryUi defectUi = new BoardDefectSummaryUi(next, compactor);
+
+ String srvCode = next.tcSrvCode(compactor);
+
+ if(!creds.hasAccess(srvCode))
+ continue;
+
+ ITeamcityIgnited tcIgn = tcProv.server(srvCode, creds);
+
+ ITcServerConfig cfg = tcIgn.config();
+
+ List<BlameCandidate> candidates = next.blameCandidates();
+
+
+ Map<Integer, DefectFirstBuild> build = next.buildsInvolved();
+ for (DefectFirstBuild cause : build.values()) {
+ FatBuildCompacted firstBuild = cause.build();
+ defectUi.addTags(SingleBuildRunCtx.getBuildTagsFromParameters(cfg, compactor, firstBuild));
+ FatBuildCompacted fatBuild = fatBuildDao.getFatBuild(next.tcSrvId(), firstBuild.id());
+
+ List<Future<FatBuildCompacted>> futures = buildChainProcessor.replaceWithRecent(fatBuild, allBuildsMap, tcIgn);
+
+ Stream<FatBuildCompacted> results = FutureUtil.getResults(futures);
+ List<FatBuildCompacted> freshRebuild = results.collect(Collectors.toList());
+ if(!freshRebuild.isEmpty()) {
+ FatBuildCompacted buildCompacted = freshRebuild.get(0);
+
+ Set<DefectIssue> issues = cause.issues();
+ for (DefectIssue issue : issues) {
+ Optional<ITest> any = buildCompacted.getAllTests()
+ .filter(t -> t.testName() == issue.testNameCid())
+ .findAny();
+
+ if(any.isPresent()) {
+ boolean failed = any.get().isFailedTest(compactor);
+ if(!failed)
+ defectUi.addFixedIssue();
+ else
+ defectUi.addNotFixedIssue();
+ }
+
+ String testOrBuildName = compactor.getStringFromId(issue.testNameCid());
+ defectUi.addIssue(testOrBuildName, "");
+ }
+ }
+ }
+
+ defectUi.branch = next.tcBranch(compactor);
+
+ res.addDefect(defectUi);
+ }
+
+ return res;
+ }
+
+ public void issuesToDefectsLater() {
+ scheduler.sheduleNamed("issuesToDefects", this::issuesToDefects, 15, TimeUnit.MINUTES);
+ }
+
+ @MonitoredTask(name = "Convert issues to defect")
+ protected void issuesToDefects() {
+ Stream<Issue> stream = issuesStorage.allIssues();
+
+ long minIssueTs = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(3);
+
+ //todo not so good to to call init() twice
+ fatBuildDao.init();
+ changeDao.init();
+
+ stream
+ .filter(issue -> {
+ long detected = issue.detectedTs == null ? 0 : issue.detectedTs;
+
+ return detected >= minIssueTs;
+ })
+ .filter(issue -> {
+ String type = issue.type;
+ return !IssueType.newContributedTestFailure.code().equals(type);
+ })
+ .forEach(issue -> {
+ IssueKey key = issue.issueKey;
+ String srvCode = key.getServer();
+ //just for init call
+
+ int srvId = ITeamcityIgnited.serverIdToInt(srvCode);
+ FatBuildCompacted fatBuild = fatBuildDao.getFatBuild(srvId, key.buildId);
+ if (fatBuild == null)
+ return;
+
+ //todo non test failures
+ String testName = issue.issueKey().getTestOrBuildName();
+
+ int issueTypeCid = compactor.getStringId(issue.type);
+ Integer testNameCid = compactor.getStringIdIfPresent(testName);
+ int trackedBranchCid = compactor.getStringId(issue.trackedBranchName);
+
+ int tcSrvCodeCid = compactor.getStringId(srvCode);
+ defectStorage.merge(tcSrvCodeCid, srvId, fatBuild,
+ (k, defect) -> {
+ defect.trackedBranchCidSetIfEmpty(trackedBranchCid);
+
+ defect.computeIfAbsent(fatBuild).addIssue(issueTypeCid, testNameCid);
+
+ if(defect.blameCandidates().isEmpty()) {
+ Map<Integer, ChangeCompacted> map = defect.changeMap();
+
+ Collection<ChangeCompacted> values = map.values();
+ for (ChangeCompacted next : values) {
+ BlameCandidate candidate = new BlameCandidate();
+ candidate.vcsUsername(next.vcsUsername());
+ defect.addBlameCandidate(candidate);
+ }
+ }
+
+ return defect;
+ });
+
+ });
+
+ }
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/buildtime/BuildTimeService.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/buildtime/BuildTimeService.java
index 3f71c4c..86c1dfd 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/buildtime/BuildTimeService.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/buildtime/BuildTimeService.java
@@ -25,7 +25,6 @@ import org.apache.ignite.tcbot.engine.ui.BuildTimeResultUi;
import org.apache.ignite.tcbot.persistence.IStringCompactor;
import org.apache.ignite.tcbot.persistence.scheduler.IScheduler;
import org.apache.ignite.tcignited.ITeamcityIgnited;
-import org.apache.ignite.tcignited.ITeamcityIgnitedProvider;
import org.apache.ignite.tcignited.build.FatBuildDao;
import org.apache.ignite.tcignited.buildref.BuildRefDao;
import org.apache.ignite.tcignited.buildtime.BuildTimeRecord;
@@ -42,9 +41,10 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+/**
+ * Prepares overview related to build times of suites, tests, and branches
+ */
public class BuildTimeService {
- @Inject private ITeamcityIgnitedProvider tcProv;
-
/** Config. */
@Inject private ITcBotConfig cfg;
@@ -64,17 +64,17 @@ public class BuildTimeService {
if (buildRefDao.buildRefsCache() == null)
return new BuildTimeResultUi();
- Collection<String> allServers = cfg.getServerIds();
+ Collection<String> allSrvs = cfg.getServerIds();
scheduler.sheduleNamed("BuildTimeService.loadAnalytics",
this::loadAnalytics, 15, TimeUnit.MINUTES);
- Set<Integer> availableServers = allServers.stream()
+ Set<Integer> availableSrvs = allSrvs.stream()
.filter(prov::hasAccess)
.map(ITeamcityIgnited::serverIdToInt)
.collect(Collectors.toSet());
- BuildTimeResultUi resultUi = new BuildTimeResultUi();
+ BuildTimeResultUi resUi = new BuildTimeResultUi();
long minDuration = Duration.ofMinutes(90).toMillis();
long minDurationTimeout = Duration.ofMinutes(60).toMillis();
@@ -82,13 +82,13 @@ public class BuildTimeService {
int cntToInclude = 50;
BuildTimeResult res = lastRes1d;
- res.topByBuildTypes(availableServers, minDuration, cntToInclude, totalDurationMs)
- .stream().map(this::convertToUi).forEach(e -> resultUi.byBuildType.add(e));
+ res.topByBuildTypes(availableSrvs, minDuration, cntToInclude, totalDurationMs)
+ .stream().map(this::convertToUi).forEach(e -> resUi.byBuildType.add(e));
- res.topTimeoutsByBuildTypes(availableServers, minDurationTimeout, cntToInclude, totalDurationMs)
- .stream().map(this::convertToUi).forEach(e -> resultUi.timedOutByBuildType.add(e));
+ res.topTimeoutsByBuildTypes(availableSrvs, minDurationTimeout, cntToInclude, totalDurationMs)
+ .stream().map(this::convertToUi).forEach(e -> resUi.timedOutByBuildType.add(e));
- return resultUi;
+ return resUi;
}
public BuildTimeRecordUi convertToUi(Map.Entry<Long, BuildTimeRecord> e) {
@@ -97,8 +97,12 @@ public class BuildTimeService {
int btId = BuildTimeResult.cacheKeyToBuildType(key);
buildTimeRecordUi.buildType = compactor.getStringFromId(btId);
- buildTimeRecordUi.averageDuration = TimeUtil.millisToDurationPrintable(e.getValue().avgDuration());
- buildTimeRecordUi.totalDuration = TimeUtil.millisToDurationPrintable(e.getValue().totalDuration());
+ BuildTimeRecord val = e.getValue();
+ buildTimeRecordUi.averageDuration = TimeUtil.millisToDurationPrintable(val.avgDuration());
+ buildTimeRecordUi.totalDuration = TimeUtil.millisToDurationPrintable(val.totalDuration());
+
+ buildTimeRecordUi.setCnt(val.count());
+
return buildTimeRecordUi;
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
index 09eb044..dca9293 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/BuildChainProcessor.java
@@ -21,6 +21,7 @@ import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
@@ -303,13 +304,23 @@ public class BuildChainProcessor {
ctx.setChanges(tcIgnited.getAllChanges(buildCompacted.changes()));
- ParametersCompacted parameters = buildCompacted.parameters();
- if (parameters != null)
- ctx.addTagsFromParameters(parameters, tcIgnited.config(), this.compactor);
+ ctx.addTags(SingleBuildRunCtx.getBuildTagsFromParameters(tcIgnited.config(), compactor, buildCompacted));
return ctx;
}
+
+ public List<Future<FatBuildCompacted>> replaceWithRecent(FatBuildCompacted build,
+ Map<Integer, Future<FatBuildCompacted>> allBuildsMap,
+ ITeamcityIgnited tcIgn) {
+
+ return replaceWithRecent(Collections.singletonList(build), 1,
+ LatestRebuildMode.LATEST,
+ allBuildsMap,
+ SyncMode.RELOAD_QUEUED,
+ tcIgn, null);
+ }
+
@SuppressWarnings("WeakerAccess")
@Nonnull
@AutoProfiling
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SingleBuildRunCtx.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SingleBuildRunCtx.java
index fdd9f1f..77ddf63 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SingleBuildRunCtx.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/chain/SingleBuildRunCtx.java
@@ -33,7 +33,6 @@ import java.util.regex.Pattern;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-
import org.apache.ignite.ci.teamcity.ignited.buildtype.ParametersCompacted;
import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
@@ -268,13 +267,18 @@ public class SingleBuildRunCtx implements ISuiteResults {
return tags;
}
- public void addTagsFromParameters(ParametersCompacted parameters, ITcServerConfig tcCfg,
- IStringCompactor compactor) {
+ public static Set<String> getBuildTagsFromParameters(ITcServerConfig tcCfg,
+ IStringCompactor compactor, FatBuildCompacted fatBuildCompacted) {
+ ParametersCompacted parameters = fatBuildCompacted.parameters();
+ if (parameters == null)
+ return Collections.emptySet();
+
+ HashSet<String> tags = new HashSet<>();
for (IBuildParameterSpec parm0 : tcCfg.filteringParameters()) {
if (!parm0.isFilled())
continue;
- String propVal = getPropertyOrSpecialValue(parameters, compactor, parm0.name());
+ String propVal = getPropertyOrSpecialValue(parameters, compactor, parm0.name(), fatBuildCompacted);
if (Strings.isNullOrEmpty(propVal))
continue;
@@ -283,35 +287,37 @@ public class SingleBuildRunCtx implements ISuiteResults {
.filter(pvs -> {
String valRegExp = pvs.valueRegExp();
- if(!Strings.isNullOrEmpty(valRegExp))
+ if (!Strings.isNullOrEmpty(valRegExp))
return Pattern.compile(valRegExp).matcher(propVal).find();
String exactVal = pvs.value();
- if(!Strings.isNullOrEmpty(exactVal))
+ if (!Strings.isNullOrEmpty(exactVal))
return Objects.equals(exactVal, propVal);
return false;
})
.findAny()
- .ifPresent(v -> addTag(v.label()));
+ .ifPresent(v -> tags.add(v.label()));
}
+ return tags;
}
/**
* @param parameters Parameters from build.
* @param compactor Compactor.
* @param parmKey Parmeters key.
+ * @param fatBuildCompacted
*/
- public String getPropertyOrSpecialValue(ParametersCompacted parameters, IStringCompactor compactor,
- String parmKey) {
+ public static String getPropertyOrSpecialValue(ParametersCompacted parameters, IStringCompactor compactor,
+ String parmKey, FatBuildCompacted fatBuildCompacted) {
String propVal;
if (ITeamcity.SUITE_ID_PROPERTY.equals(parmKey))
- propVal = suiteId();
+ propVal = fatBuildCompacted.buildTypeId(compactor);
else if (ITeamcity.SUITE_NAME_PROPERTY.equals(parmKey))
- propVal = suiteName();
+ propVal = fatBuildCompacted.buildTypeName(compactor);
else
propVal = parameters.getProperty(compactor, parmKey);
@@ -338,4 +344,8 @@ public class SingleBuildRunCtx implements ISuiteResults {
public int buildTypeIdId() {
return buildCompacted.buildTypeId();
}
+
+ public void addTags(Set<String> strings) {
+ this.tags.addAll(strings);
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueList.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/BlameCandidate.java
similarity index 65%
copy from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueList.java
copy to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/BlameCandidate.java
index d6e14a3..2b2feec 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueList.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/BlameCandidate.java
@@ -14,26 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.ignite.tcbot.engine.defect;
-package org.apache.ignite.ci.issue;
+import org.apache.ignite.tcbot.persistence.IStringCompactor;
+import org.apache.ignite.tcbot.persistence.Persisted;
-import java.util.List;
+@Persisted
+public class BlameCandidate {
+ private int vcsUsername = -1;
-public class IssueList {
-
- public String branch;
-
- private List<Issue> issues;
-
- public IssueList(List<Issue> all) {
- issues = all;
- }
-
- public List<Issue> getIssues() {
- return issues;
+ public void vcsUsername(int username) {
+ vcsUsername = username;
}
- public void setIssues(List<Issue> issues) {
- this.issues = issues;
+ public String vcsUsername(IStringCompactor compactor) {
+ return compactor.getStringFromId(vcsUsername);
}
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/CommitCompacted.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/CommitCompacted.java
new file mode 100644
index 0000000..7ab0cfc
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/CommitCompacted.java
@@ -0,0 +1,77 @@
+/*
+ * 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.tcbot.engine.defect;
+
+import java.util.Arrays;
+import org.apache.ignite.tcbot.persistence.Persisted;
+
+@Persisted
+public class CommitCompacted implements Comparable<CommitCompacted> {
+ /** Sha of the commit. */
+ private byte[] data;
+
+ public CommitCompacted(byte[] data) {
+ this.data = data;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ CommitCompacted commit = (CommitCompacted)o;
+ return Arrays.equals(data, commit.data);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Arrays.hashCode(data);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int compareTo(CommitCompacted o) {
+ return compare(data, o.data);
+ }
+
+ public static int compare(byte[] a, byte[] b) {
+ if (a == b)
+ return 0;
+ if (a == null || b == null)
+ return a == null ? -1 : 1;
+
+ int i = mismatch(a, b,
+ Math.min(a.length, b.length));
+ if (i >= 0)
+ return Byte.compare(a[i], b[i]);
+
+ return a.length - b.length;
+ }
+
+ public static int mismatch(byte[] a,
+ byte[] b,
+ int len) {
+
+ int i = 0;
+ for (; i < len; i++) {
+ if (a[i] != b[i])
+ return i;
+ }
+ return -1;
+ }
+
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectCompacted.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectCompacted.java
new file mode 100644
index 0000000..a0c105b
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectCompacted.java
@@ -0,0 +1,164 @@
+/*
+ * 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.tcbot.engine.defect;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.tcbot.persistence.IStringCompactor;
+
+public class DefectCompacted {
+ /** Syntetic Defect Id. */
+ private int id;
+
+ private int tcBranch = -1;
+
+ /** Tc server code hashcode. */
+ private int tcSrvId = -1;
+
+ /** Tc server code compactor string ID. */
+ private int tcSrvCodeCid = -1;
+
+ /** Tracked branch Compactor string ID. */
+ private int trackedBranchCid = -1;
+
+ /** Resolved by username id. */
+ private int resolvedByUsernameId = -1;
+ /** Commits hashes involved. */
+ private List<CommitCompacted> commits = new ArrayList<>();
+
+ /** Blame candidates. */
+ private List<BlameCandidate> blameCandidates = new ArrayList<>();
+
+ private Map<Integer, DefectFirstBuild> buildsInvolved = new HashMap<>();
+ private Map<Integer, ChangeCompacted> changes = new HashMap<>();
+
+ public DefectCompacted(int id) {
+ this.id = id;
+ }
+
+ public int resolvedByUsernameId() {
+ return resolvedByUsernameId;
+ }
+
+ /**
+ * @param collect Collected commits, should be sorted.
+ */
+ public boolean sameCommits(List<CommitCompacted> collect) {
+ return commits.equals(collect);
+ }
+
+ /**
+ * @param collect Collected commits, should be sorted.
+ */
+ public DefectCompacted commits(List<CommitCompacted> collect) {
+ commits.clear();
+ commits.addAll(collect);
+
+ return this;
+ }
+
+ public Map<Integer, DefectFirstBuild> buildsInvolved() {
+ return Collections.unmodifiableMap(buildsInvolved);
+ }
+
+ public DefectFirstBuild computeIfAbsent(FatBuildCompacted build) {
+ return buildsInvolved.computeIfAbsent(build.id(), k -> new DefectFirstBuild(build));
+ }
+
+ public int tcSrvId() {
+ return tcSrvId;
+ }
+
+ public void trackedBranchCidSetIfEmpty(int trackedBranchCid) {
+ if (this.trackedBranchCid <= 0)
+ this.trackedBranchCid = trackedBranchCid;
+
+ }
+
+ /** */
+ public String tcBranch(IStringCompactor compactor) {
+ return compactor.getStringFromId(tcBranch);
+ }
+
+ /** */
+ public String tcSrvCode(IStringCompactor compactor) {
+ return compactor.getStringFromId(tcSrvCodeCid);
+ }
+
+ /** */
+ public int id() {
+ return id;
+ }
+
+ /** */
+ public DefectCompacted tcBranch(int tcBranch) {
+ this.tcBranch = tcBranch;
+
+ return this;
+ }
+
+ /** */
+ public DefectCompacted tcSrvId(int srvId) {
+ this.tcSrvId = srvId;
+ return this;
+ }
+
+ /** */
+ public DefectCompacted tcSrvCodeCid(int cid) {
+ tcSrvCodeCid = cid;
+
+ return this;
+ }
+
+ public void id(int id) {
+ this.id = id;
+ }
+
+ public boolean hasBuild(int id) {
+ return buildsInvolved.containsKey(id);
+ }
+
+ public List<BlameCandidate> blameCandidates() {
+ if (blameCandidates == null)
+ return Collections.emptyList();
+
+ return Collections.unmodifiableList(blameCandidates);
+ }
+
+ public DefectCompacted changeMap(Map<Integer, ChangeCompacted> changes) {
+ this.changes = changes;
+
+ return this;
+ }
+
+ public Map<Integer, ChangeCompacted> changeMap() {
+ return changes;
+ }
+
+ public void addBlameCandidate(BlameCandidate candidate) {
+ blameCandidates.add(candidate);
+ }
+
+ public int trackedBranchCid() {
+ return trackedBranchCid;
+ }
+}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectFirstBuild.java
similarity index 52%
copy from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
copy to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectFirstBuild.java
index 348a623..2531034 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectFirstBuild.java
@@ -14,41 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.ignite.tcbot.engine.defect;
-package org.apache.ignite.ci.issue;
-
-import com.google.common.base.MoreObjects;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
import org.apache.ignite.tcbot.persistence.Persisted;
@Persisted
-public class IssueKey {
- public String server;
- public Integer buildId;
- public String testOrBuildName;
-
- public IssueKey(String srv, Integer buildId, String testOrBuildName) {
- this.server = srv;
- this.buildId = buildId;
- this.testOrBuildName = testOrBuildName;
- }
+public class DefectFirstBuild {
+ private FatBuildCompacted build;
- public String getServer() {
- return server;
+ private Set<DefectIssue> issues = new HashSet<>();
+
+ public DefectFirstBuild(FatBuildCompacted build) {
+ this.build = build;
}
- public Integer getBuildId() {
- return buildId;
+ public DefectFirstBuild addIssue(int typeCid, Integer testNameCid) {
+ issues.add(new DefectIssue(typeCid, testNameCid));
+
+ return this;
}
- public String getTestOrBuildName() {
- return testOrBuildName;
+ public FatBuildCompacted build() {
+ return build;
}
- @Override public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("server", server)
- .add("buildId", buildId)
- .add("testOrBuildName", testOrBuildName)
- .toString();
+ public Set<DefectIssue> issues() {
+ return Collections.unmodifiableSet(issues);
}
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectIssue.java
similarity index 51%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectIssue.java
index 348a623..62304ec 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueKey.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectIssue.java
@@ -14,41 +14,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.ignite.tcbot.engine.defect;
-package org.apache.ignite.ci.issue;
-
-import com.google.common.base.MoreObjects;
+import java.util.Objects;
import org.apache.ignite.tcbot.persistence.Persisted;
@Persisted
-public class IssueKey {
- public String server;
- public Integer buildId;
- public String testOrBuildName;
-
- public IssueKey(String srv, Integer buildId, String testOrBuildName) {
- this.server = srv;
- this.buildId = buildId;
- this.testOrBuildName = testOrBuildName;
- }
+public class DefectIssue {
+ private int issueTypeCode;
+ private int testOrSuiteName;
- public String getServer() {
- return server;
+ public DefectIssue(int issueTypeCode, Integer testNameCid) {
+ this.issueTypeCode = issueTypeCode;
+ testOrSuiteName = testNameCid;
}
- public Integer getBuildId() {
- return buildId;
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ DefectIssue issue = (DefectIssue)o;
+ return issueTypeCode == issue.issueTypeCode &&
+ testOrSuiteName == issue.testOrSuiteName;
}
- public String getTestOrBuildName() {
- return testOrBuildName;
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return Objects.hash(issueTypeCode, testOrSuiteName);
}
- @Override public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("server", server)
- .add("buildId", buildId)
- .add("testOrBuildName", testOrBuildName)
- .toString();
+ public int testNameCid() {
+ return testOrSuiteName;
}
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectKey.java
similarity index 77%
copy from tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
copy to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectKey.java
index f411d83..cb8beb1 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectKey.java
@@ -14,11 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.ignite.tcbot.engine.ui;
+package org.apache.ignite.tcbot.engine.defect;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefectKey {
+ private int srvId;
+ private int branchId;
+ private List<CommitCompacted> commits = new ArrayList<>();
-@SuppressWarnings({"WeakerAccess", "PublicField"})
-public class BuildTimeRecordUi {
- public String buildType;
- public String averageDuration;
- public String totalDuration;
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectsStorage.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectsStorage.java
new file mode 100644
index 0000000..2efb4e2
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/defect/DefectsStorage.java
@@ -0,0 +1,155 @@
+/*
+ * 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.tcbot.engine.defect;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import javax.annotation.concurrent.NotThreadSafe;
+import javax.cache.Cache;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteAtomicSequence;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.ScanQuery;
+import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
+import org.apache.ignite.ci.teamcity.ignited.change.ChangeDao;
+import org.apache.ignite.ci.teamcity.ignited.fatbuild.FatBuildCompacted;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.tcbot.persistence.CacheConfigs;
+
+@NotThreadSafe
+public class DefectsStorage {
+ /** Bot detected defects. */
+ public static final String BOT_DETECTED_DEFECTS = "botDetectedDefects";
+ /** Bot detected defects sequence. */
+ public static final String BOT_DETECTED_DEFECTS_SEQ = "botDetectedDefectsSeq";
+
+ @Inject
+ private Provider<Ignite> igniteProvider;
+ @Inject
+ private ChangeDao changeDao;
+
+
+ public DefectsStorage() {
+ }
+
+ private IgniteAtomicSequence sequence() {
+ return getIgnite().atomicSequence(BOT_DETECTED_DEFECTS_SEQ, 0, true);
+ }
+
+ private IgniteCache<Integer, DefectCompacted> cache() {
+ return botDetectedIssuesCache(getIgnite());
+ }
+
+ private Ignite getIgnite() {
+ return igniteProvider.get();
+ }
+
+ public static IgniteCache<Integer, DefectCompacted> botDetectedIssuesCache(Ignite ignite) {
+ CacheConfiguration<Integer, DefectCompacted> ccfg = CacheConfigs.getCacheV2TxConfig(BOT_DETECTED_DEFECTS);
+
+ ccfg.setQueryEntities(Collections.singletonList(new QueryEntity(Integer.class, DefectCompacted.class)));
+
+ return ignite.getOrCreateCache(ccfg);
+ }
+
+ public DefectCompacted merge(
+ int tcSrvCodeCid,
+ final int srvId,
+ FatBuildCompacted fatBuild,
+ BiFunction<Integer, DefectCompacted, DefectCompacted> function) {
+
+ IgniteCache<Integer, DefectCompacted> cache = cache();
+
+ try (QueryCursor<Cache.Entry<Integer, DefectCompacted>> qry = cache.query(new ScanQuery<Integer, DefectCompacted>()
+ .setFilter((k, v) -> v.resolvedByUsernameId() < 1 && v.tcSrvId() == srvId))) {
+ for (Cache.Entry<Integer, DefectCompacted> next : qry) {
+ DefectCompacted openDefect = next.getValue();
+
+ if (openDefect.hasBuild(fatBuild.id()))
+ return processExisting(function, cache, next.getKey(), openDefect);
+ }
+ }
+
+ int[] changes = fatBuild.changes();
+ Map<Integer, ChangeCompacted> changeList = changeDao.getAll(srvId, changes);
+
+ List<CommitCompacted> commitsToUse = changeList
+ .values()
+ .stream()
+ .map(ChangeCompacted::commitVersion)
+ .map(CommitCompacted::new)
+ .sorted(CommitCompacted::compareTo)
+ .collect(Collectors.toList());
+
+ try (QueryCursor<Cache.Entry<Integer, DefectCompacted>> qry = cache.query(new ScanQuery<Integer, DefectCompacted>()
+ .setFilter((k, v) -> v.resolvedByUsernameId() < 1 && v.tcSrvId() == srvId))) {
+ for (Cache.Entry<Integer, DefectCompacted> next : qry) {
+ DefectCompacted openDefect = next.getValue();
+
+ if (openDefect.sameCommits(commitsToUse))
+ return processExisting(function, cache, next.getKey(), openDefect);
+ }
+ }
+
+ int id = (int)sequence().incrementAndGet();
+
+ DefectCompacted defect = new DefectCompacted(id)
+ .commits(commitsToUse)
+ .changeMap(changeList)
+ .tcBranch(fatBuild.branchName())
+ .tcSrvId(srvId)
+ .tcSrvCodeCid(tcSrvCodeCid);
+
+ DefectCompacted defectT = function.apply(id, defect);
+
+ boolean putSuccess = cache.putIfAbsent(id, defectT);
+
+ return defectT;
+ }
+
+ public DefectCompacted processExisting(BiFunction<Integer, DefectCompacted, DefectCompacted> function,
+ IgniteCache<Integer, DefectCompacted> cache, Integer id, DefectCompacted openDefect) {
+ DefectCompacted defect = function.apply(id, openDefect);
+
+ defect.id(id);
+
+ cache.put(id, defect);
+
+ return defect;
+ }
+
+ public List<DefectCompacted> loadAllDefects() {
+ List<DefectCompacted> res = new ArrayList<>();
+ try (QueryCursor<Cache.Entry<Integer, DefectCompacted>> qry = cache().query(new ScanQuery<Integer, DefectCompacted>()
+ .setFilter((k, v) -> v.resolvedByUsernameId() < 1))) {
+ for (Cache.Entry<Integer, DefectCompacted> next : qry) {
+ DefectCompacted openDefect = next.getValue();
+ openDefect.id(next.getKey());
+ res.add(openDefect);
+ }
+ }
+ return res;
+ }
+}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IIssuesStorage.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IIssuesStorage.java
similarity index 97%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IIssuesStorage.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IIssuesStorage.java
index af7a992..df19ae7 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/issue/IIssuesStorage.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IIssuesStorage.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.ci.tcbot.issue;
+package org.apache.ignite.tcbot.engine.issue;
import java.util.stream.Stream;
import javax.annotation.Nullable;
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueType.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java
similarity index 97%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueType.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java
index a690614..b7b6cce 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueType.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssueType.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.ci.issue;
+package org.apache.ignite.tcbot.engine.issue;
/**
* Type of Issue detectable by the Bot.
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssuesStorage.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssuesStorage.java
similarity index 93%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssuesStorage.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssuesStorage.java
index a18294d..1171db2 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssuesStorage.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/IssuesStorage.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.ci.issue;
+package org.apache.ignite.tcbot.engine.issue;
import java.util.HashMap;
import java.util.stream.Stream;
@@ -26,8 +26,9 @@ import javax.inject.Inject;
import javax.inject.Provider;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
-import org.apache.ignite.ci.db.TcHelperDb;
-import org.apache.ignite.ci.tcbot.issue.IIssuesStorage;
+import org.apache.ignite.ci.issue.Issue;
+import org.apache.ignite.ci.issue.IssueKey;
+import org.apache.ignite.tcbot.persistence.CacheConfigs;
/**
*
@@ -50,7 +51,7 @@ public class IssuesStorage implements IIssuesStorage {
}
public static IgniteCache<IssueKey, Issue> botDetectedIssuesCache(Ignite ignite) {
- return ignite.getOrCreateCache(TcHelperDb.getCacheV2TxConfig(BOT_DETECTED_ISSUES));
+ return ignite.getOrCreateCache(CacheConfigs.getCacheV2TxConfig(BOT_DETECTED_ISSUES));
}
/** {@inheritDoc} */
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java
new file mode 100644
index 0000000..1d4e0af
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectSummaryUi.java
@@ -0,0 +1,94 @@
+/*
+ * 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.tcbot.engine.ui;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.ignite.tcbot.engine.defect.DefectCompacted;
+import org.apache.ignite.tcbot.persistence.IStringCompactor;
+
+public class BoardDefectSummaryUi {
+ private final transient DefectCompacted defect;
+ private final transient IStringCompactor compactor;
+
+ public String branch;
+
+ public Integer cntIssues;
+ public Integer fixedIssues;
+ public Integer notFixedIssues;
+
+ public List<String> testOrSuitesAffected = new ArrayList<>();
+ public Set<String> tags = new HashSet<>();
+
+ public BoardDefectSummaryUi(DefectCompacted defect, IStringCompactor compactor) {
+ this.defect = defect;
+ this.compactor = compactor;
+ }
+
+ public Set<String> getTags() {
+ return tags;
+ }
+
+ public List<String> getSuites() {
+ return defect.buildsInvolved().values().stream().map(
+ b -> b.build().buildTypeName()
+ ).distinct().map(compactor::getStringFromId).collect(Collectors.toList());
+ }
+
+ public List<String> getBlameCandidates() {
+ return defect.blameCandidates().stream().map(c -> c.vcsUsername(compactor)).collect(Collectors.toList());
+ }
+
+ public String getTrackedBranch() {
+ return compactor.getStringFromId(defect.trackedBranchCid());
+ }
+
+ public int getId() {
+ return defect.id();
+ }
+
+ public void addIssue(String testOrBuildName, String trackedBranchName) {
+ if (cntIssues == null)
+ cntIssues = 0;
+
+ cntIssues++;
+
+ testOrSuitesAffected.add(testOrBuildName);
+
+ }
+
+ public void addFixedIssue() {
+ if (fixedIssues == null)
+ fixedIssues = 0;
+
+ fixedIssues++;
+ }
+
+ public void addNotFixedIssue() {
+ if (notFixedIssues == null)
+ notFixedIssues = 0;
+
+ notFixedIssues++;
+ }
+
+ public void addTags(Set<String> parameters) {
+ this.tags.addAll(parameters);
+ }
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardSummaryUi.java
similarity index 71%
copy from tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
copy to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardSummaryUi.java
index f411d83..8063935 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardSummaryUi.java
@@ -16,9 +16,18 @@
*/
package org.apache.ignite.tcbot.engine.ui;
-@SuppressWarnings({"WeakerAccess", "PublicField"})
-public class BuildTimeRecordUi {
- public String buildType;
- public String averageDuration;
- public String totalDuration;
+import java.util.List;
+import java.util.ArrayList;
+
+public class BoardSummaryUi {
+ private List<BoardDefectSummaryUi> defects = new ArrayList<>();
+
+
+ public void addDefect(BoardDefectSummaryUi defect) {
+ this.defects.add(defect);
+ }
+
+ public List<BoardDefectSummaryUi> getDefects() {
+ return defects;
+ }
}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
index f411d83..3e5bb3d 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeRecordUi.java
@@ -21,4 +21,15 @@ public class BuildTimeRecordUi {
public String buildType;
public String averageDuration;
public String totalDuration;
+
+ private Integer cnt;
+
+ /** */
+ public Integer getCnt() {
+ return cnt;
+ }
+
+ public void setCnt(Integer cnt) {
+ this.cnt = cnt;
+ }
}
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueList.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/IssueListUi.java
similarity index 87%
rename from ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueList.java
rename to tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/IssueListUi.java
index d6e14a3..2299187 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/issue/IssueList.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/IssueListUi.java
@@ -15,17 +15,17 @@
* limitations under the License.
*/
-package org.apache.ignite.ci.issue;
+package org.apache.ignite.tcbot.engine.ui;
import java.util.List;
+import org.apache.ignite.ci.issue.Issue;
-public class IssueList {
-
+public class IssueListUi {
public String branch;
private List<Issue> issues;
- public IssueList(List<Issue> all) {
+ public IssueListUi(List<Issue> all) {
issues = all;
}
diff --git a/tcbot-persistence/src/main/java/org/apache/ignite/tcbot/persistence/CacheConfigs.java b/tcbot-persistence/src/main/java/org/apache/ignite/tcbot/persistence/CacheConfigs.java
index 7b9d757..24b5ab3 100644
--- a/tcbot-persistence/src/main/java/org/apache/ignite/tcbot/persistence/CacheConfigs.java
+++ b/tcbot-persistence/src/main/java/org/apache/ignite/tcbot/persistence/CacheConfigs.java
@@ -16,6 +16,7 @@
*/
package org.apache.ignite.tcbot.persistence;
+import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
import org.apache.ignite.configuration.CacheConfiguration;
@@ -42,4 +43,10 @@ public class CacheConfigs {
return ccfg;
}
+
+ @Nonnull
+ public static <K, V> CacheConfiguration<K, V> getCacheV2TxConfig(String name) {
+ return CacheConfigs.<K, V>getCacheV2Config(name).setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+ }
+
}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeCompacted.java
index 45aafd8..37072de 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeCompacted.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeCompacted.java
@@ -143,9 +143,9 @@ public class ChangeCompacted implements IVersionedEntity {
/** {@inheritDoc} */
@Override public int hashCode() {
- int result = Objects.hash(_ver, id, vcsUsername, tcUserId, tcUserUsername, tcUserFullname, date);
- result = 31 * result + Arrays.hashCode(version);
- return result;
+ int res = Objects.hash(_ver, id, vcsUsername, tcUserId, tcUserUsername, tcUserFullname, date);
+ res = 31 * res + Arrays.hashCode(version);
+ return res;
}
/**
@@ -154,4 +154,15 @@ public class ChangeCompacted implements IVersionedEntity {
public String commitFullVersion() {
return DatatypeConverter.printHexBinary(version).toLowerCase();
}
+
+ /**
+ *
+ */
+ public byte[] commitVersion() {
+ return version;
+ }
+
+ public int vcsUsername() {
+ return vcsUsername;
+ }
}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeDao.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeDao.java
index b79e5fd..9ab12df 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeDao.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/change/ChangeDao.java
@@ -17,6 +17,7 @@
package org.apache.ignite.ci.teamcity.ignited.change;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -24,10 +25,9 @@ import javax.inject.Inject;
import javax.inject.Provider;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.tcbot.common.interceptor.AutoProfiling;
import org.apache.ignite.tcbot.persistence.CacheConfigs;
-import org.apache.ignite.tcbot.persistence.IStringCompactor;
-import org.apache.ignite.configuration.CacheConfiguration;
public class ChangeDao {
/** Cache name */
@@ -91,12 +91,19 @@ public class ChangeDao {
}
@AutoProfiling
- public Map<Long, ChangeCompacted> getAll(int srvIdMaskHigh, int[] changeIds) {
+ public Map<Integer, ChangeCompacted> getAll(int srvIdMaskHigh, int[] changeIds) {
final Set<Long> collect = new HashSet<>();
for (int changeId : changeIds)
collect.add(changeIdToCacheKey(srvIdMaskHigh, changeId));
- return changesCache.getAll(collect);
+ final Map<Integer, ChangeCompacted> changes = new HashMap<>();
+ changesCache.getAll(collect).forEach((k, v) -> {
+ final int changeId = ChangeDao.cacheKeyToChangeId(k);
+
+ changes.put(changeId, v);
+ });
+
+ return changes;
}
}
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 8b52eb1..42b36c4 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
@@ -533,7 +533,11 @@ public class FatBuildCompacted extends BuildRefCompacted implements IVersionedEn
}
public String buildTypeName(IStringCompactor compactor) {
- return compactor.getStringFromId(name);
+ return compactor.getStringFromId(buildTypeName());
+ }
+
+ public int buildTypeName() {
+ return name;
}
public String projectId(IStringCompactor compactor) {
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java
index e6d0778..ad40e79 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/TeamcityIgnitedImpl.java
@@ -517,7 +517,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
Stream<Integer> allIds = Stream.concat(Stream.of(build.getId()), deps.stream().map(BuildRef::getId));
- //todo may add additional parameter: load builds into DB in sync/async fashion
+ //todo may addBuild additional parameter: load builds into DB in sync/async fashion
buildRefSync.runActualizeBuildRefs(srvCode, BuildRefSync.SyncMode.ULTRAFAST, allIds.collect(Collectors.toSet()), conn);
return build;
@@ -613,16 +613,7 @@ public class TeamcityIgnitedImpl implements ITeamcityIgnited {
/** {@inheritDoc} */
@AutoProfiling
@Override public Collection<ChangeCompacted> getAllChanges(int[] changeIds) {
- final Map<Long, ChangeCompacted> all = changesDao.getAll(srvIdMaskHigh, changeIds);
-
- final Map<Integer, ChangeCompacted> changes = new HashMap<>();
-
- //todo support change version upgrade
- all.forEach((k, v) -> {
- final int changeId = ChangeDao.cacheKeyToChangeId(k);
-
- changes.put(changeId, v);
- });
+ final Map<Integer, ChangeCompacted> changes = changesDao.getAll(srvIdMaskHigh, changeIds);
for (int changeId : changeIds) {
if (!changes.containsKey(changeId)) {
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/FatBuildDao.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/FatBuildDao.java
index 5b2220c..439adca 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/FatBuildDao.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/FatBuildDao.java
@@ -279,7 +279,7 @@ public class FatBuildDao {
int srvId = BuildRefDao.cacheKeyToSrvId(key);
boolean hasTimeout = build.hasBuildProblemType(timeoutProblemCode);
- res.add(srvId, buildTypeId, runningTime, hasTimeout);
+ res.addBuild(srvId, buildTypeId, runningTime, hasTimeout);
}
});
}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ITest.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ITest.java
index 63bd32a..508e41a 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ITest.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/ITest.java
@@ -48,9 +48,15 @@ public interface ITest {
* @param successStatus Success status code.
*/
public default boolean isFailedButNotMuted(int successStatus) {
- return successStatus != status() && !isMutedOrIgnored();
+ return isFailedTest(successStatus) && !isMutedOrIgnored();
}
+ public default boolean isFailedTest(int successStatus) {
+ return successStatus != status();
+ }
+
+ public boolean isFailedTest(IStringCompactor compactor);
+
public default boolean isMutedOrIgnored() {
return isMutedTest() || isIgnoredTest();
}
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 4531efc..15ec251 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
@@ -354,6 +354,10 @@ public class TestCompactedV2 implements ITest {
return duration < 0 ? null : duration;
}
+ @Override public boolean isFailedTest(IStringCompactor compactor) {
+ return isFailedTest(statusSuccess(compactor));
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return MoreObjects.toStringHelper(this)
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/LogMsgToWarn.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/LogMsgToWarn.java
index 573d498..78bec57 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/LogMsgToWarn.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildlog/LogMsgToWarn.java
@@ -25,7 +25,7 @@ import org.apache.ignite.tcservice.model.result.problems.ProblemOccurrence;
*/
//todo make non static
//todo include test name
-//todo add NPE
+//todo addBuild NPE
public class LogMsgToWarn {
private static final String JAVA_LEVEL_DEADLOCK_TXT = " Java-level deadlock:";
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 654b08c..d942c12 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
@@ -352,4 +352,8 @@ public class BuildRefDao {
public IgniteCache<Long, BuildRefCompacted> buildRefsCache() {
return buildRefsCache;
}
+
+ public BuildRefCompacted get(int srvId, Integer buildId) {
+ return buildRefsCache.get(buildIdToCacheKey(srvId, buildId));
+ }
}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeRecord.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeRecord.java
index 63e8026..e88754b 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeRecord.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeRecord.java
@@ -35,4 +35,8 @@ public class BuildTimeRecord {
public long totalDuration() {
return totaltime;
}
+
+ public int count() {
+ return cnt;
+ }
}
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeResult.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeResult.java
index fcf6675..f48f8a8 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeResult.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeResult.java
@@ -26,10 +26,12 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
public class BuildTimeResult {
+ /** Build time summary by build type, map from (srvId||buildTypeId)->Invocations summary. */
private Map<Long, BuildTimeRecord> btByBuildType = new HashMap<>();
+ /** Timed out builds: Build time summary by build type, map from (srvId||buildTypeId)->Invocations summary. */
private Map<Long, BuildTimeRecord> timedOutByBuildType = new HashMap<>();
- public void add(int srvId, int buildTypeId, long runningTime, boolean hasTimeout) {
+ public void addBuild(int srvId, int buildTypeId, long runningTime, boolean hasTimeout) {
long cacheKey = buildTypeToCacheKey(srvId, buildTypeId);
btByBuildType.computeIfAbsent(cacheKey, k -> new BuildTimeRecord()).addInvocation(runningTime);
@@ -77,14 +79,14 @@ public class BuildTimeResult {
private Stream<Map.Entry<Long, BuildTimeRecord>> filtered(
Map<Long, BuildTimeRecord> map,
- Set<Integer> availableServers,
+ Set<Integer> availableSrvs,
long minAvgDurationMs,
long totalDurationMs) {
return map.entrySet().stream()
.filter(e -> {
Long key = e.getKey();
int srvId = cacheKeyToSrvId(key);
- return availableServers.contains(srvId);
+ return availableSrvs.contains(srvId);
})
.filter(e -> e.getValue().avgDuration() > minAvgDurationMs)
.filter(e -> e.getValue().totalDuration() > totalDurationMs);