Add comment
This commit is contained in:
parent
429ff42489
commit
c17a336856
@ -61,7 +61,7 @@ QA_INPROGRESS = 1
|
|||||||
QA_FAILED = 2
|
QA_FAILED = 2
|
||||||
QA_PASSED = 3
|
QA_PASSED = 3
|
||||||
|
|
||||||
comment_marker_re = re.compile(r'<!-- openqa state=(?P<state>done|seen)(?: result=(?P<result>accepted|declined))? -->')
|
comment_marker_re = re.compile(r'<!-- openqa state=(?P<state>done|seen)(?: result=(?P<result>accepted|declined))?(?: maxreporevision=(?P<revision>\d+))? -->')
|
||||||
|
|
||||||
logger = None
|
logger = None
|
||||||
|
|
||||||
@ -685,13 +685,14 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
comment = "<!-- openqa state=%s%s -->\n" % (state, ' result=%s' % result if result else '')
|
comment = "<!-- openqa state=%s%s -->\n" % (state, ' result=%s' % result if result else '')
|
||||||
comment += "\n" + msg
|
comment += "\n" + msg
|
||||||
|
|
||||||
(comment_id, comment_state, comment_result, comment_text) = self.find_obs_request_comment(req, state)
|
info = self.find_obs_request_comment(state=state, request_id=req.reqid)
|
||||||
|
comment_id = info.get('id', None)
|
||||||
|
|
||||||
if comment_id is not None and state == comment_state:
|
if state == info.get('state', 'missing'):
|
||||||
lines_before = len(comment_text.split('\n'))
|
lines_before = len(info['comment'].split('\n'))
|
||||||
lines_after = len(comment.split('\n'))
|
lines_after = len(comment.split('\n'))
|
||||||
if lines_before == lines_after:
|
if lines_before == lines_after:
|
||||||
self.logger.debug("not worth the update, previous comment %s is state %s", comment_id, comment_state)
|
self.logger.debug("not worth the update, previous comment %s is state %s", comment_id, info['state'])
|
||||||
return
|
return
|
||||||
|
|
||||||
self.logger.debug("adding comment to %s, state %s result %s", req.reqid, state, result)
|
self.logger.debug("adding comment to %s, state %s result %s", req.reqid, state, result)
|
||||||
@ -718,7 +719,10 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
def summarize_one_openqa_job(self, job):
|
def summarize_one_openqa_job(self, job):
|
||||||
testurl = osc.core.makeurl(self.openqa.baseurl, ['tests', str(job['id'])])
|
testurl = osc.core.makeurl(self.openqa.baseurl, ['tests', str(job['id'])])
|
||||||
if not job['result'] in ['passed', 'failed', 'softfailed']:
|
if not job['result'] in ['passed', 'failed', 'softfailed']:
|
||||||
return '\n- [%s](%s) is %s' % (self.job_test_name(job), testurl, job['result'])
|
rstring = job['result']
|
||||||
|
if rstring == 'none':
|
||||||
|
rstring = job['state']
|
||||||
|
return '\n- [%s](%s) is %s' % (self.job_test_name(job), testurl, rstring)
|
||||||
|
|
||||||
modstrings = []
|
modstrings = []
|
||||||
for module in job['modules']:
|
for module in job['modules']:
|
||||||
@ -732,43 +736,7 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
return '\n- [%s](%s) failed' % (self.job_test_name(job), testurl)
|
return '\n- [%s](%s) failed' % (self.job_test_name(job), testurl)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def check_one_request(self, req):
|
def summarize_openqa_jobs(self, jobs):
|
||||||
ret = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
jobs = self.request_get_openqa_jobs(req)
|
|
||||||
qa_state = self.calculate_qa_status(jobs)
|
|
||||||
self.logger.debug("request %s state %s", req.reqid, qa_state)
|
|
||||||
msg = None
|
|
||||||
if self.force or qa_state == QA_UNKNOWN:
|
|
||||||
ret = ReviewBot.ReviewBot.check_one_request(self, req)
|
|
||||||
jobs = self.request_get_openqa_jobs(req)
|
|
||||||
|
|
||||||
if self.force:
|
|
||||||
# make sure to delete previous comments if we're forcing
|
|
||||||
(comment_id, comment_state, comment_result, comment_text) = self.find_obs_request_comment(req)
|
|
||||||
if comment_id is not None:
|
|
||||||
self.logger.debug("deleting old comment %s", comment_id)
|
|
||||||
if not self.dryrun:
|
|
||||||
self.commentapi.delete(comment_id)
|
|
||||||
|
|
||||||
if not jobs:
|
|
||||||
msg = "no openQA tests defined"
|
|
||||||
self.add_comment(req, msg, 'done', 'accepted')
|
|
||||||
ret = True
|
|
||||||
else:
|
|
||||||
# no notification until the result is done
|
|
||||||
osc.core.change_review_state(self.apiurl, req.reqid, newstate='new',
|
|
||||||
by_group=self.review_group, by_user=self.review_user,
|
|
||||||
message='now testing in openQA')
|
|
||||||
elif qa_state == QA_FAILED or qa_state == QA_PASSED:
|
|
||||||
# don't take test repo results into the calculation of total
|
|
||||||
# this is for humans to decide which incident broke the test repo
|
|
||||||
jobs += self.request_get_openqa_jobs(req, incident=False, test_repo=True)
|
|
||||||
if self.calculate_qa_status(jobs) == QA_INPROGRESS:
|
|
||||||
self.logger.debug(
|
|
||||||
"incident tests for request %s are done, but need to wait for test repo", req.reqid)
|
|
||||||
return
|
|
||||||
groups = dict()
|
groups = dict()
|
||||||
for job in jobs:
|
for job in jobs:
|
||||||
gl = "%s@%s" % (self.emd(job['group']), self.emd(job['settings']['FLAVOR']))
|
gl = "%s@%s" % (self.emd(job['group']), self.emd(job['settings']['FLAVOR']))
|
||||||
@ -792,23 +760,62 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
gmsg = groups[gl]
|
gmsg = groups[gl]
|
||||||
groups[gl]['failed'].append(job_summary)
|
groups[gl]['failed'].append(job_summary)
|
||||||
|
|
||||||
if qa_state == QA_PASSED:
|
msg = ''
|
||||||
self.logger.debug("request %s passed", req.reqid)
|
|
||||||
msg = "openQA tests passed\n"
|
|
||||||
state = 'accepted'
|
|
||||||
ret = True
|
|
||||||
else:
|
|
||||||
self.logger.debug("request %s failed", req.reqid)
|
|
||||||
msg = "openQA tests problematic\n"
|
|
||||||
state = 'declined'
|
|
||||||
ret = False
|
|
||||||
|
|
||||||
for group in sorted(groups.keys()):
|
for group in sorted(groups.keys()):
|
||||||
msg += "\n\n" + groups[group]['title']
|
msg += "\n\n" + groups[group]['title']
|
||||||
msg += "(%d tests passed, %d failed)\n" % (groups[group]['passed'], len(groups[group]['failed']))
|
msg += "(%d tests passed, %d failed)\n" % (groups[group]['passed'], len(groups[group]['failed']))
|
||||||
for fail in groups[group]['failed']:
|
for fail in groups[group]['failed']:
|
||||||
msg += fail
|
msg += fail
|
||||||
|
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def check_one_request(self, req):
|
||||||
|
ret = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
jobs = self.request_get_openqa_jobs(req)
|
||||||
|
qa_state = self.calculate_qa_status(jobs)
|
||||||
|
self.logger.debug("request %s state %s", req.reqid, qa_state)
|
||||||
|
msg = None
|
||||||
|
if self.force or qa_state == QA_UNKNOWN:
|
||||||
|
ret = ReviewBot.ReviewBot.check_one_request(self, req)
|
||||||
|
jobs = self.request_get_openqa_jobs(req)
|
||||||
|
|
||||||
|
if self.force:
|
||||||
|
# make sure to delete previous comments if we're forcing
|
||||||
|
info = self.find_obs_request_comment(request_id=req.reqid)
|
||||||
|
if 'id' in info:
|
||||||
|
self.logger.debug("deleting old comment %s", info['id'])
|
||||||
|
if not self.dryrun:
|
||||||
|
self.commentapi.delete(info['id'])
|
||||||
|
|
||||||
|
if not jobs:
|
||||||
|
msg = "no openQA tests defined"
|
||||||
|
self.add_comment(req, msg, 'done', 'accepted')
|
||||||
|
ret = True
|
||||||
|
else:
|
||||||
|
# no notification until the result is done
|
||||||
|
osc.core.change_review_state(self.apiurl, req.reqid, newstate='new',
|
||||||
|
by_group=self.review_group, by_user=self.review_user,
|
||||||
|
message='now testing in openQA')
|
||||||
|
elif qa_state == QA_FAILED or qa_state == QA_PASSED:
|
||||||
|
# don't take test repo results into the calculation of total
|
||||||
|
# this is for humans to decide which incident broke the test repo
|
||||||
|
jobs += self.request_get_openqa_jobs(req, incident=False, test_repo=True)
|
||||||
|
if self.calculate_qa_status(jobs) == QA_INPROGRESS:
|
||||||
|
self.logger.debug(
|
||||||
|
"incident tests for request %s are done, but need to wait for test repo", req.reqid)
|
||||||
|
return
|
||||||
|
if qa_state == QA_PASSED:
|
||||||
|
msg = "openQA tests passed\n"
|
||||||
|
state = 'accepted'
|
||||||
|
ret = True
|
||||||
|
else:
|
||||||
|
msg = "openQA tests problematic\n"
|
||||||
|
state = 'declined'
|
||||||
|
ret = False
|
||||||
|
|
||||||
|
msg += self.summarize_openqa_jobs(jobs)
|
||||||
self.add_comment(req, msg, 'done', state)
|
self.add_comment(req, msg, 'done', state)
|
||||||
elif qa_state == QA_INPROGRESS:
|
elif qa_state == QA_INPROGRESS:
|
||||||
self.logger.debug("request %s still in progress", req.reqid)
|
self.logger.debug("request %s still in progress", req.reqid)
|
||||||
@ -823,15 +830,15 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def find_obs_request_comment(self, req, state=None):
|
def find_obs_request_comment(self, request_id=None, project_name=None, state=None):
|
||||||
"""Return previous comments (should be one)."""
|
"""Return previous comments (should be one)."""
|
||||||
if self.do_comments:
|
if self.do_comments:
|
||||||
comments = self.commentapi.get_comments(request_id=req.reqid)
|
comments = self.commentapi.get_comments(request_id=request_id, project_name=project_name)
|
||||||
for c in comments.values():
|
for c in comments.values():
|
||||||
m = comment_marker_re.match(c['comment'])
|
m = comment_marker_re.match(c['comment'])
|
||||||
if m and (state is None or state == m.group('state')):
|
if m and (state is None or state == m.group('state')):
|
||||||
return c['id'], m.group('state'), m.group('result'), c['comment']
|
return { 'id' : c['id'], 'state': m.group('state'), 'result': m.group('result'), 'comment': c['comment'], 'revision': m.group('revision') }
|
||||||
return None, None, None, None
|
return {}
|
||||||
|
|
||||||
def check_product(self, job, product_prefix):
|
def check_product(self, job, product_prefix):
|
||||||
pmap = API_MAP[product_prefix]
|
pmap = API_MAP[product_prefix]
|
||||||
@ -861,14 +868,17 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
|
|
||||||
def test(self):
|
def test(self):
|
||||||
for inc in requests.get('https://maintenance.suse.de/api/incident/active/').json():
|
for inc in requests.get('https://maintenance.suse.de/api/incident/active/').json():
|
||||||
if not inc == '2129': continue
|
if not inc == '4871': continue
|
||||||
job = requests.get('https://maintenance.suse.de/api/incident/' + inc).json()
|
job = requests.get('https://maintenance.suse.de/api/incident/' + inc).json()
|
||||||
|
print json.dumps(job, indent=4)
|
||||||
if job['meta']['state'] in ['final', 'gone']:
|
if job['meta']['state'] in ['final', 'gone']:
|
||||||
continue
|
continue
|
||||||
openqa_posts = []
|
openqa_posts = []
|
||||||
for prod in API_MAP.keys():
|
for prod in API_MAP.keys():
|
||||||
s = self.check_product(job['base'], prod)
|
s = self.check_product(job['base'], prod)
|
||||||
openqa_posts += s
|
openqa_posts += s
|
||||||
|
openqa_jobs = []
|
||||||
|
openqa_done = True
|
||||||
for s in openqa_posts:
|
for s in openqa_posts:
|
||||||
jobs = self.openqa.openqa_request(
|
jobs = self.openqa.openqa_request(
|
||||||
'GET', 'jobs',
|
'GET', 'jobs',
|
||||||
@ -879,14 +889,33 @@ class OpenQABot(ReviewBot.ReviewBot):
|
|||||||
'flavor': s['FLAVOR'],
|
'flavor': s['FLAVOR'],
|
||||||
'build': s['BUILD'],
|
'build': s['BUILD'],
|
||||||
'scope': 'relevant',
|
'scope': 'relevant',
|
||||||
|
'latest': '1'
|
||||||
})['jobs']
|
})['jobs']
|
||||||
if not len(jobs):
|
if not len(jobs):
|
||||||
if self.dryrun:
|
if self.dryrun:
|
||||||
print 'WOULD POST', s
|
print 'WOULD POST', s
|
||||||
else:
|
else:
|
||||||
ret = self.openqa.openqa_request('POST', 'isos', data=s, retries=1)
|
ret = self.openqa.openqa_request('POST', 'isos', data=s, retries=1)
|
||||||
|
openqa_done = False
|
||||||
else:
|
else:
|
||||||
print jobs
|
print s, 'got', len(jobs)
|
||||||
|
openqa_jobs += jobs
|
||||||
|
#print openqa_jobs
|
||||||
|
msg = self.summarize_openqa_jobs(openqa_jobs)
|
||||||
|
state = 'running'
|
||||||
|
comment = "<!-- openqa state=%s maxreporevision=%s -->\n" % (state, job.get('openqa_build'))
|
||||||
|
comment += "\n" + msg
|
||||||
|
|
||||||
|
info = self.find_obs_request_comment(state=state, project_name=str(job['base']['project']))
|
||||||
|
comment_id = info.get('id', None)
|
||||||
|
|
||||||
|
self.logger.debug("adding comment to %s, state %s", job['base']['project'], state)
|
||||||
|
self.logger.debug("message: %s", msg)
|
||||||
|
if not self.dryrun:
|
||||||
|
if comment_id is not None:
|
||||||
|
self.commentapi.delete(comment_id)
|
||||||
|
self.commentapi.add_comment(project_name=str(job['base']['project']), comment=str(comment))
|
||||||
|
|
||||||
|
|
||||||
class CommandLineInterface(ReviewBot.CommandLineInterface):
|
class CommandLineInterface(ReviewBot.CommandLineInterface):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user