This is an automated email from the ASF dual-hosted git repository. dpavlov pushed a commit to branch partial-pr-data-display in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git
The following commit(s) were added to refs/heads/partial-pr-data-display by this push: new 40f5b9a Show count of blockers according current branch statistics 40f5b9a is described below commit 40f5b9adbd20ce948f801bc32780e9b41dd44881 Author: Dmitriy Pavlov <dpav...@apache.org> AuthorDate: Fri Nov 16 22:04:35 2018 +0300 Show count of blockers according current branch statistics --- .../apache/ignite/ci/IgnitePersistentTeamcity.java | 12 +-- .../main/java/org/apache/ignite/ci/TcHelper.java | 105 ++------------------- .../ignite/ci/tcbot/chain/PrChainsProcessor.java | 105 +++++++++++++++++++++ .../ignite/ci/tcbot/visa/CurrentVisaStatus.java | 21 +++++ .../tcbot/visa/TcBotTriggerAndSignOffService.java | 22 ++++- .../ignite/ci/web/rest/visa/TcBotVisaService.java | 15 +++ ignite-tc-helper-web/src/main/webapp/js/prs-1.0.js | 47 +++++++-- 7 files changed, 213 insertions(+), 114 deletions(-) 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 2229694..c7f0e11 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 @@ -909,8 +909,7 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea return teamcity.triggerBuild(buildTypeId, branchName, cleanRebuild, queueAtTop); } - @Override - public ProblemOccurrences getProblems(int buildId) { + @Override public ProblemOccurrences getProblems(int buildId) { return teamcity.getProblems(buildId); } @@ -924,18 +923,15 @@ public class IgnitePersistentTeamcity implements IAnalyticsEnabledTeamcity, ITea return problems; } - @Override - public Statistics getStatistics(int buildId) { + @Override public Statistics getStatistics(int buildId) { return teamcity.getStatistics(buildId); } - @Override - public ChangesList getChangesList(int buildId) { + @Override public ChangesList getChangesList(int buildId) { return teamcity.getChangesList(buildId); } - @Override - public Change getChange(int changeId) { + @Override public Change getChange(int changeId) { return teamcity.getChange(changeId); } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java index 9a0c891..061c7c0 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/TcHelper.java @@ -181,7 +181,9 @@ public class TcHelper implements ITcHelper, IJiraIntegration { JiraCommentResponse res; try { - List<SuiteCurrentStatus> suitesStatuses = getSuitesStatuses(buildTypeId, build.branchName, srvId, prov); + List<SuiteCurrentStatus> suitesStatuses = prChainsProcessor.getSuitesStatuses(buildTypeId, build.branchName, srvId, prov); + if (suitesStatuses == null) + return new Visa("JIRA wasn't commented - no finished builds to analyze."); String comment = generateJiraComment(suitesStatuses, build.webUrl); @@ -202,38 +204,15 @@ public class TcHelper implements ITcHelper, IJiraIntegration { return new Visa(JIRA_COMMENTED, res, blockers); } + /** * @param buildTypeId Suite name. * @param branchForTc Branch for TeamCity. * @param srvId Server id. * @param prov Credentials. - * @return List of suites with possible blockers. + * @param webUrl Build URL. + * @return Comment, which should be sent to the JIRA ticket. */ - public List<SuiteCurrentStatus> getSuitesStatuses(String buildTypeId, - String branchForTc, - String srvId, - ICredentialsProv prov) { - List<SuiteCurrentStatus> res = new ArrayList<>(); - - TestFailuresSummary summary = prChainsProcessor.getTestFailuresSummary( - prov, srvId, buildTypeId, branchForTc, - FullQueryParams.LATEST, null, null, false, SyncMode.RELOAD_QUEUED); - - if (summary != null) { - for (ChainAtServerCurrentStatus server : summary.servers) { - if (!"apache".equals(server.serverName())) - continue; - - Map<String, List<SuiteCurrentStatus>> fails = findFailures(server); - - fails.forEach((k, v) -> res.addAll(v)); - } - } - - return res; - } - - /** */ private String generateJiraComment(List<SuiteCurrentStatus> suites, String webUrl) { StringBuilder res = new StringBuilder(); @@ -288,78 +267,6 @@ public class TcHelper implements ITcHelper, IJiraIntegration { return xmlEscapeText(res.toString()); } - /** - * @param buildTypeId Suite name. - * @param branchForTc Branch for TeamCity. - * @param srvId Server id. - * @param prov Credentials. - * @param webUrl Build URL. - * @return Comment, which should be sent to the JIRA ticket. - */ - private String generateJiraComment( - String buildTypeId, - String branchForTc, - String srvId, - ICredentialsProv prov, - String webUrl - ) { - return generateJiraComment(getSuitesStatuses(buildTypeId, branchForTc,srvId, prov), webUrl); - } - - /** - * @param srv Server. - * @return Failures for given server. - */ - private Map<String, List<SuiteCurrentStatus>> findFailures(ChainAtServerCurrentStatus srv) { - Map<String, List<SuiteCurrentStatus>> fails = new LinkedHashMap<>(); - - for (SuiteCurrentStatus suite : srv.suites) { - String suiteRes = suite.result.toLowerCase(); - String failType = null; - - if (suiteRes.contains("compilation")) - failType = "compilation"; - - if (suiteRes.contains("timeout")) - failType = "timeout"; - - if (suiteRes.contains("exit code")) - failType = "exit code"; - - if (suiteRes.contains(ProblemOccurrence.JAVA_LEVEL_DEADLOCK.toLowerCase())) - failType = "java level deadlock"; - - if (suiteRes.contains(ProblemOccurrence.BUILD_FAILURE_ON_MESSAGE.toLowerCase())) - failType = "build failure on message"; - - if (suiteRes.contains(ProblemOccurrence.BUILD_FAILURE_ON_METRIC.toLowerCase())) - failType = "build failure on metrics"; - - if (suiteRes.contains(MultBuildRunCtx.CANCELLED.toLowerCase())) - failType = MultBuildRunCtx.CANCELLED.toLowerCase(); - - if (failType == null) { - List<TestFailure> failures = new ArrayList<>(); - - for (TestFailure testFailure : suite.testFailures) { - if (testFailure.isNewFailedTest()) - failures.add(testFailure); - } - - if (!failures.isEmpty()) { - suite.testFailures = failures; - - failType = "failed tests"; - } - } - - if (failType != null) - fails.computeIfAbsent(failType, k -> new ArrayList<>()).add(suite); - } - - return fails; - } - public void close() { if (stop.compareAndSet(false, true)) detector.stop(); diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java index e87029c..c5988f0 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/chain/PrChainsProcessor.java @@ -17,7 +17,12 @@ package org.apache.ignite.ci.tcbot.chain; import com.google.common.base.Strings; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.Map; import org.apache.ignite.ci.IAnalyticsEnabledTeamcity; +import org.apache.ignite.ci.analysis.MultBuildRunCtx; +import org.apache.ignite.ci.tcmodel.result.problems.ProblemOccurrence; import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnited; import org.apache.ignite.ci.teamcity.ignited.ITeamcityIgnitedProvider; import org.apache.ignite.ci.teamcity.ignited.SyncMode; @@ -31,8 +36,11 @@ import org.apache.ignite.ci.github.pure.IGitHubConnection; import org.apache.ignite.ci.github.pure.IGitHubConnectionProvider; import org.apache.ignite.ci.user.ICredentialsProv; import org.apache.ignite.ci.web.model.current.ChainAtServerCurrentStatus; +import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus; +import org.apache.ignite.ci.web.model.current.TestFailure; import org.apache.ignite.ci.web.model.current.TestFailuresSummary; import org.apache.ignite.ci.web.rest.parms.FullQueryParams; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.inject.Inject; @@ -149,4 +157,101 @@ public class PrChainsProcessor { return res; } + + /** + * @param buildTypeId Suite name. + * @param branchForTc Branch for TeamCity. + * @param srvId Server id. + * @param prov Credentials. + * @return List of suites with possible blockers. + */ + @Nullable public List<SuiteCurrentStatus> getSuitesStatuses(String buildTypeId, + String branchForTc, + String srvId, + ICredentialsProv prov) { + SyncMode queued = SyncMode.RELOAD_QUEUED; + + return getSuitesStatuses(buildTypeId, branchForTc, srvId, prov, queued); + } + + + @Nullable public List<SuiteCurrentStatus> getSuitesStatuses(String buildTypeId, String branchForTc, String srvId, + ICredentialsProv prov, SyncMode queued) { + List<SuiteCurrentStatus> res = new ArrayList<>(); + + TestFailuresSummary summary = getTestFailuresSummary( + prov, srvId, buildTypeId, branchForTc, + FullQueryParams.LATEST, null, null, false, queued); + + boolean noBuilds = summary.servers.stream().anyMatch(s -> s.buildNotFound); + if(noBuilds) + return null; + + if (summary != null) { + for (ChainAtServerCurrentStatus server : summary.servers) { + if (!srvId.equals(server.serverName())) + continue; + + Map<String, List<SuiteCurrentStatus>> fails = findFailures(server); + + fails.forEach((k, v) -> res.addAll(v)); + } + } + + return res; + } + + /** + * @param srv Server. + * @return Failures for given server. + */ + private Map<String, List<SuiteCurrentStatus>> findFailures(ChainAtServerCurrentStatus srv) { + Map<String, List<SuiteCurrentStatus>> fails = new LinkedHashMap<>(); + + for (SuiteCurrentStatus suite : srv.suites) { + String suiteRes = suite.result.toLowerCase(); + String failType = null; + + if (suiteRes.contains("compilation")) + failType = "compilation"; + + if (suiteRes.contains("timeout")) + failType = "timeout"; + + if (suiteRes.contains("exit code")) + failType = "exit code"; + + if (suiteRes.contains(ProblemOccurrence.JAVA_LEVEL_DEADLOCK.toLowerCase())) + failType = "java level deadlock"; + + if (suiteRes.contains(ProblemOccurrence.BUILD_FAILURE_ON_MESSAGE.toLowerCase())) + failType = "build failure on message"; + + if (suiteRes.contains(ProblemOccurrence.BUILD_FAILURE_ON_METRIC.toLowerCase())) + failType = "build failure on metrics"; + + if (suiteRes.contains(MultBuildRunCtx.CANCELLED.toLowerCase())) + failType = MultBuildRunCtx.CANCELLED.toLowerCase(); + + if (failType == null) { + List<TestFailure> failures = new ArrayList<>(); + + for (TestFailure testFailure : suite.testFailures) { + if (testFailure.isNewFailedTest()) + failures.add(testFailure); + } + + if (!failures.isEmpty()) { + suite.testFailures = failures; + + failType = "failed tests"; + } + } + + if (failType != null) + fails.computeIfAbsent(failType, k -> new ArrayList<>()).add(suite); + } + + return fails; + } } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/CurrentVisaStatus.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/CurrentVisaStatus.java new file mode 100644 index 0000000..89da1ce --- /dev/null +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/CurrentVisaStatus.java @@ -0,0 +1,21 @@ +/* + * 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.tcbot.visa; + +public class CurrentVisaStatus { + public Integer blockers; +} diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java index d252e15..6a686ac 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/tcbot/visa/TcBotTriggerAndSignOffService.java @@ -39,15 +39,18 @@ import org.apache.ignite.ci.github.pure.IGitHubConnectionProvider; import org.apache.ignite.ci.jira.IJiraIntegration; import org.apache.ignite.ci.observer.BuildObserver; import org.apache.ignite.ci.observer.BuildsInfo; +import org.apache.ignite.ci.tcbot.chain.PrChainsProcessor; import org.apache.ignite.ci.tcmodel.result.Build; import org.apache.ignite.ci.teamcity.ignited.BuildRefCompacted; 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.ignited.SyncMode; import org.apache.ignite.ci.web.model.VisaRequest; import org.apache.ignite.ci.web.model.Visa; import org.apache.ignite.ci.user.ICredentialsProv; import org.apache.ignite.ci.web.model.SimpleResult; +import org.apache.ignite.ci.web.model.current.SuiteCurrentStatus; import org.apache.ignite.ci.web.model.hist.VisasHistoryStorage; import org.apache.ignite.internal.util.typedef.F; import org.jetbrains.annotations.NotNull; @@ -84,7 +87,7 @@ public class TcBotTriggerAndSignOffService { @Inject ITcHelper tcHelper; /** */ - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** */ public void startObserver() { @@ -400,4 +403,21 @@ public class TcBotTriggerAndSignOffService { @NotNull public String getWebLinkToQueued(ITeamcityIgnited teamcity, BuildRefCompacted ref) { return teamcity.host() + "viewQueued.html?itemId=" + ref.id(); } + + @Inject PrChainsProcessor prChainsProcessor; + + public CurrentVisaStatus currentVisaStatus(String srvId, ICredentialsProv prov, String buildTypeId, String tcBranch) { + CurrentVisaStatus status = new CurrentVisaStatus(); + + List<SuiteCurrentStatus> suitesStatuses + = prChainsProcessor.getSuitesStatuses(buildTypeId, tcBranch, srvId, prov, SyncMode.NONE); + + if(suitesStatuses==null) + return status; + + status.blockers = suitesStatuses.stream().mapToInt(suite -> + suite.testFailures.size()).sum(); + + return status; + } } diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java index 5b52dfa..18e2f60 100644 --- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java +++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/rest/visa/TcBotVisaService.java @@ -29,6 +29,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import org.apache.ignite.ci.tcbot.visa.ContributionCheckStatus; import org.apache.ignite.ci.tcbot.visa.ContributionToCheck; +import org.apache.ignite.ci.tcbot.visa.CurrentVisaStatus; import org.apache.ignite.ci.tcbot.visa.TcBotTriggerAndSignOffService; import org.apache.ignite.ci.tcbot.visa.VisaStatus; import org.apache.ignite.ci.user.ICredentialsProv; @@ -85,4 +86,18 @@ public class TcBotVisaService { return instance.contributionStatus(srvId, prov, suiteId, prId); } + + @GET + @Path("visaStatus") + public CurrentVisaStatus currentVisaStatus(@Nullable @QueryParam("serverId") String srvId, + @Nonnull @QueryParam("suiteId") String suiteId, + @QueryParam("tcBranch") String tcBranch) { + ICredentialsProv prov = ICredentialsProv.get(req); + if (!prov.hasAccess(srvId)) + throw ServiceUnauthorizedException.noCreds(srvId); + + TcBotTriggerAndSignOffService instance = CtxListener.getInjector(ctx).getInstance(TcBotTriggerAndSignOffService.class); + + return instance.currentVisaStatus(srvId, prov, suiteId, tcBranch); + } } diff --git a/ignite-tc-helper-web/src/main/webapp/js/prs-1.0.js b/ignite-tc-helper-web/src/main/webapp/js/prs-1.0.js index b172279..dff689d 100644 --- a/ignite-tc-helper-web/src/main/webapp/js/prs-1.0.js +++ b/ignite-tc-helper-web/src/main/webapp/js/prs-1.0.js @@ -194,6 +194,25 @@ function showStageResult(stageNum, prId, passed, failed) { } +function showStageBlockers(stageNum, prId, blockers) { + let stageOneStatus = $('#visaStage_' + stageNum + '_' + prId); + let html; + if (!isDefinedAndFilled(blockers) || blockers == null) { + html = "?"; + + stageOneStatus.css('background', 'orange'); + } else if (blockers === 0) { + html = blockers + " "; + stageOneStatus.css('background', '#12AD5E'); + } else { + html = blockers + " "; + + stageOneStatus.css('background', 'orange'); + } + stageOneStatus.html(html); +} + + /* Formatting function for row details - modify as you need */ function formatContributionDetails(row, srvId, suiteId) { // row is the original data object for the row @@ -292,9 +311,8 @@ function repaintLater(srvId, suiteId) { } function showContributionStatus(status, prId, row, srvId, suiteId) { - let finishedBranch = status.branchWithFinishedRunAll; let tdForPr = $('#showResultFor' + prId); - let buildIsCompleted = isDefinedAndFilled(finishedBranch); + let hasSomeRunAll = isDefinedAndFilled(status.branchWithFinishedRunAll); let hasJiraIssue = isDefinedAndFilled(row.jiraIssueId); let hasQueued = status.queuedBuilds > 0 || status.runningBuilds > 0; let queuedStatus = "Has queued builds: " + status.queuedBuilds + " queued " + " " + status.runningBuilds + " running"; @@ -311,7 +329,9 @@ function showContributionStatus(status, prId, row, srvId, suiteId) { } $('#viewQueuedBuildsFor' + prId).html(linksToRunningBuilds); - if (buildIsCompleted) { + if (hasSomeRunAll) { + let finishedBranch = status.branchWithFinishedRunAll; + tdForPr.html("<a id='showReportlink_" + prId + "' href='" + prShowHref(srvId, suiteId, finishedBranch) + "'>" + "<button id='show_" + prId + "'>Show " + finishedBranch + " report</button></a>"); @@ -339,9 +359,11 @@ function showContributionStatus(status, prId, row, srvId, suiteId) { showStageResult(1, prId, hasJiraIssue, !hasJiraIssue); - let noNeedToTrigger = hasQueued || buildIsCompleted; + + let buildFinished = isDefinedAndFilled(status.runAllFinished) && status.runAllFinished; + let noNeedToTrigger = hasQueued || buildFinished; showStageResult(2, prId, noNeedToTrigger, false); - showStageResult(3, prId, buildIsCompleted, false); + showStageResult(3, prId, hasSomeRunAll, false); if(hasQueued) { showWaitingResults(3, prId, queuedStatus); } @@ -352,7 +374,7 @@ function showContributionStatus(status, prId, row, srvId, suiteId) { function prepareStatusOfTrigger() { var res = ""; - if (hasQueued || buildIsCompleted) { + if (hasQueued || hasSomeRunAll) { res += " class='disabledbtn'"; if (hasQueued) res += " title='" + queuedStatus + "'"; @@ -399,4 +421,17 @@ function showContributionStatus(status, prId, row, srvId, suiteId) { $('#testDraw').html(testDraw); + + if(isDefinedAndFilled(status.branchWithFinishedRunAll)) { + $.ajax({ + url: "rest/visa/visaStatus" + + "?serverId=" + srvId + + "&suiteId=" + suiteId + + "&tcBranch=" + status.branchWithFinishedRunAll, + success: + function (result) { + showStageBlockers(3, prId, result.blockers); + } + }); + } } \ No newline at end of file