fedora-nightlies/test_fedora_nightlies.py
Adam Williamson d965a3725b 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>
2022-01-27 12:20:39 -08:00

290 lines
12 KiB
Python

# Copyright Red Hat
#
# This file is part of fedora_nightlies.
#
# fedora_nightlies is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author: Adam Williamson <awilliam@redhat.com>
"""Tests for the Fedora nightly image finder."""
from __future__ import unicode_literals
from __future__ import print_function
import collections
import itertools
import mock
import pytest
import fedora_nightlies
import openqa_client.const as oqc
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.
"""
if branched:
return 24
return 23
class FakeElement(object):
"""Mock 'Element' class which just stores the args it was called
with.
"""
def __init__(self, name, contents='', cssclass='', **kwargs):
self.name = name
self.contents = contents
self.cssclass = cssclass
self.kwargs = kwargs
@mock.patch('fedfind.helpers.get_current_release', _fake_get_current)
def test_current_releases_branched():
"""If we have a Branched (simulated by _fake_get_current), we
should get it and Rawhide, as strings.
"""
# clear the cache
fedora_nightlies.CURRENT_RELEASES = []
assert fedora_nightlies.current_releases() == ['24', 'Rawhide']
@mock.patch('fedfind.helpers.get_current_release', return_value=24)
def test_current_releases_no_branched(fakecurr):
"""If we have no Branched (simulated by get_current_release always
returning the same value), we should get a single-item list with
only Rawhide.
"""
# clear the cache
fedora_nightlies.CURRENT_RELEASES = []
assert fedora_nightlies.current_releases() == ['Rawhide']
# we're not testing the behaviour of Element here, so use FakeElement
@mock.patch('fedora_nightlies.Element', FakeElement)
def test_get_cell_pass():
"""Check the properties of the HTML table cell for an image that
passed tests. Checks that the FakeElement instances created have
the expected properties. The Image dict in this test must return
True for its testspass property, if it doesn't the test should
fail. We could just mock Image, but mehh.
"""
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({
'openqa': [{'result': "passed"}],
'compose': compose,
'url': url
})
cell = fedora_nightlies.get_cell(image)
assert cell.name == 'td'
# cell's contents is itself an element:
link = cell.contents
assert link.name == 'a'
assert link.contents == compose
assert link.kwargs['href'] == url
assert link.cssclass == 'passedlink'
@mock.patch('fedora_nightlies.Element', FakeElement)
def test_get_cell_untested():
"""Ditto the cell for an 'untested' image."""
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.raw.xz"
image = fedora_nightlies.Image({
'compose': compose,
'url': url
})
cell = fedora_nightlies.get_cell(image)
assert cell.name == 'td'
# cell's contents is itself an element:
link = cell.contents
assert link.name == 'a'
assert link.contents == compose
assert link.kwargs['href'] == url
assert link.cssclass == ''
@mock.patch('fedora_nightlies.Element', FakeElement)
def test_get_cell_failed():
"""Ditto the cell for a 'failed' image. This cell is pretty complex
and has a ton of nested elements, we extract each and check it.
"""
compose = "Fedora-Rawhide-20160418.n.0"
url = "https://kojipkgs.fedoraproject.org/compose/rawhide/Fedora-Rawhide-20160418.n.0/compose/Server/x86_64/iso/Fedora-Server-dvd-x86_64-Rawhide-20160418.n.0.iso"
job = 13335
test = 'base_services_start'
image = fedora_nightlies.Image({
'compose': compose,
'url': url,
'openqa': [{'result': 'failed', 'id': job, 'test': test}]
})
cell = fedora_nightlies.get_cell(image)
assert cell.name == 'td'
# cell's contents is itself a div element:
div = cell.contents
assert div.name == 'div'
assert div.cssclass == 'failcell'
# div's contents is a list of elements:
(imglink, faillinksdiv) = div.contents
assert imglink.name == 'a'
assert imglink.contents == compose
assert imglink.kwargs['href'] == url
assert imglink.cssclass == 'failedlink'
assert faillinksdiv.name == 'div'
assert faillinksdiv.cssclass == 'faillinks'
# this div's contents is a list containing a title and links: just one here
assert len(faillinksdiv.contents) == 2
faillink = faillinksdiv.contents[1]
assert faillink.name == 'a'
assert faillink.contents == 'openQA: {0} ({1})'.format(job, test)
def test_element_short_link():
"""Given a simple link element with short link text and a CSS
class, we should get the correct syntax all on a single line.
"""
elem = fedora_nightlies.Element('a', 'link target', cssclass='test', href='http://www.example.org/link')
assert str(elem) == '<a class="test" href="http://www.example.org/link">link target</a>'
assert elem.contents == ['link target']
def test_element_single_nest():
"""An Element with a single other Element as its contents. Outer
contents should be a single-item list containing inner element.
Text should be correct syntax on a single line.
"""
th = fedora_nightlies.Element('th', 'Title')
tr = fedora_nightlies.Element('tr', th)
assert tr.contents == [th]
assert str(tr) == '<tr><th>Title</th></tr>'
def test_element_short_list():
"""An element with a mixed list of strings and other elements as
its contents; should still come out on a single line so long as
the total length of contents is < 80.
"""
text = "some text "
link = fedora_nightlies.Element('a', 'foo', href='http://www.foo.com')
para = fedora_nightlies.Element('p', "some more text")
contents = [text, link, para]
div = fedora_nightlies.Element('div', contents)
assert div.contents == contents
assert str(div) == '<div>some text <a href="http://www.foo.com">foo</a><p>some more text</p></div>'
def test_element_long_string():
"""An element whose contents is a long string should have the
tags and content on separate lines.
"""
text = ("Lorem ipsum dolor who the hell remembers how the rest of "
"this goes anyway? Not me. Oh well, that's enough.")
elem = fedora_nightlies.Element('p', text)
assert str(elem) == '<p>\n{0}\n</p>'.format(text)
def test_element_long_list():
"""An element whose contents is a list of items whose combined
string representations total more than 80 characters should get
the tags and each item on separate lines.
"""
text1 = "Some text goes here, we love text."
link1 = fedora_nightlies.Element('a', 'link target', href='http://www.link.com')
text2 = "Some more text! Boy, isn't text great."
head = fedora_nightlies.Element('h1', "This is a big important heading!")
elem = fedora_nightlies.Element('div', [text1, link1, text2, head])
assert str(elem) == '<div>\n{0}\n{1}\n{2}\n{3}\n</div>'.format(
text1, str(link1), text2, str(head))
@mock.patch('fedora_nightlies.get_cell', return_value=fedora_nightlies.Element('td', 'fake cell'))
def test_release_table(fakegetcell):
"""Typical release table case. We mock get_cell, so we don't need
any real contents in any of the image dicts, we just need the
shape of the group dicts."""
wslive = {'x86_64': [{}, {}], 'i386': [{}]}
svboot = {'x86_64': [{}], 'i386': []}
# no images, should be skipped
atomic = {'x86_64': [], 'i386': []}
groups = {'Workstation live': wslive, 'Server boot': svboot, 'Atomic': atomic}
table = fedora_nightlies.ReleaseTable('24', groups)
# should try to get a cell for each image
assert fakegetcell.call_count == 4
# table should be, well, a table
assert table.name == 'table'
# table contents should be a list of table rows:
# the release header, two group headers, two column title headers,
# two arch rows for workstation and one arch row for server
# the contents should all be table rows
assert all(elem.name == 'tr' for elem in table.contents)
# we should have two group headers (not three)
grphds = [elem for elem in table.contents if
elem.contents[0].attributes.get('class') == 'groupheader']
assert len(grphds) == 2
# we should have three actual image rows, two for workstation
# (both arches), one for server (x86_64 only)
arches = [elem for elem in table.contents if len(elem.contents) == 3 and
all(cell.name == 'td' for cell in elem.contents)]
assert len(arches) == 3
# we should have two empty 'padding' cells, workstation i386 and
# server x86_64
cells = list(itertools.chain.from_iterable(arch.contents for arch in arches))
empty = [cell for cell in cells if cell.contents == ['']]
assert len(empty) == 2
def test_image():
"""Some tests for the Image class."""
img = fedora_nightlies.Image({
"arch": "x86_64",
"bootable": True,
"compose": "Fedora-29-20181028.n.0",
"disc_count": 1,
"disc_number": 1,
"format": "iso",
"implant_md5": "e0b57a312b61fdc526e521c4de1b59a6",
"mtime": 1540728857,
"path": "AtomicHost/x86_64/iso/Fedora-AtomicHost-ostree-x86_64-29-20181028.n.0.iso",
"size": 1102053376,
"subvariant": "AtomicHost",
"type": "dvd-ostree",
"url": "https://kojipkgs.fedoraproject.org/compose/branched/Fedora-29-20181028.n.0/compose/AtomicHost/x86_64/iso/Fedora-AtomicHost-ostree-x86_64-29-20181028.n.0.iso",
"volume_id": "Fedora-AH-ostree-x86_64-29"
})
assert img.release == "29"
# newly-instantiated image must always have these attributes
assert img['openqa'] == []
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
# Pass
img['openqa'] = [{'result': oqc.JOB_RESULT_PASSED}]
assert img.testspass is True
# Fail
img['openqa'] = [{'result': oqc.JOB_RESULT_FAILED}]
assert img.testspass is False
# 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'] = []
# same image with different test results should match
assert img.matches(img2)
# check Rawhide release
img2['compose'] = 'Fedora-Rawhide-20181028.n.0'
assert img2.release == 'Rawhide'
# check sorting
img2['compose'] = 'Fedora-29-20181028.n.1'
img3 = fedora_nightlies.Image(img2)
img3['compose'] = 'Fedora-29-20181029.n.0'
img4 = fedora_nightlies.Image(img3)
img4['compose'] = 'Fedora-29-20181101.n.0'
imgs = sorted([img2, img, img4, img3], key=lambda x:x.sortid)
assert imgs == [img, img2, img3, img4]