Drop all code handling autocloud test results
Autocloud was retired years ago, we don't need any of this any more. Simplifies things quite a bit. Yay. Signed-off-by: Adam Williamson <awilliam@redhat.com>
This commit is contained in:
parent
aca3474fd2
commit
d965a3725b
2 changed files with 18 additions and 257 deletions
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
"""Fedora nightly image finder."""
|
||||
|
||||
from collections import (OrderedDict, defaultdict)
|
||||
from collections import OrderedDict
|
||||
import datetime
|
||||
import functools
|
||||
import itertools
|
||||
|
|
@ -38,9 +38,6 @@ import openqa_client.client
|
|||
import openqa_client.exceptions
|
||||
from openqa_client import const as oqc
|
||||
|
||||
from urllib.parse import urlencode
|
||||
from urllib.request import Request
|
||||
|
||||
# HTML template
|
||||
HTML_TEMPLATE = """
|
||||
<!DOCTYPE html>
|
||||
|
|
@ -92,33 +89,6 @@ def current_releases():
|
|||
else:
|
||||
return ['Rawhide']
|
||||
|
||||
def recursive_dict():
|
||||
"""It's defaultdicts all the way down, Jim. Per
|
||||
https://the.randomengineer.com/2015/04/28/python-recursive-defaultdict/
|
||||
"""
|
||||
return defaultdict(recursive_dict)
|
||||
|
||||
def datagrepper_query(topics, days):
|
||||
"""Get messages on specified topics in the last X days."""
|
||||
messages = []
|
||||
secs = days * 24 * 60 * 60
|
||||
page = 1
|
||||
params = [('topic', topic) for topic in topics]
|
||||
params.extend([('delta', secs), ('page', page)])
|
||||
baseurl = 'https://apps.fedoraproject.org/datagrepper/raw'
|
||||
nxt = True
|
||||
while nxt:
|
||||
url = '?'.join((baseurl, urlencode(params)))
|
||||
headers = {'Content-type': 'application/json'}
|
||||
req = Request(url, headers=headers)
|
||||
resp = fedfind.helpers.download_json(req)
|
||||
messages.extend(message['msg'] for message in resp['raw_messages'])
|
||||
page += 1
|
||||
params[-1] = ('page', page)
|
||||
if resp['pages'] < page:
|
||||
nxt = False
|
||||
return messages
|
||||
|
||||
def get_cell(image):
|
||||
"""Build a results table cell for an image. This is a bit complex
|
||||
and looks pretty messy in-line in add_group, so it's split out
|
||||
|
|
@ -136,18 +106,13 @@ def get_cell(image):
|
|||
# cell to include the failed test links popups.
|
||||
# First build the links div:
|
||||
faillinks = ['Failed tests:']
|
||||
if image['openqa']:
|
||||
fails = [(str(job['id']), job['test']) for job in image['openqa']
|
||||
if job['result'] not in (oqc.JOB_RESULT_PASSED, oqc.JOB_RESULT_SOFTFAILED)]
|
||||
if fails:
|
||||
faillinks.extend(
|
||||
[Element('a', "openQA: {0} ({1})".format(jobid, jobtest),
|
||||
href='https://openqa.fedoraproject.org/tests/{0}'.format(jobid))
|
||||
for (jobid, jobtest) in fails])
|
||||
elif image['autocloud']:
|
||||
job = str(image['autocloud']['job_id'])
|
||||
url = 'https://apps.fedoraproject.org/autocloud/jobs/{0}/output'.format(job)
|
||||
faillinks.append(Element('a', "Autocloud: " + job, href=url))
|
||||
fails = [(str(job['id']), job['test']) for job in image['openqa']
|
||||
if job['result'] not in (oqc.JOB_RESULT_PASSED, oqc.JOB_RESULT_SOFTFAILED)]
|
||||
if fails:
|
||||
faillinks.extend(
|
||||
[Element('a', "openQA: {0} ({1})".format(jobid, jobtest),
|
||||
href='https://openqa.fedoraproject.org/tests/{0}'.format(jobid))
|
||||
for (jobid, jobtest) in fails])
|
||||
faillinksdiv = Element('div', faillinks, cssclass='faillinks')
|
||||
# now wrap it and the image link in the cell div:
|
||||
imglink = lnpart(cssclass='failedlink')
|
||||
|
|
@ -281,7 +246,6 @@ class Image(dict):
|
|||
# we always want these keys to exist, so set default values
|
||||
# *BEFORE* super __init__
|
||||
self['openqa'] = []
|
||||
self['autocloud'] = []
|
||||
super(Image, self).__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
|
|
@ -334,23 +298,11 @@ class Image(dict):
|
|||
if any tests failed, True if all tests passed, None if we have
|
||||
no test results.
|
||||
"""
|
||||
openqa = autocloud = None
|
||||
res = None
|
||||
if self.get('openqa'):
|
||||
openqa = all(job['result'] in (oqc.JOB_RESULT_PASSED, oqc.JOB_RESULT_SOFTFAILED)
|
||||
res = all(job['result'] in (oqc.JOB_RESULT_PASSED, oqc.JOB_RESULT_SOFTFAILED)
|
||||
for job in self['openqa'])
|
||||
if self.get('autocloud'):
|
||||
autocloud = self['autocloud']['status'] == 'success'
|
||||
|
||||
# if any test type failed, 'False'
|
||||
if any(tests is False for tests in (openqa, autocloud)):
|
||||
return False
|
||||
# else if any test type passed, 'True', because others must be
|
||||
# 'True' or 'None'
|
||||
if any(tests is True for tests in (openqa, autocloud)):
|
||||
return True
|
||||
# else None, because all must be 'None'
|
||||
else:
|
||||
return None
|
||||
return res
|
||||
|
||||
def matches(self, other):
|
||||
"""Check if this Image represents the same image as another
|
||||
|
|
@ -492,13 +444,6 @@ class Nightlies(object):
|
|||
composes.append(cid)
|
||||
self.add_images(composes)
|
||||
self.update_openqa(composes)
|
||||
|
||||
# autocloud: pull messages from datagrepper, since there is no
|
||||
# API
|
||||
topics = ('org.fedoraproject.prod.autocloud.image.success',
|
||||
'org.fedoraproject.prod.autocloud.image.failed')
|
||||
self.update_autocloud(datagrepper_query(topics, days))
|
||||
|
||||
self.write_data()
|
||||
|
||||
def add_images(self, composes):
|
||||
|
|
@ -599,45 +544,6 @@ class Nightlies(object):
|
|||
"flavor %s, arch %s, compose %s", flavor, arch, compose)
|
||||
logger.info("openQA update done")
|
||||
|
||||
def update_autocloud(self, messages):
|
||||
"""Update data based on Autocloud test results. As the API
|
||||
still isn't available, we can only run on fedmsg output for
|
||||
now, so we expect to be passed fedmsg message dicts.
|
||||
"""
|
||||
updated = set()
|
||||
for message in messages:
|
||||
imgurl = message.get('compose_url', message.get('image_url'))
|
||||
filename = imgurl.split('/')[-1]
|
||||
compose = message.get('compose_id')
|
||||
logger.info("Processing Autocloud result for %s", filename)
|
||||
matches = []
|
||||
# find the image by filename and compose ID (for newer-style
|
||||
# messages). If there isn't one and we haven't updated the
|
||||
# built data for this compose, update it and try again.
|
||||
while True:
|
||||
matches = [image for image in self.data if
|
||||
image['path'].split('/')[-1] == filename]
|
||||
# we only get a compose ID for newer-style messages
|
||||
if compose:
|
||||
matches = [match for match in matches if match['compose'] == compose]
|
||||
if matches or compose in updated:
|
||||
break
|
||||
else:
|
||||
self.add_images([compose])
|
||||
updated.add(compose)
|
||||
# no match
|
||||
if not matches:
|
||||
logger.warning("update_autocloud: No Image found for %s", filename)
|
||||
elif len(matches) > 1:
|
||||
logger.warning("update_autocloud: More than one Image found for %s", filename)
|
||||
else:
|
||||
# AFAIK there's just one 'test event' per image in
|
||||
# autocloud; whenever we get a message we can just call
|
||||
# that the current autocloud 'status' for the image and
|
||||
# stuff it in the image dict, overriding whatever was
|
||||
# there before
|
||||
matches[0]['autocloud'] = message
|
||||
|
||||
def find_latest(self, rel, group, arch):
|
||||
"""Find 'last built' and 'last known good' for a specific
|
||||
release, group and arch.
|
||||
|
|
@ -703,8 +609,7 @@ class Nightlies(object):
|
|||
|
||||
class NightlyConsumer(object):
|
||||
"""A fedora-messaging consumer that updates the data when a new
|
||||
compose appears, when openQA testing for a compose completes, and
|
||||
when autocloud testing for an image completes.
|
||||
compose appears or when openQA testing for a compose completes.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.datafile = fedora_messaging.config.conf["consumer_config"].get("datafile")
|
||||
|
|
@ -749,11 +654,6 @@ class NightlyConsumer(object):
|
|||
self.log.info("Updating for openQA results of compose %s", compose)
|
||||
# set the method to run
|
||||
meth = functools.partial(nightlies.update_openqa, [compose])
|
||||
else:
|
||||
# autocloud image tests done
|
||||
image = message.body.get('compose_url', message.body.get('image_url'))
|
||||
self.log.info("Updating for Autocloud results of image %s", image)
|
||||
meth = functools.partial(nightlies.update_autocloud, [message.body])
|
||||
# do the update
|
||||
meth()
|
||||
nightlies.write_data()
|
||||
|
|
|
|||
|
|
@ -29,80 +29,6 @@ import pytest
|
|||
import fedora_nightlies
|
||||
import openqa_client.const as oqc
|
||||
|
||||
# Fake PDC output; filtered down from real output for conciseness
|
||||
|
||||
# old autocloud format
|
||||
PDC1 = {
|
||||
"arguments": {
|
||||
"page": 1,
|
||||
"rows_per_page": 1,
|
||||
"start": 1460847632.0,
|
||||
"topics": [
|
||||
"org.fedoraproject.prod.autocloud.image.failed",
|
||||
"org.fedoraproject.prod.autocloud.image.success"
|
||||
],
|
||||
"users": []
|
||||
},
|
||||
"count": 1,
|
||||
"pages": 2,
|
||||
"raw_messages": [
|
||||
{
|
||||
"i": 644,
|
||||
"msg": {
|
||||
"buildid": 13696295,
|
||||
"image_name": "Fedora-Cloud-Base-Vagrant-Libvirt",
|
||||
"image_url": "https://kojipkgs.fedoraproject.org//work/tasks/6295/13696295/Fedora-Cloud-Base-Vagrant-Rawhide-20160418.n.0.x86_64.vagrant-libvirt.box",
|
||||
"job_id": 1992,
|
||||
"release": "Rawhide",
|
||||
"status": "failed"
|
||||
},
|
||||
"msg_id": "2016-266296ba-a338-4429-9118-5a0d9d15a606",
|
||||
"source_name": "datanommer",
|
||||
"source_version": "0.6.5",
|
||||
"timestamp": 1460966406.0,
|
||||
"topic": "org.fedoraproject.prod.autocloud.image.failed"
|
||||
}
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
|
||||
# new autocloud format
|
||||
PDC2 = {
|
||||
"arguments": {
|
||||
"page": 2,
|
||||
"rows_per_page": 1,
|
||||
"start": 1460847632.0,
|
||||
"topics": [
|
||||
"org.fedoraproject.prod.autocloud.image.failed",
|
||||
"org.fedoraproject.prod.autocloud.image.success"
|
||||
],
|
||||
"users": []
|
||||
},
|
||||
"count": 1,
|
||||
"pages": 2,
|
||||
"raw_messages": [
|
||||
{
|
||||
"i": 260,
|
||||
"msg": {
|
||||
"compose_id": "Fedora-Atomic-24-20160712.0",
|
||||
"compose_url": "http://kojipkgs.fedoraproject.org/compose//twoweek/Fedora-Atomic-24-20160712.0/compose/CloudImages/x86_64/images/Fedora-Cloud-Base-Vagrant-24-20160712.0.x86_64.vagrant-libvirt.box",
|
||||
"family": "Base",
|
||||
"image_name": "Fedora-Cloud-Base-Vagrant-24-20160712.0",
|
||||
"job_id": 193,
|
||||
"release": "atomic",
|
||||
"status": "success",
|
||||
"type": "vagrant-libvirt"
|
||||
},
|
||||
"msg_id": "2016-ea3e5ed2-923d-44a9-8402-716c6d168d4c",
|
||||
"source_name": "datanommer",
|
||||
"source_version": "0.6.5",
|
||||
"timestamp": 1468345355.0,
|
||||
"topic": "org.fedoraproject.prod.autocloud.image.success"
|
||||
}
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
|
||||
def _fake_get_current(branched=False):
|
||||
"""Fake fedfind.helpers.get_current_release for case when there is
|
||||
a Branched. Return 24 if branched is true, otherwise 23.
|
||||
|
|
@ -111,26 +37,6 @@ def _fake_get_current(branched=False):
|
|||
return 24
|
||||
return 23
|
||||
|
||||
def _fake_download_json(request):
|
||||
"""Fake fedfind.helpers.download_json. Returns two pages of fake
|
||||
PDC-ish output. Checks the URL contains correct params for the
|
||||
test.
|
||||
"""
|
||||
# first position arg to the Request mock is URL
|
||||
url = request.get_full_url()
|
||||
if 'delta=604800' not in url:
|
||||
raise ValueError("Invalid delta! URL: {0}".format(url))
|
||||
if not all('topic=org.fedoraproject.prod.autocloud.image.{0}'.format(topic) in url
|
||||
for topic in ['failed', 'success']):
|
||||
raise ValueError("Missing topic(s)! URL: {0}".format(url))
|
||||
if 'page=1' in url:
|
||||
return PDC1
|
||||
elif 'page=2' in url:
|
||||
return PDC2
|
||||
else:
|
||||
# make sure we never get here
|
||||
raise ValueError("Invalid page!")
|
||||
|
||||
|
||||
class FakeElement(object):
|
||||
"""Mock 'Element' class which just stores the args it was called
|
||||
|
|
@ -162,34 +68,6 @@ def test_current_releases_no_branched(fakecurr):
|
|||
fedora_nightlies.CURRENT_RELEASES = []
|
||||
assert fedora_nightlies.current_releases() == ['Rawhide']
|
||||
|
||||
def test_recursive_dict():
|
||||
"""This should behave like, well, a recursive dict. So check
|
||||
setting a value in a dict some crazy number of levels down,
|
||||
and check that an instance several levels down is still a
|
||||
collections.defaultdict.
|
||||
"""
|
||||
recdict = fedora_nightlies.recursive_dict()
|
||||
recdict[1][2][3][4][5][6][7][8] = "boy, it's dark down here"
|
||||
assert recdict[1][2][3][4][5][6][7][8] == "boy, it's dark down here"
|
||||
assert isinstance(recdict['foo']['bar'], collections.defaultdict)
|
||||
|
||||
@mock.patch('fedfind.helpers.download_json', _fake_download_json)
|
||||
def test_datagrepper_query():
|
||||
"""datagrepper_query should get the multi-page data correctly
|
||||
and return the list of actual fedmsgs (it throws away the rest
|
||||
of the data, for now at least; if that changes, this test will
|
||||
need changing too). Note, some checking is done in _fake_download
|
||||
_json here (I couldn't figure a way to mock the Request that's
|
||||
passed to download_json such that we can check its properties
|
||||
here).
|
||||
"""
|
||||
topics = ["org.fedoraproject.prod.autocloud.image.failed",
|
||||
"org.fedoraproject.prod.autocloud.image.success"]
|
||||
ret = fedora_nightlies.datagrepper_query(topics, 7)
|
||||
assert len(ret) == 2
|
||||
assert ret[0]['job_id'] == 1992
|
||||
assert ret[1]['job_id'] == 193
|
||||
|
||||
# we're not testing the behaviour of Element here, so use FakeElement
|
||||
@mock.patch('fedora_nightlies.Element', FakeElement)
|
||||
def test_get_cell_pass():
|
||||
|
|
@ -202,7 +80,7 @@ def test_get_cell_pass():
|
|||
compose = "Fedora-Rawhide-20160418.n.0"
|
||||
url = "https://kojipkgs.fedoraproject.org/compose/rawhide/Fedora-Rawhide-20160418.n.0/compose/CloudImages/x86_64/images/Fedora-Cloud-Base-Rawhide-20160418.n.0.x86_64.qcow2"
|
||||
image = fedora_nightlies.Image({
|
||||
'autocloud': {'status': "success"},
|
||||
'openqa': [{'result': "passed"}],
|
||||
'compose': compose,
|
||||
'url': url
|
||||
})
|
||||
|
|
@ -376,42 +254,25 @@ def test_image():
|
|||
assert img.release == "29"
|
||||
# newly-instantiated image must always have these attributes
|
||||
assert img['openqa'] == []
|
||||
assert img['autocloud'] == []
|
||||
assert img.group == "AtomicHost dvd-ostree"
|
||||
assert img.openqa_flavor == "AtomicHost-dvd_ostree-iso"
|
||||
|
||||
# test passed/failed/None test combinations work correctly
|
||||
# None
|
||||
assert img.testspass is None
|
||||
# test various passed/failed test combinations work correctly
|
||||
# ac pass oq none
|
||||
img['autocloud'] = {'status': "success"}
|
||||
assert img.testspass is True
|
||||
# ac pass oq pass
|
||||
# Pass
|
||||
img['openqa'] = [{'result': oqc.JOB_RESULT_PASSED}]
|
||||
assert img.testspass is True
|
||||
# ac pass oq fail
|
||||
# Fail
|
||||
img['openqa'] = [{'result': oqc.JOB_RESULT_FAILED}]
|
||||
assert img.testspass is False
|
||||
# ac fail oq fail
|
||||
img['autocloud'] = {'status': "failed"}
|
||||
assert img.testspass is False
|
||||
# ac fail oq pass
|
||||
img['openqa'] = [{'result': oqc.JOB_RESULT_PASSED}]
|
||||
assert img.testspass is False
|
||||
# ac fail oq none
|
||||
img['openqa'] = []
|
||||
assert img.testspass is False
|
||||
# ac none oq pass
|
||||
img['autocloud'] = []
|
||||
img['openqa'] = [{'result': oqc.JOB_RESULT_PASSED}]
|
||||
assert img.testspass is True
|
||||
# ac none oq softfail
|
||||
# Softfail
|
||||
img['openqa'] = [{'result': oqc.JOB_RESULT_SOFTFAILED}]
|
||||
assert img.testspass is True
|
||||
|
||||
# clone image to test matches
|
||||
img2 = fedora_nightlies.Image(img)
|
||||
img2['openqa'] = []
|
||||
img2['autocloud'] = {'status': "failed"}
|
||||
# same image with different test results should match
|
||||
assert img.matches(img2)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue