Skip to content

Commit 32b079d

Browse files
Merge pull request #80 from bmunozm/feature/overrideResolvedIssues
Include overrideResolvedIssues parameter to create new tickets if test failure are linked to already resolved ones
2 parents 638ce49 + e846265 commit 32b079d

File tree

4 files changed

+83
-15
lines changed

4 files changed

+83
-15
lines changed

src/main/java/org/jenkinsci/plugins/JiraTestResultReporter/JiraTestDataPublisher.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ private JobConfigMapping.JobConfigEntry getJobConfig() {
130130
*/
131131
@DataBoundConstructor
132132
public JiraTestDataPublisher(List<AbstractFields> configs, String projectKey, String issueType,
133-
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue) {
133+
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue, boolean overrideResolvedIssues) {
134134

135135
long defaultIssueType;
136136
try {
@@ -143,6 +143,7 @@ public JiraTestDataPublisher(List<AbstractFields> configs, String projectKey, St
143143
.withProjectKey(projectKey)
144144
.withIssueType(defaultIssueType)
145145
.withAutoRaiseIssues(autoRaiseIssue)
146+
.withOverrideResolvedIssues(overrideResolvedIssues)
146147
.withAutoResolveIssues(autoResolveIssue)
147148
.withAutoUnlinkIssues(autoUnlinkIssue)
148149
.withConfigs(Util.fixNull(configs))
@@ -192,6 +193,10 @@ public TestResultAction.Data contributeTestData(Run<?, ?> run, @Nonnull FilePath
192193
}
193194

194195
boolean hasTestData = false;
196+
if(JobConfigMapping.getInstance().getOverrideResolvedIssues(project)) {
197+
hasTestData |= cleanJobCacheFile(listener, job, getTestCaseResults(testResult));
198+
}
199+
195200
if(JobConfigMapping.getInstance().getAutoRaiseIssue(project)) {
196201
hasTestData |= raiseIssues(listener, project, job, envVars, getTestCaseResults(testResult));
197202
}
@@ -267,6 +272,18 @@ private boolean resolveIssues(TaskListener listener, Job project, Job job,
267272
}
268273
return solved;
269274
}
275+
private boolean cleanJobCacheFile(TaskListener listener, Job job,
276+
List<CaseResult> testCaseResults) {
277+
boolean cleaUp = false;
278+
try {
279+
cleaUp = JiraUtils.cleanJobCacheFile(testCaseResults, job);
280+
} catch (RestClientException e){
281+
listener.error("Could not do the clean up of the JiraIssueJobConfigs.json\n");
282+
e.printStackTrace(listener.getLogger());
283+
throw e;
284+
}
285+
return cleaUp;
286+
}
270287

271288
private boolean raiseIssues(TaskListener listener, Job project, Job job,
272289
EnvVars envVars,List<CaseResult> testCaseResults) {

src/main/java/org/jenkinsci/plugins/JiraTestResultReporter/JiraUtils.java

+42-10
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,22 @@
2424
import com.atlassian.jira.rest.client.api.domain.input.IssueInput;
2525
import com.atlassian.jira.rest.client.api.domain.input.IssueInputBuilder;
2626
import com.atlassian.jira.rest.client.api.domain.util.ErrorCollection;
27-
import io.atlassian.util.concurrent.Promise;
2827
import hudson.EnvVars;
2928
import hudson.model.Job;
3029
import hudson.tasks.junit.CaseResult;
3130
import hudson.tasks.test.TestResult;
31+
import io.atlassian.util.concurrent.Promise;
3232
import jenkins.model.Jenkins;
33-
3433
import org.apache.commons.lang3.StringUtils;
3534
import org.jenkinsci.plugins.JiraTestResultReporter.config.AbstractFields;
3635

3736
import java.io.ByteArrayInputStream;
3837
import java.net.URI;
3938
import java.nio.charset.StandardCharsets;
40-
import java.util.HashSet;
41-
import java.util.Map;
42-
import java.util.Set;
39+
import java.util.*;
4340
import java.util.logging.Level;
4441
import java.util.logging.Logger;
42+
import java.util.stream.Collectors;
4543

4644
/**
4745
* Created by tuicu.
@@ -107,17 +105,44 @@ public static String getErrorMessage(RestClientException e, String newLine) {
107105
}
108106
return errorMessages.toString();
109107
}
110-
108+
111109
public static String createIssue(Job job, EnvVars envVars, CaseResult test) throws RestClientException {
112110
return createIssue(job, job, envVars, test, JiraIssueTrigger.JOB);
113111
}
114-
112+
113+
public static boolean cleanJobCacheFile(List<CaseResult> testCaseResults, Job testJob){
114+
List<String> testNames = testCaseResults.stream().filter(CaseResult::isFailed).map( CaseResult::getId ).collect( Collectors.toList());
115+
HashMap<String, String> keysToCheck = new HashMap<>();
116+
List<String> jiraIds = new ArrayList<>();
117+
for (String test : testNames){
118+
if(TestToIssueMapping.getInstance().getTestIssueKey(testJob, test) != null) {
119+
String jiraId = TestToIssueMapping.getInstance().getTestIssueKey(testJob, test);
120+
jiraIds.add(jiraId);
121+
keysToCheck.put(jiraId, test);
122+
}
123+
}
124+
if(keysToCheck.isEmpty()) {
125+
return false;
126+
}
127+
128+
SearchResult searchResult = JiraUtils.findUnresolvedJiraIssues(String.join(",", jiraIds));
129+
if (searchResult != null && searchResult.getTotal() > 0) {
130+
for (Issue issue: searchResult.getIssues()) {
131+
String testKey = issue.getKey();
132+
String testId = keysToCheck.get(testKey);
133+
synchronized (testId) {
134+
TestToIssueMapping.getInstance().removeTestToIssueMapping(testJob, testId, testKey);
135+
}
136+
}
137+
}
138+
return true;
139+
}
140+
115141
public static String createIssue(Job job, Job project, EnvVars envVars, CaseResult test, JiraIssueTrigger trigger) throws RestClientException {
116142
synchronized (test.getId()) { //avoid creating duplicated issues
117143
if(TestToIssueMapping.getInstance().getTestIssueKey(job, test.getId()) != null) {
118144
return null;
119145
}
120-
121146
IssueInput issueInput = JiraUtils.createIssueInput(project, test, envVars, trigger);
122147
SearchResult searchResult = JiraUtils.findIssues(project, test, envVars, issueInput);
123148
if (searchResult != null && searchResult.getTotal() > 0) {
@@ -221,6 +246,14 @@ public static SearchResult findIssues(Job project, TestResult test, EnvVars envV
221246
FieldInput fi = JiraTestDataPublisher.JiraTestDataPublisherDescriptor.templates.get(0).getFieldInput(test, envVars);
222247
String jql = String.format("resolution = \"unresolved\" and project = \"%s\" and text ~ \"%s\"", projectKey, escapeJQL(issueInput.getField(fi.getId()).getValue().toString()));
223248

249+
return getSearchResult(jql);
250+
}
251+
private static SearchResult findUnresolvedJiraIssues(String keys) throws RestClientException {
252+
String jql = String.format("key in (%s) and resolution != \"unresolved\" ", keys);
253+
return getSearchResult(jql);
254+
}
255+
256+
private static SearchResult getSearchResult(String jql) {
224257
final Set<String > fields = new HashSet<>();
225258
fields.add("issueKey");
226259
fields.add("summary");
@@ -229,8 +262,7 @@ public static SearchResult findIssues(Job project, TestResult test, EnvVars envV
229262
fields.add("updated");
230263
fields.add("project");
231264
fields.add("status");
232-
233-
log(jql);
265+
JiraUtils.log(jql);
234266

235267
Promise<SearchResult> searchJqlPromise = JiraUtils.getJiraDescriptor().getRestClient().getSearchClient().searchJql(jql, 50, 0, fields);
236268
return searchJqlPromise.claim();

src/main/java/org/jenkinsci/plugins/JiraTestResultReporter/JobConfigMapping.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public static class JobConfigEntry implements Serializable {
4747
protected Long issueType;
4848
protected List<AbstractFields> configs;
4949
protected boolean autoRaiseIssue;
50+
protected boolean overrideResolvedIssues;
5051
protected boolean autoResolveIssue;
5152
protected boolean autoUnlinkIssue;
5253
protected transient Pattern issueKeyPattern;
@@ -58,13 +59,15 @@ public static class JobConfigEntry implements Serializable {
5859
* @param configs list with the configured fields
5960
*/
6061
public JobConfigEntry(String projectKey, Long issueType, List<AbstractFields> configs,
61-
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue) {
62+
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue,
63+
boolean overrideResolvedIssues) {
6264
this.projectKey = projectKey;
6365
this.issueType = issueType;
6466
this.configs = configs;
6567
this.autoRaiseIssue = autoRaiseIssue;
6668
this.autoResolveIssue = autoResolveIssue;
6769
this.autoUnlinkIssue = autoUnlinkIssue;
70+
this.overrideResolvedIssues = overrideResolvedIssues;
6871
compileIssueKeyPattern();
6972
}
7073

@@ -94,6 +97,8 @@ public List<AbstractFields> getConfigs() {
9497

9598
public boolean getAutoRaiseIssue() { return autoRaiseIssue; }
9699

100+
public boolean getOverrideResolvedIssues() { return overrideResolvedIssues; }
101+
97102
public boolean getAutoResolveIssue() { return autoResolveIssue; }
98103

99104
public boolean getAutoUnlinkIssue() { return autoUnlinkIssue; }
@@ -127,7 +132,7 @@ public static class JobConfigEntryBuilder extends JobConfigEntry {
127132
* Constructor
128133
*/
129134
public JobConfigEntryBuilder() {
130-
super(null, null, new ArrayList<>(), false, false, false);
135+
super(null, null, new ArrayList<>(), false, false, false, false);
131136
}
132137

133138
public JobConfigEntryBuilder withProjectKey(String projectKey) {
@@ -151,6 +156,11 @@ public JobConfigEntryBuilder withAutoRaiseIssues(boolean autoRaiseIssues) {
151156
return this;
152157
}
153158

159+
public JobConfigEntryBuilder withOverrideResolvedIssues(boolean overrideResolvedIssues) {
160+
this.overrideResolvedIssues = overrideResolvedIssues;
161+
return this;
162+
}
163+
154164
public JobConfigEntryBuilder withAutoResolveIssues(boolean autoResolveIssue) {
155165
this.autoResolveIssue = autoResolveIssue;
156166
return this;
@@ -320,8 +330,9 @@ public synchronized void saveConfig(Job project,
320330
List<AbstractFields> configs,
321331
boolean autoRaiseIssue,
322332
boolean autoResolveIssue,
323-
boolean autoUnlinkIssue) {
324-
JobConfigEntry entry = new JobConfigEntry(projectKey, issueType, configs, autoRaiseIssue, autoResolveIssue, autoUnlinkIssue);
333+
boolean autoUnlinkIssue,
334+
boolean overrideResolvedIssues) {
335+
JobConfigEntry entry = new JobConfigEntry(projectKey, issueType, configs, autoRaiseIssue, autoResolveIssue, autoUnlinkIssue, overrideResolvedIssues);
325336
saveConfig(project, entry);
326337
}
327338

@@ -381,6 +392,11 @@ public boolean getAutoRaiseIssue(Job project) {
381392
return entry != null ? entry.getAutoRaiseIssue() : false;
382393
}
383394

395+
public boolean getOverrideResolvedIssues(Job project) {
396+
JobConfigEntry entry = getJobConfigEntry(project);
397+
return entry != null ? entry.getOverrideResolvedIssues() : false;
398+
}
399+
384400
public boolean getAutoResolveIssue(Job project) {
385401
JobConfigEntry entry = getJobConfigEntry(project);
386402
return entry != null ? entry.getAutoResolveIssue() : false;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div>
2+
Create issues automatically for failing tests that are linked to resolved issues in JiraIssueKeyToTestMap.json.
3+
</div>

0 commit comments

Comments
 (0)