Skip to content

Commit

Permalink
Merge pull request #80 from bmunozm/feature/overrideResolvedIssues
Browse files Browse the repository at this point in the history
Include overrideResolvedIssues parameter to create new tickets if test failure are linked to already resolved ones
  • Loading branch information
imonteroperez committed Jul 14, 2022
2 parents 638ce49 + e846265 commit 32b079d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private JobConfigMapping.JobConfigEntry getJobConfig() {
*/
@DataBoundConstructor
public JiraTestDataPublisher(List<AbstractFields> configs, String projectKey, String issueType,
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue) {
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue, boolean overrideResolvedIssues) {

long defaultIssueType;
try {
Expand All @@ -143,6 +143,7 @@ public JiraTestDataPublisher(List<AbstractFields> configs, String projectKey, St
.withProjectKey(projectKey)
.withIssueType(defaultIssueType)
.withAutoRaiseIssues(autoRaiseIssue)
.withOverrideResolvedIssues(overrideResolvedIssues)
.withAutoResolveIssues(autoResolveIssue)
.withAutoUnlinkIssues(autoUnlinkIssue)
.withConfigs(Util.fixNull(configs))
Expand Down Expand Up @@ -192,6 +193,10 @@ public TestResultAction.Data contributeTestData(Run<?, ?> run, @Nonnull FilePath
}

boolean hasTestData = false;
if(JobConfigMapping.getInstance().getOverrideResolvedIssues(project)) {
hasTestData |= cleanJobCacheFile(listener, job, getTestCaseResults(testResult));
}

if(JobConfigMapping.getInstance().getAutoRaiseIssue(project)) {
hasTestData |= raiseIssues(listener, project, job, envVars, getTestCaseResults(testResult));
}
Expand Down Expand Up @@ -267,6 +272,18 @@ private boolean resolveIssues(TaskListener listener, Job project, Job job,
}
return solved;
}
private boolean cleanJobCacheFile(TaskListener listener, Job job,
List<CaseResult> testCaseResults) {
boolean cleaUp = false;
try {
cleaUp = JiraUtils.cleanJobCacheFile(testCaseResults, job);
} catch (RestClientException e){
listener.error("Could not do the clean up of the JiraIssueJobConfigs.json\n");
e.printStackTrace(listener.getLogger());
throw e;
}
return cleaUp;
}

private boolean raiseIssues(TaskListener listener, Job project, Job job,
EnvVars envVars,List<CaseResult> testCaseResults) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,22 @@
import com.atlassian.jira.rest.client.api.domain.input.IssueInput;
import com.atlassian.jira.rest.client.api.domain.input.IssueInputBuilder;
import com.atlassian.jira.rest.client.api.domain.util.ErrorCollection;
import io.atlassian.util.concurrent.Promise;
import hudson.EnvVars;
import hudson.model.Job;
import hudson.tasks.junit.CaseResult;
import hudson.tasks.test.TestResult;
import io.atlassian.util.concurrent.Promise;
import jenkins.model.Jenkins;

import org.apache.commons.lang3.StringUtils;
import org.jenkinsci.plugins.JiraTestResultReporter.config.AbstractFields;

import java.io.ByteArrayInputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
* Created by tuicu.
Expand Down Expand Up @@ -107,17 +105,44 @@ public static String getErrorMessage(RestClientException e, String newLine) {
}
return errorMessages.toString();
}

public static String createIssue(Job job, EnvVars envVars, CaseResult test) throws RestClientException {
return createIssue(job, job, envVars, test, JiraIssueTrigger.JOB);
}


public static boolean cleanJobCacheFile(List<CaseResult> testCaseResults, Job testJob){
List<String> testNames = testCaseResults.stream().filter(CaseResult::isFailed).map( CaseResult::getId ).collect( Collectors.toList());
HashMap<String, String> keysToCheck = new HashMap<>();
List<String> jiraIds = new ArrayList<>();
for (String test : testNames){
if(TestToIssueMapping.getInstance().getTestIssueKey(testJob, test) != null) {
String jiraId = TestToIssueMapping.getInstance().getTestIssueKey(testJob, test);
jiraIds.add(jiraId);
keysToCheck.put(jiraId, test);
}
}
if(keysToCheck.isEmpty()) {
return false;
}

SearchResult searchResult = JiraUtils.findUnresolvedJiraIssues(String.join(",", jiraIds));
if (searchResult != null && searchResult.getTotal() > 0) {
for (Issue issue: searchResult.getIssues()) {
String testKey = issue.getKey();
String testId = keysToCheck.get(testKey);
synchronized (testId) {
TestToIssueMapping.getInstance().removeTestToIssueMapping(testJob, testId, testKey);
}
}
}
return true;
}

public static String createIssue(Job job, Job project, EnvVars envVars, CaseResult test, JiraIssueTrigger trigger) throws RestClientException {
synchronized (test.getId()) { //avoid creating duplicated issues
if(TestToIssueMapping.getInstance().getTestIssueKey(job, test.getId()) != null) {
return null;
}

IssueInput issueInput = JiraUtils.createIssueInput(project, test, envVars, trigger);
SearchResult searchResult = JiraUtils.findIssues(project, test, envVars, issueInput);
if (searchResult != null && searchResult.getTotal() > 0) {
Expand Down Expand Up @@ -221,6 +246,14 @@ public static SearchResult findIssues(Job project, TestResult test, EnvVars envV
FieldInput fi = JiraTestDataPublisher.JiraTestDataPublisherDescriptor.templates.get(0).getFieldInput(test, envVars);
String jql = String.format("resolution = \"unresolved\" and project = \"%s\" and text ~ \"%s\"", projectKey, escapeJQL(issueInput.getField(fi.getId()).getValue().toString()));

return getSearchResult(jql);
}
private static SearchResult findUnresolvedJiraIssues(String keys) throws RestClientException {
String jql = String.format("key in (%s) and resolution != \"unresolved\" ", keys);
return getSearchResult(jql);
}

private static SearchResult getSearchResult(String jql) {
final Set<String > fields = new HashSet<>();
fields.add("issueKey");
fields.add("summary");
Expand All @@ -229,8 +262,7 @@ public static SearchResult findIssues(Job project, TestResult test, EnvVars envV
fields.add("updated");
fields.add("project");
fields.add("status");

log(jql);
JiraUtils.log(jql);

Promise<SearchResult> searchJqlPromise = JiraUtils.getJiraDescriptor().getRestClient().getSearchClient().searchJql(jql, 50, 0, fields);
return searchJqlPromise.claim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static class JobConfigEntry implements Serializable {
protected Long issueType;
protected List<AbstractFields> configs;
protected boolean autoRaiseIssue;
protected boolean overrideResolvedIssues;
protected boolean autoResolveIssue;
protected boolean autoUnlinkIssue;
protected transient Pattern issueKeyPattern;
Expand All @@ -58,13 +59,15 @@ public static class JobConfigEntry implements Serializable {
* @param configs list with the configured fields
*/
public JobConfigEntry(String projectKey, Long issueType, List<AbstractFields> configs,
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue) {
boolean autoRaiseIssue, boolean autoResolveIssue, boolean autoUnlinkIssue,
boolean overrideResolvedIssues) {
this.projectKey = projectKey;
this.issueType = issueType;
this.configs = configs;
this.autoRaiseIssue = autoRaiseIssue;
this.autoResolveIssue = autoResolveIssue;
this.autoUnlinkIssue = autoUnlinkIssue;
this.overrideResolvedIssues = overrideResolvedIssues;
compileIssueKeyPattern();
}

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

public boolean getAutoRaiseIssue() { return autoRaiseIssue; }

public boolean getOverrideResolvedIssues() { return overrideResolvedIssues; }

public boolean getAutoResolveIssue() { return autoResolveIssue; }

public boolean getAutoUnlinkIssue() { return autoUnlinkIssue; }
Expand Down Expand Up @@ -127,7 +132,7 @@ public static class JobConfigEntryBuilder extends JobConfigEntry {
* Constructor
*/
public JobConfigEntryBuilder() {
super(null, null, new ArrayList<>(), false, false, false);
super(null, null, new ArrayList<>(), false, false, false, false);
}

public JobConfigEntryBuilder withProjectKey(String projectKey) {
Expand All @@ -151,6 +156,11 @@ public JobConfigEntryBuilder withAutoRaiseIssues(boolean autoRaiseIssues) {
return this;
}

public JobConfigEntryBuilder withOverrideResolvedIssues(boolean overrideResolvedIssues) {
this.overrideResolvedIssues = overrideResolvedIssues;
return this;
}

public JobConfigEntryBuilder withAutoResolveIssues(boolean autoResolveIssue) {
this.autoResolveIssue = autoResolveIssue;
return this;
Expand Down Expand Up @@ -320,8 +330,9 @@ public synchronized void saveConfig(Job project,
List<AbstractFields> configs,
boolean autoRaiseIssue,
boolean autoResolveIssue,
boolean autoUnlinkIssue) {
JobConfigEntry entry = new JobConfigEntry(projectKey, issueType, configs, autoRaiseIssue, autoResolveIssue, autoUnlinkIssue);
boolean autoUnlinkIssue,
boolean overrideResolvedIssues) {
JobConfigEntry entry = new JobConfigEntry(projectKey, issueType, configs, autoRaiseIssue, autoResolveIssue, autoUnlinkIssue, overrideResolvedIssues);
saveConfig(project, entry);
}

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

public boolean getOverrideResolvedIssues(Job project) {
JobConfigEntry entry = getJobConfigEntry(project);
return entry != null ? entry.getOverrideResolvedIssues() : false;
}

public boolean getAutoResolveIssue(Job project) {
JobConfigEntry entry = getJobConfigEntry(project);
return entry != null ? entry.getAutoResolveIssue() : false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Create issues automatically for failing tests that are linked to resolved issues in JiraIssueKeyToTestMap.json.
</div>

0 comments on commit 32b079d

Please sign in to comment.