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/15 17:57:51 UTC
[ignite-teamcity-bot] branch master updated: Board: Displaying each
test details added - Fixes #153.
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 47c4121 Board: Displaying each test details added - Fixes #153.
47c4121 is described below
commit 47c4121ebaeda1bd9fa7168cc767dea2b2653106
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Thu Aug 15 20:53:35 2019 +0300
Board: Displaying each test details added - Fixes #153.
Signed-off-by: Dmitriy Pavlov <dp...@apache.org>
---
.../org/apache/ignite/ci/web/model/Version.java | 2 +-
.../src/main/webapp/board/index.html | 35 +++-
.../ignite/tcbot/engine/board/BoardService.java | 180 ++++++++++++---------
.../tcbot/engine/board/IssueResolveStatus.java | 21 +++
.../ignite/tcbot/engine/ui/BoardDefectIssueUi.java | 70 ++++++++
.../tcbot/engine/ui/BoardDefectSummaryUi.java | 39 ++++-
.../ignite/tcbot/engine/ui/ShortTestFailureUi.java | 27 ++--
7 files changed, 282 insertions(+), 92 deletions(-)
diff --git a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
index 2f2bb49..34e494a 100644
--- a/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
+++ b/ignite-tc-helper-web/src/main/java/org/apache/ignite/ci/web/model/Version.java
@@ -28,7 +28,7 @@ package org.apache.ignite.ci.web.model;
public static final String GITHUB_REF = "https://github.com/apache/ignite-teamcity-bot";
/** TC Bot Version. */
- public static final String VERSION = "20190814";
+ public static final String VERSION = "20190815";
/** Java version, where Web App is running. */
public String javaVer;
diff --git a/ignite-tc-helper-web/src/main/webapp/board/index.html b/ignite-tc-helper-web/src/main/webapp/board/index.html
index ff74043..92ebc68 100644
--- a/ignite-tc-helper-web/src/main/webapp/board/index.html
+++ b/ignite-tc-helper-web/src/main/webapp/board/index.html
@@ -54,7 +54,8 @@
{text: "Commits", value: 'blameCandidateSummary'},
{text: "Issues", value: 'cntissues'},
{text: "Fixed", value: 'fixedissues'},
- {text: "Not Fixed", value: 'notfixedissues'},
+ {text: "Ignored", value: 'cntignoredissues'},
+ {text: "Not Fixed", value: 'cntfailingissues'},
{text: "Unclear", value: 'unclearissues'}
]
},
@@ -183,11 +184,24 @@
</div>
Tests affected:
- <div v-for="(test) in item.testOrSuitesAffected">
- {{ test }}
- </div>
-
- <button v-on:click="onResolve(item.id)">Resolve</button>
+ <table>
+ <tr v-for="(issue) in item.allIssues">
+ <td v-if="issue.status === 'FIXED'">
+ Fixed
+ </td>
+ <td v-else-if="issue.status === 'FAILING'">
+ Still Failing
+ </td>
+ <td v-else>
+ {{ issue.status }}
+ </td>
+
+ <td>{{ issue.issueType }}</td>
+ <td>{{ issue.name }}</td>
+ </tr>
+ </table>
+
+ <button v-if="item.cntFailingIssues === 0" v-on:click="onResolve(item.id)">Resolve</button>
</td>
</template>
@@ -209,8 +223,13 @@
<template v-slot:item.fixedIssues="{ item }">
<span class='visaStage' style="background: #12AD5E" v-if="item.fixedIssues!=null" > {{ item.fixedIssues }} </span>
</template>
- <template v-slot:item.notFixedIssues="{ item }" >
- <span class='visaStage' style="background: red" v-if="item.notFixedIssues!=null" > {{ item.notFixedIssues }} </span>
+ <template v-slot:item.cntIgnoredIssues="{ item }">
+ <span class='visaStage' style="background: darkorange"
+ v-if="item.cntIgnoredIssues!=0"
+ :title="item.summaryIgnoredIssues"> {{ item.cntIgnoredIssues }} </span>
+ </template>
+ <template v-slot:item.cntFailingIssues="{ item }" >
+ <span class='visaStage' style="background: red" v-if="item.cntFailingIssues!=0" :title="item.summaryFailingIssues"> {{ item.cntFailingIssues }} </span>
</template>
<template v-slot:item.unclearIssues="{ item }" >
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
index be09320..0405eef 100644
--- 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
@@ -23,7 +23,6 @@ import java.util.HashMap;
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.concurrent.atomic.AtomicInteger;
@@ -31,6 +30,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import javax.inject.Inject;
+
+import com.google.common.base.Preconditions;
import org.apache.ignite.ci.issue.Issue;
import org.apache.ignite.ci.issue.IssueKey;
import org.apache.ignite.ci.teamcity.ignited.change.ChangeCompacted;
@@ -49,6 +50,7 @@ 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.BoardDefectIssueUi;
import org.apache.ignite.tcbot.engine.ui.BoardDefectSummaryUi;
import org.apache.ignite.tcbot.engine.ui.BoardSummaryUi;
import org.apache.ignite.tcbot.engine.user.IUserStorage;
@@ -87,7 +89,7 @@ public class BoardService {
String srvCode = next.tcSrvCode(compactor);
- if(!creds.hasAccess(srvCode))
+ if (!creds.hasAccess(srvCode))
continue;
ITeamcityIgnited tcIgn = tcProv.server(srvCode, creds);
@@ -96,7 +98,6 @@ public class BoardService {
List<BlameCandidate> candidates = next.blameCandidates();
-
Map<Integer, DefectFirstBuild> build = next.buildsInvolved();
for (DefectFirstBuild cause : build.values()) {
FatBuildCompacted firstBuild = cause.build();
@@ -107,40 +108,19 @@ public class BoardService {
Stream<FatBuildCompacted> results = FutureUtil.getResults(futures);
List<FatBuildCompacted> freshRebuild = results.collect(Collectors.toList());
- if(!freshRebuild.isEmpty()) {
- FatBuildCompacted buildCompacted = freshRebuild.get(0);
-
- for (DefectIssue issue : cause.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();
- } else {
- //exception for new test. removal of test means test is fixed
- if(IssueType.newContributedTestFailure.code().equals(compactor.getStringFromId(issue.issueTypeCode())))
- defectUi.addFixedIssue();
- else
- defectUi.addUnclearIssue();
- }
-
- defectUi.addIssue(compactor.getStringFromId(issue.testNameCid()));
- }
- } else {
- for (DefectIssue issue : cause.issues()) {
- defectUi.addUnclearIssue();
-
- defectUi.addIssue(compactor.getStringFromId(issue.testNameCid()));
- }
+
+ Optional<FatBuildCompacted> rebuild;
+
+ rebuild = !freshRebuild.isEmpty() ? freshRebuild.stream().findFirst() : Optional.empty();
+
+ for (DefectIssue issue : cause.issues()) {
+ BoardDefectIssueUi issueUi = processIssue(defectUi, rebuild, issue);
+
+ defectUi.addIssue(compactor.getStringFromId(issue.testNameCid()), issueUi);
}
}
- defectUi.branch = next.tcBranch(compactor);
+ defectUi.branch = next.tcBranch(compactor);
res.addDefect(defectUi);
}
@@ -148,6 +128,57 @@ public class BoardService {
return res;
}
+ public BoardDefectIssueUi processIssue(BoardDefectSummaryUi defectUi, Optional<FatBuildCompacted> rebuild,
+ DefectIssue issue) {
+ Optional<ITest> testResult;
+
+ if (rebuild.isPresent()) {
+ testResult = rebuild.get().getAllTests()
+ .filter(t -> t.testName() == issue.testNameCid())
+ .findAny();
+ }
+ else
+ testResult = Optional.empty();
+
+ IssueResolveStatus status;
+ if (testResult.isPresent()) {
+ ITest test = testResult.get();
+
+ if (test.isIgnoredTest() || test.isMutedTest())
+ status = IssueResolveStatus.IGNORED;
+ else {
+ boolean failed = test.isFailedTest(compactor);
+ if (!failed) {
+ defectUi.addFixedIssue();
+
+ status = IssueResolveStatus.FIXED;
+ }
+ else {
+ defectUi.addNotFixedIssue();
+
+ status = IssueResolveStatus.FAILING;
+
+ }
+ }
+ } else{
+ //exception for new test. removal of test means test is fixed
+ if (IssueType.newContributedTestFailure.code().equals(compactor.getStringFromId(issue.issueTypeCode()))) {
+ defectUi.addFixedIssue();
+
+ status = IssueResolveStatus.FIXED;
+ }
+ else {
+ defectUi.addUnclearIssue();
+ status = IssueResolveStatus.UNKNOWN;
+ }
+ }
+
+ return new BoardDefectIssueUi(status,
+ compactor, issue,
+ issue.testNameCid(),
+ issue.issueTypeCode());
+ }
+
public void issuesToDefectsLater() {
scheduler.sheduleNamed("issuesToDefects", this::issuesToDefects, 15, TimeUnit.MINUTES);
}
@@ -207,53 +238,56 @@ public class BoardService {
defect.removeOldVerBlameCandidates();
- if(defect.blameCandidates().isEmpty()) {
- //save changes because it can be missed in older DB versions
- defect.changeMap(changeDao.getAll(srvId, fatBuild.changes()));
-
- Map<Integer, ChangeCompacted> map = defect.changeMap();
+ if(defect.blameCandidates().isEmpty())
+ fillBlameCandidates(srvId, fatBuild, defect);
- Collection<ChangeCompacted> values = map.values();
- for (ChangeCompacted change : values) {
- BlameCandidate candidate = new BlameCandidate();
- int vcsUsernameCid = change.vcsUsername();
- candidate.vcsUsername(vcsUsernameCid);
-
- int tcUserUsername = change.tcUserUsername();
- @Nullable TcHelperUser tcHelperUser = null;
- if (tcUserUsername != -1)
- tcHelperUser = userStorage.getUser(compactor.getStringFromId(tcUserUsername));
- else {
- String strVcsUsername = compactor.getStringFromId(vcsUsernameCid);
-
- if(!Strings.isNullOrEmpty(strVcsUsername) &&
- strVcsUsername.contains("<") && strVcsUsername.contains(">")) {
- int emailStartIdx = strVcsUsername.indexOf('<');
- int emailEndIdx = strVcsUsername.indexOf('>');
- String email = strVcsUsername.substring(emailStartIdx + 1, emailEndIdx);
- tcHelperUser = userStorage.findUserByEmail(email);
- }
- }
+ return defect;
+ });
+ });
- if (tcHelperUser != null) {
- String username = tcHelperUser.username();
+ return cntDefects.get() + " defects processed for " + cntIssues.get() + " issues checked";
+ }
- String fullName = tcHelperUser.fullName();
- candidate.fullDisplayName(compactor.getStringId(fullName));
- candidate.tcHelperUserUsername(compactor.getStringId(username));
- }
+ private void fillBlameCandidates(int srvId, FatBuildCompacted fatBuild, DefectCompacted defect) {
+ //save changes because it can be missed in older DB versions
+ defect.changeMap(changeDao.getAll(srvId, fatBuild.changes()));
+
+ Map<Integer, ChangeCompacted> map = defect.changeMap();
+
+ Collection<ChangeCompacted> values = map.values();
+ for (ChangeCompacted change : values) {
+ BlameCandidate candidate = new BlameCandidate();
+ int vcsUsernameCid = change.vcsUsername();
+ candidate.vcsUsername(vcsUsernameCid);
+
+ int tcUserUsername = change.tcUserUsername();
+ @Nullable TcHelperUser tcHelperUser = null;
+ if (tcUserUsername != -1)
+ tcHelperUser = userStorage.getUser(compactor.getStringFromId(tcUserUsername));
+ else {
+ String strVcsUsername = compactor.getStringFromId(vcsUsernameCid);
+
+ if(!Strings.isNullOrEmpty(strVcsUsername) &&
+ strVcsUsername.contains("<") && strVcsUsername.contains(">")) {
+ int emailStartIdx = strVcsUsername.indexOf('<');
+ int emailEndIdx = strVcsUsername.indexOf('>');
+ String email = strVcsUsername.substring(emailStartIdx + 1, emailEndIdx);
+ tcHelperUser = userStorage.findUserByEmail(email);
+ }
+ }
- defect.addBlameCandidate(candidate);
- }
- }
- return defect;
- });
+ if (tcHelperUser != null) {
+ String username = tcHelperUser.username();
- });
+ String fullName = tcHelperUser.fullName();
+ candidate.fullDisplayName(compactor.getStringId(fullName));
+ candidate.tcHelperUserUsername(compactor.getStringId(username));
+ }
- return cntDefects.get() + " defects processed for " + cntIssues.get() + " issues checked";
+ defect.addBlameCandidate(candidate);
+ }
}
public void resolveDefect(Integer defectId, ICredentialsProv creds) {
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.java
new file mode 100644
index 0000000..d76fac9
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/board/IssueResolveStatus.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.tcbot.engine.board;
+
+public enum IssueResolveStatus {
+ FIXED, FAILING, IGNORED, UNKNOWN
+}
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java
new file mode 100644
index 0000000..76927ad
--- /dev/null
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BoardDefectIssueUi.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.google.common.base.Strings;
+import org.apache.ignite.tcbot.engine.board.IssueResolveStatus;
+import org.apache.ignite.tcbot.engine.defect.DefectIssue;
+import org.apache.ignite.tcbot.persistence.IStringCompactor;
+
+/**
+ * UI version for displaying org.apache.ignite.tcbot.engine.defect.DefectIssue and its current status
+ */
+public class BoardDefectIssueUi {
+ private transient IStringCompactor compactor;
+ private transient DefectIssue issue;
+ private IssueResolveStatus status;
+
+ public BoardDefectIssueUi(IssueResolveStatus status, IStringCompactor compactor,
+ DefectIssue issue, int testNameCid, int code) {
+ this.status = status;
+ this.compactor = compactor;
+ this.issue = issue;
+ }
+
+ public String getName() {
+ String name = compactor.getStringFromId(issue.testNameCid());
+
+ //todo check if it is a suite name
+
+ String suiteName = null, testName = null;
+
+ String[] split = Strings.nullToEmpty(name).split("\\:");
+ if (split.length >= 2) {
+ suiteName = ShortTestFailureUi.extractSuite(split[0]);
+ testName = ShortTestFailureUi.extractTest(split[1]);
+ }
+
+ if (testName != null && suiteName != null)
+ return suiteName + ":" + testName;
+
+ return name;
+
+ }
+
+ public String getIssueType() {
+ return compactor.getStringFromId(issue.issueTypeCode());
+ }
+
+ public String getStatus() {
+ return status.toString();
+ }
+
+ public IssueResolveStatus status() {
+ return status;
+ }
+}
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
index 1495a64..d9a61cb 100644
--- 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
@@ -17,11 +17,13 @@
package org.apache.ignite.tcbot.engine.ui;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import org.apache.ignite.tcbot.engine.board.IssueResolveStatus;
import org.apache.ignite.tcbot.engine.defect.BlameCandidate;
import org.apache.ignite.tcbot.engine.defect.DefectCompacted;
import org.apache.ignite.tcbot.persistence.IStringCompactor;
@@ -37,9 +39,12 @@ public class BoardDefectSummaryUi {
public Integer notFixedIssues;
public Integer unclearIssues;
+ @Deprecated
public List<String> testOrSuitesAffected = new ArrayList<>();
private Set<String> tags = new HashSet<>();
+ private List<BoardDefectIssueUi> issuesList = new ArrayList<>();
+
public BoardDefectSummaryUi(DefectCompacted defect, IStringCompactor compactor) {
this.defect = defect;
this.compactor = compactor;
@@ -110,15 +115,46 @@ public class BoardDefectSummaryUi {
return defect.id();
}
- public void addIssue(String testOrBuildName) {
+ public void addIssue(String testOrBuildName, BoardDefectIssueUi issue) {
if (cntIssues == null)
cntIssues = 0;
cntIssues++;
testOrSuitesAffected.add(testOrBuildName);
+ issuesList.add(issue);
+ }
+
+ public List<BoardDefectIssueUi> getAllIssues() {
+ return Collections.unmodifiableList(issuesList);
+ }
+
+ public List<BoardDefectIssueUi> getIgnoredIssues() {
+ return issuesList.stream().filter(iss -> iss.status() == IssueResolveStatus.IGNORED).collect(Collectors.toList());
+ }
+
+ public String getSummaryIgnoredIssues() {
+ return limitedListPrint(getIgnoredIssues(), BoardDefectIssueUi::getName);
+ }
+
+ public Integer getCntIgnoredIssues() {
+ return getIgnoredIssues().size();
}
+
+ public List<BoardDefectIssueUi> getFailingIssues() {
+ return issuesList.stream().filter(iss -> iss.status() == IssueResolveStatus.FAILING).collect(Collectors.toList());
+ }
+
+ public String getSummaryFailingIssues() {
+ return limitedListPrint(getFailingIssues(), BoardDefectIssueUi::getName);
+ }
+
+ public Integer getCntFailingIssues() {
+ return getFailingIssues().size();
+ }
+
+
public void addFixedIssue() {
if (fixedIssues == null)
fixedIssues = 0;
@@ -137,6 +173,7 @@ public class BoardDefectSummaryUi {
this.tags.addAll(parameters);
}
+ @Deprecated
public void addUnclearIssue() {
if (unclearIssues == null)
unclearIssues = 0;
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/ShortTestFailureUi.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/ShortTestFailureUi.java
index b702274..92a2319 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/ShortTestFailureUi.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/ShortTestFailureUi.java
@@ -50,15 +50,8 @@ public class ShortTestFailureUi {
String[] split = Strings.nullToEmpty(name).split("\\:");
if (split.length >= 2) {
- String suiteShort = split[0].trim();
- String[] suiteComps = suiteShort.split("\\.");
- if (suiteComps.length > 1)
- suiteName = suiteComps[suiteComps.length - 1];
-
- String testShort = split[1].trim();
- String[] testComps = testShort.split("\\.");
- if (testComps.length > 2)
- testName = testComps[testComps.length - 2] + "." + testComps[testComps.length - 1];
+ this.suiteName = extractSuite(split[0]);
+ this.testName = extractTest(split[1]);
}
final IRunHistory stat = failure.history(tcIgn, baseBranchId);
@@ -66,4 +59,20 @@ public class ShortTestFailureUi {
return this;
}
+
+ public static String extractTest(String s) {
+ String testShort = s.trim();
+ String[] testComps = testShort.split("\\.");
+ if (testComps.length > 2)
+ return testComps[testComps.length - 2] + "." + testComps[testComps.length - 1];
+ return null;
+ }
+
+ public static String extractSuite(String s) {
+ String suiteShort = s.trim();
+ String[] suiteComps = suiteShort.split("\\.");
+ if (suiteComps.length > 1)
+ return suiteComps[suiteComps.length - 1];
+ return null;
+ }
}