Skip to content

Commit

Permalink
Integrate Jira issue creation/update (#35)
Browse files Browse the repository at this point in the history
* Define logJira and var defaults

Signed-off-by: Julia Pineda <[email protected]>

* get_gitsha: return hash map

Signed-off-by: Julia Pineda <[email protected]>

* UpdateBOOTFiles: Parse failing_msg outside if send_results

Signed-off-by: Julia Pineda <[email protected]>

* UpdateBOOTFiles: Call logJira

Signed-off-by: Julia Pineda <[email protected]>

* LinuxTests: Call logJira

Signed-off-by: Julia Pineda <[email protected]>

* PyADITests: Call logJira

Signed-off-by: Julia Pineda <[email protected]>

* Libad9361Tests: Call logJira

* MATLABTests: Call logJira

Signed-off-by: Julia Pineda <[email protected]>

* Move common jiraArgs update inside logJira

Signed-off-by: Julia Pineda <[email protected]>

* Revert get_gitsha definition

Signed-off-by: Julia Pineda <[email protected]>

* Enclose Jira site access in try-catch

Signed-off-by: Julia Pineda <[email protected]>

* logJira cleanup

Signed-off-by: Julia Pineda <[email protected]>

* LinuxTests: Attach dmesg.log

Signed-off-by: Julia Pineda <[email protected]>
  • Loading branch information
jpineda3 authored Feb 7, 2022
1 parent 1978400 commit 60a0718
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 3 deletions.
172 changes: 169 additions & 3 deletions src/sdg/Gauntlet.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,23 @@ def stage_library(String stage_name) {
echo "Update BOOT Files unexpectedly failed. ${ex.getMessage()}"
}
get_gitsha(board)
failing_msg = "'" + ex.getMessage().split('\n').last().replaceAll( /(['])/, '"') + "'"
// send logs to elastic
if (gauntEnv.send_results){
set_elastic_field(board, 'last_failing_stage', 'UpdateBOOTFiles')
failing_msg = "'" + ex.getMessage().split('\n').last().replaceAll( /(['])/, '"') + "'"
set_elastic_field(board, 'last_failing_stage_failure', failing_msg)
stage_library('SendResults').call(board)
}
if (is_nominal_exception)
throw new NominalException('UpdateBOOTFiles failed: '+ ex.getMessage())
// log Jira
try{
description = failing_msg
}catch(Exception desc){
println('Error updating description.')
}finally{
logJira([board:board, summary:'Update BOOT files failed.', description:description, attachment:[board+".log"]])
}
throw new Exception('UpdateBOOTFiles failed: '+ ex.getMessage())
}finally{
//archive uart logs
Expand Down Expand Up @@ -357,6 +365,17 @@ def stage_library(String stage_name) {
}

if(failed_test && !failed_test.allWhitespace){
// log Jira
def description = ""
try{
description += "*Missing drivers: " + missing_devs.size().toString() + "* (" + missing_devs.join(", ") + ")\n"
dmesg_errs = readFile("dmesg_err_filtered.log").readLines()
description += "*dmesg errors: ${dmesg_errs.size()}*\n" + dmesg_errs.join("\n")
}catch(Exception desc){
println('Error updating description.')
}finally{
logJira([board:board, summary:'Linux tests failed.', description:description, attachment:[board+"_diag_report.tar.bz2","dmesg.log"]])
}
unstable("Linux Tests Failed: ${failed_test}")
}
}catch(Exception ex) {
Expand All @@ -383,6 +402,8 @@ def stage_library(String stage_name) {
def ip = nebula('update-config network-config dutip --board-name='+board)
def serial = nebula('update-config uart-config address --board-name='+board)
def uri;
def description = ""
def pytest_attachment = null
println('IP: ' + ip)
// temporarily get pytest-libiio from another source
run_i('git clone -b "' + gauntEnv.pytest_libiio_branch + '" ' + gauntEnv.pytest_libiio_repo, true)
Expand Down Expand Up @@ -432,11 +453,23 @@ def stage_library(String stage_name) {
println('Parsing pytest results failed')
echo getStackTrace(ex)
}
pytest_attachment = board+"_reports.xml"
}

// throw exception if pytest failed
if ((statusCode != 5) && (statusCode != 0)){
// Ignore error 5 which means no tests were run
// log Jira
dir('testxml'){
try{
sh 'grep \" name=.*<failure\" *.xml | sed \'s/.*name=\"\\(.*\\)" .*<failure.*/\\1/\' > failures.txt'
description += readFile 'failures.txt'
}catch(Exception desc){
println('Error updating description.')
}finally{
logJira([board:board, summary:'PyADI tests failed.', description: description, attachment:[pytest_attachment]])
}
}
unstable("PyADITests Failed")
}
}
Expand Down Expand Up @@ -473,6 +506,14 @@ def stage_library(String stage_name) {
}
}
}catch(Exception ex){
// log Jira
try{
description = "LibAD9361Tests Failed: ${ex.getMessage()}"
} catch(Exception desc){
println('Error updating description.')
} finally{
logJira([board:board, summary:'libad9361 tests failed.', description:description])
}
unstable("LibAD9361Tests Failed: ${ex.getMessage()}")
}finally{
dir('libad9361-iio/build'){
Expand All @@ -492,6 +533,8 @@ def stage_library(String stage_name) {
def under_scm = true
stage("Run MATLAB Toolbox Tests") {
def ip = nebula('update-config network-config dutip --board-name='+board)
def description = ""
def xmlFile = board+'_HWTestResults.xml'
sh 'cp -r /root/.matlabro /root/.matlab'
under_scm = isMultiBranchPipeline()
if (under_scm)
Expand All @@ -506,11 +549,18 @@ def stage_library(String stage_name) {
try{
sh 'IIO_URI="ip:'+ip+'" board="'+board+'" elasticserver='+gauntEnv.elastic_server+' /usr/local/MATLAB/'+gauntEnv.matlab_release+'/bin/matlab -nosplash -nodesktop -nodisplay -r "run(\'matlab_commands.m\');exit"'
}catch (Exception ex){
// log Jira
try{
description += readFile 'failures.txt'
}catch(Exception desc){
println('Error updating description.')
}finally{
logJira([board:board, summary:'MATLAB tests failed.', description: description, attachment:[xmlFile]])
}
throw new NominalException(ex.getMessage())
}finally{
junit testResults: '*.xml', allowEmptyResults: true
// get MATLAB hardware test results for logging
xmlFile = board+'_HWTestResults.xml'
if(fileExists(xmlFile)){
try{
parseForLogging ('matlab', xmlFile, board)
Expand All @@ -531,11 +581,18 @@ def stage_library(String stage_name) {
try{
sh 'IIO_URI="ip:'+ip+'" board="'+board+'" elasticserver='+gauntEnv.elastic_server+' /usr/local/MATLAB/'+gauntEnv.matlab_release+'/bin/matlab -nosplash -nodesktop -nodisplay -r "run(\'matlab_commands.m\');exit"'
}catch (Exception ex){
// log Jira
try{
description += readFile 'failures.txt'
}catch(Exception desc){
println('Error updating description.')
}finally{
logJira([board:board, summary:'MATLAB tests failed.', description: description, attachment:[xmlFile]])
}
throw new NominalException(ex.getMessage())
}finally{
junit testResults: '*.xml', allowEmptyResults: true
// get MATLAB hardware test results for logging
xmlFile = board+'_HWTestResults.xml'
if(fileExists(xmlFile)){
try{
parseForLogging ('matlab', xmlFile, board)
Expand Down Expand Up @@ -973,6 +1030,115 @@ def set_recovery_reference(reference) {
gauntEnv.recovery_ref = reference
}

/**
* Enable logging issues to Jira. Setting true will update existing Jira issues or create a new issue.
* @param log_jira Boolean of enable jira logging.
*/
def set_log_jira(log_jira) {
gauntEnv.log_jira = log_jira
}

/**
* Set stages where Jira issues should be updated or created.
* @param log_jira_stages List of stage names
*/
def set_log_jira_stages(log_jira_stages) {
gauntEnv.log_jira_stages = log_jira_stages
}

/**
* Creates or updates existing Jira issue for carrier-daughter board
* Each stage has its own Jira thread for each carrier-daughter board
* Required key: jiraArgs.summary, other fields have default values or optional
* attachments is a list of filesnames to upload in the Jira issue
* Default values: Jira site: ADI SDG
* project: HTH
* issuetype: Bug
* assignee: JPineda3
* component: KuiperTesting
*/

def logJira(jiraArgs) {
defaultFields = [site:'sdg-jira',project:'HTH', assignee:'JPineda3', issuetype:'Bug', components:"KuiperTesting", description:"Issue exists in recent build."]
optionalFields = ['assignee','issuetype','description']
def key = ''
// Assign default values if not defined in jiraArgs
for (field in defaultFields.keySet()){
if (!jiraArgs.containsKey(field)){
jiraArgs.put(field,defaultFields."${field}")
}
}
// Append [carier-daugther] to summary
jiraArgs.board = jiraArgs.board.replaceAll('_', '-')
try{
jiraArgs.summary = "["+nebula('update-config board-config carrier --board-name='+jiraArgs.board )+"-"+nebula('update-config board-config daughter --board-name='+jiraArgs.board )+"] ".concat(jiraArgs.summary)
}catch(Exception summary){
println('Jira: Cannot append [carier-daugther] to summary.')
}
// Include hdl and linux hash if available
try{
jiraArgs.description = "{color:#de350b}*[hdl_hash:"+get_elastic_field(jiraArgs.board, 'hdl_hash' , 'NA')+", linux_hash:"+get_elastic_field(jiraArgs.board, 'linux_hash' , 'NA')+"]*{color}\n".concat(jiraArgs.description)
jiraArgs.description = "["+env.JOB_NAME+'-build-'+env.BUILD_NUMBER+"]\n".concat(jiraArgs.description)
}catch(Exception desc){
println('Jira: Cannot include hdl and linux hash to description.')
}
echo 'Checking if Jira logging is enabled..'
try{
if (gauntEnv.log_jira) {
echo 'Checking if stage is included in log_jira_stages'
if (gauntEnv.log_jira_stages.isEmpty() || !gauntEnv.log_jira_stages.isEmpty() && (env.STAGE_NAME in gauntEnv.log_jira_stages)) {
println('Jira logging is enabled for '+env.STAGE_NAME+'. Checking if Jira issue with summary '+jiraArgs.summary+' exists..')
existingIssuesSearch = jiraJqlSearch jql: "project='${jiraArgs.project}' and summary ~ '\"${jiraArgs.summary}\"'", site: jiraArgs.site, failOnError: true
// Comment on existing Jira ticket
if (existingIssuesSearch.data.total != 0){
echo 'Updating existing issue..'
existingIssue = existingIssuesSearch.data.issues
key = existingIssue[0].key
issueUpdate = jiraArgs.description
comment = [body: issueUpdate]
jiraAddComment site: jiraArgs.site, idOrKey: key, input: comment
}
// Create new Jira ticket
else{
echo 'Issue does not exist. Creating new Jira issue..'
// Required fields
issue = [fields: [
project: [key: jiraArgs.project],
summary: jiraArgs.summary,
assignee: [name: jiraArgs.assignee],
issuetype: [name: jiraArgs.issuetype],
components: [[name:jiraArgs.components]]]]
// Optional fields
for (field in optionalFields){
if (jiraArgs.containsKey(field)){
if (field == 'description'){
issue.fields.put(field,jiraArgs."${field}")
}else{
issue.fields.put(field,[name:jiraArgs."${field}"])
}
}
}
def newIssue = jiraNewIssue issue: issue, site: jiraArgs.site
key = newIssue.data.key
}
// Upload attachment if any
if (jiraArgs.containsKey("attachment") && jiraArgs.attachment != null){
echo 'Uploading attachments..'
for (attachmentFile in jiraArgs.attachment){
def attachment = jiraUploadAttachment site: jiraArgs.site, idOrKey: key, file: attachmentFile
}
}
}else{
println('Jira logging is not enabled for '+env.STAGE_NAME+'.')
}
}else{
echo 'Jira logging is disabled for all stages.'
}
}catch(Exception jiraError){
println('Error creating/updating Jira issue.')
}
}

/**
* Main method for starting pipeline once configuration is complete
* Once called all agents are queried for attached boards and parallel stages
Expand Down
2 changes: 2 additions & 0 deletions vars/getGauntEnv.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ private def call(hdlBranch, linuxBranch, bootPartitionBranch,firmwareVersion, bo
nebula_config_branch: 'master',
send_results: false,
elastic_logs : [:],
log_jira: false,
log_jira_stages: [],
max_retry: 3,
recovery_ref: "SD"
]
Expand Down

0 comments on commit 60a0718

Please sign in to comment.