[tests] Use real paths module in testing

This avoids problems of mock paths having different API that the real
ones.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
Lubomír Sedlář 2016-02-11 15:15:36 +01:00
parent 8661d294ab
commit 90954ddf0e
9 changed files with 203 additions and 211 deletions

View File

@ -5,7 +5,7 @@ import os
import time
from kobo import shortcuts
from pungi.util import get_variant_data, resolve_git_url, makedirs
from pungi.util import get_variant_data, resolve_git_url, makedirs, get_mtime, get_file_size
from pungi.phases.base import PhaseBase
from pungi.linker import Linker
from pungi.paths import translate_path
@ -223,8 +223,8 @@ class CreateImageBuildThread(WorkerThread):
img.type = image_info['type']
img.format = image_info['suffix']
img.path = os.path.join(relative_image_dir, os.path.basename(image_dest))
img.mtime = int(os.stat(image_dest).st_mtime)
img.size = os.path.getsize(image_dest)
img.mtime = get_mtime(image_dest)
img.size = get_file_size(image_dest)
img.arch = image_info['arch']
img.disc_number = 1 # We don't expect multiple disks
img.disc_count = 1

View File

@ -28,7 +28,7 @@ from productmd.images import Image
from pungi.wrappers.kojiwrapper import KojiWrapper
from pungi.wrappers.iso import IsoWrapper
from pungi.phases.base import PhaseBase
from pungi.util import get_arch_variant_data, resolve_git_url, makedirs
from pungi.util import get_arch_variant_data, resolve_git_url, makedirs, get_mtime, get_file_size
from pungi.paths import translate_path
@ -281,8 +281,8 @@ class CreateLiveImageThread(WorkerThread):
img.type = type
img.format = format
img.path = os.path.relpath(path, compose.paths.compose.topdir())
img.mtime = int(os.stat(path).st_mtime)
img.size = os.path.getsize(path)
img.mtime = get_mtime(path)
img.size = get_file_size(path)
img.arch = arch
img.disc_number = 1 # We don't expect multiple disks
img.disc_count = 1

View File

@ -4,7 +4,7 @@ import os
import time
from kobo import shortcuts
from pungi.util import get_variant_data, resolve_git_url, makedirs
from pungi.util import get_variant_data, resolve_git_url, makedirs, get_mtime, get_file_size
from pungi.phases.base import PhaseBase
from pungi.linker import Linker
from pungi.paths import translate_path
@ -122,7 +122,7 @@ class LiveMediaThread(WorkerThread):
def _get_log_file(self, compose, variant, config):
arches = '-'.join(config['arches'])
return compose.paths.log.log_file(arches, 'livemedia-%s' % variant)
return compose.paths.log.log_file(arches, 'livemedia-%s' % variant.uid)
def _run_command(self, koji_wrapper, cmd, compose, log_file):
time.sleep(self.num * 3)
@ -186,8 +186,8 @@ class LiveMediaThread(WorkerThread):
img.type = 'live'
img.format = 'iso'
img.path = os.path.join(relative_image_dir, os.path.basename(image_dest))
img.mtime = int(os.stat(image_dest).st_mtime)
img.size = os.path.getsize(image_dest)
img.mtime = get_mtime(image_dest)
img.size = get_file_size(image_dest)
img.arch = image_info['arch']
img.disc_number = 1 # We don't expect multiple disks
img.disc_count = 1

View File

@ -383,3 +383,11 @@ def get_volid(compose, arch, variant=None, escape_spaces=False, disc_type=False)
if volid and escape_spaces:
volid = volid.replace(" ", r"\x20")
return volid
def get_mtime(path):
return int(os.stat(path).st_mtime)
def get_file_size(path):
return os.path.getsize(path)

View File

@ -1,13 +1,24 @@
# -*- coding: utf-8 -*-
import mock
import os
import unittest
import tempfile
import shutil
from pungi.util import get_arch_variant_data
from pungi import paths
class PungiTestCase(unittest.TestCase):
def setUp(self):
self.topdir = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.topdir)
class _DummyCompose(object):
def __init__(self, config):
def __init__(self, topdir, config):
self.compose_date = '20151203'
self.compose_type_suffix = '.t'
self.compose_respin = 0
@ -19,47 +30,17 @@ class _DummyCompose(object):
version='1.0',
),
)
self.topdir = topdir
self.conf = config
self.paths = mock.Mock(
compose=mock.Mock(
topdir=mock.Mock(return_value='/a/b'),
os_tree=mock.Mock(
side_effect=lambda arch, variant, create_dir=False: os.path.join('/ostree', arch, variant.uid)
),
repository=mock.Mock(
side_effect=lambda arch, variant, create_dir=False: os.path.join('/repo', arch, variant.uid)
),
image_dir=mock.Mock(
side_effect=lambda variant, relative=False, symlink_to=None: os.path.join(
'' if relative else '/', 'image_dir', variant.uid, '%(arch)s'
)
),
iso_dir=mock.Mock(
side_effect=lambda arch, variant, symlink_to=None, relative=False: os.path.join(
'' if relative else '/', 'iso_dir', arch, variant.uid
)
),
iso_path=mock.Mock(
side_effect=lambda arch, variant, filename, symlink_to: os.path.join(
'/iso_dir', arch, variant.uid, filename
)
)
),
work=mock.Mock(
image_build_conf=mock.Mock(
side_effect=lambda variant, image_name, image_type:
'-'.join([variant.uid, image_name, image_type])
)
),
log=mock.Mock(
log_file=mock.Mock(return_value='/a/b/log/log_file')
)
)
self.paths = paths.Paths(self)
self._logger = mock.Mock()
self.variants = {
'Server': mock.Mock(uid='Server', arches=['x86_64', 'amd64'], is_empty=False),
'Client': mock.Mock(uid='Client', arches=['amd64'], is_empty=False),
'Everything': mock.Mock(uid='Everything', arches=['x86_64', 'amd64'], is_empty=False),
'Server': mock.Mock(uid='Server', arches=['x86_64', 'amd64'],
type='variant', is_empty=False),
'Client': mock.Mock(uid='Client', arches=['amd64'],
type='variant', is_empty=False),
'Everything': mock.Mock(uid='Everything', arches=['x86_64', 'amd64'],
type='variant', is_empty=False),
}
self.log_error = mock.Mock()
self.get_image_name = mock.Mock(return_value='image-name')

View File

@ -11,14 +11,14 @@ import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from pungi.phases.image_build import ImageBuildPhase, CreateImageBuildThread
from tests.helpers import _DummyCompose
from tests.helpers import _DummyCompose, PungiTestCase
class TestImageBuildPhase(unittest.TestCase):
class TestImageBuildPhase(PungiTestCase):
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'image_build': {
'^Client|Server$': [
{
@ -49,10 +49,10 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')],
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Client',
'install_tree': self.topdir + '/compose/Client/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': 'docker',
'repo': '/ostree/$arch/Client',
'repo': self.topdir + '/compose/Client/$arch/os',
'variant': compose.variants['Client'],
'target': 'f24',
'disk_size': 3,
@ -63,9 +63,9 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20',
}
},
"conf_file": 'Client-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Client/%(arch)s',
"relative_image_dir": 'image_dir/Client/%(arch)s',
"conf_file": self.topdir + '/work/image-build/Client/docker_Fedora-Docker-Base.cfg',
"image_dir": self.topdir + '/compose/Client/%(arch)s/images',
"relative_image_dir": 'Client/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
}
@ -73,10 +73,10 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')],
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Server',
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': 'docker',
'repo': '/ostree/$arch/Server',
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
@ -87,19 +87,20 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20',
}
},
"conf_file": 'Server-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Server/%(arch)s',
"relative_image_dir": 'image_dir/Server/%(arch)s',
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
"image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
}
self.maxDiff = None
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
[mock.call((compose, client_args)),
mock.call((compose, server_args))])
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_filter_all_variants(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'image_build': {
'^Client|Server$': [
{
@ -130,7 +131,7 @@ class TestImageBuildPhase(unittest.TestCase):
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_set_install_tree(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
@ -167,10 +168,10 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')],
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Everything',
'install_tree': self.topdir + '/compose/Everything/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': 'docker',
'repo': '/ostree/$arch/Server',
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
@ -181,16 +182,16 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20',
}
},
"conf_file": 'Server-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Server/%(arch)s',
"relative_image_dir": 'image_dir/Server/%(arch)s',
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
"image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
})
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_set_extra_repos(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
@ -227,10 +228,11 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')],
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Server',
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': 'docker',
'repo': '/ostree/$arch/Everything,/ostree/$arch/Server',
'repo': ','.join([self.topdir + '/compose/Everything/$arch/os',
self.topdir + '/compose/Server/$arch/os']),
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
@ -241,16 +243,16 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20',
}
},
"conf_file": 'Server-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Server/%(arch)s',
"relative_image_dir": 'image_dir/Server/%(arch)s',
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
"image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
})
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_create_release(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
@ -286,7 +288,7 @@ class TestImageBuildPhase(unittest.TestCase):
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_scratch_build(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
@ -320,13 +322,14 @@ class TestImageBuildPhase(unittest.TestCase):
self.assertTrue(args[0][1].get('scratch'))
class TestCreateImageBuildThread(unittest.TestCase):
class TestCreateImageBuildThread(PungiTestCase):
@mock.patch('pungi.phases.image_build.get_mtime')
@mock.patch('pungi.phases.image_build.get_file_size')
@mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker')
@mock.patch('pungi.phases.image_build.makedirs')
def test_process(self, makedirs, Linker, KojiWrapper):
compose = _DummyCompose({
def test_process(self, Linker, KojiWrapper, get_file_size, get_mtime):
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji'
})
pool = mock.Mock()
@ -349,7 +352,7 @@ class TestCreateImageBuildThread(unittest.TestCase):
}
},
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Client/%(arch)s',
"image_dir": self.topdir + '/compose/Client/%(arch)s/images',
"relative_image_dir": 'image_dir/Client/%(arch)s',
"link_type": 'hardlink-or-copy',
"scratch": False,
@ -374,28 +377,26 @@ class TestCreateImageBuildThread(unittest.TestCase):
}
linker = Linker.return_value
get_file_size.return_value = 1024
get_mtime.return_value = 13579
t = CreateImageBuildThread(pool)
with mock.patch('os.stat') as stat:
with mock.patch('os.path.getsize') as getsize:
with mock.patch('time.sleep'):
getsize.return_value = 1024
stat.return_value.st_mtime = 13579
t.process((compose, cmd), 1)
with mock.patch('time.sleep'):
t.process((compose, cmd), 1)
self.assertItemsEqual(
linker.mock_calls,
[mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.amd64.qcow2',
'/image_dir/Client/amd64/Fedora-Docker-Base-20160103.amd64.qcow2',
self.topdir + '/compose/Client/amd64/images/Fedora-Docker-Base-20160103.amd64.qcow2',
link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.amd64.tar.xz',
'/image_dir/Client/amd64/Fedora-Docker-Base-20160103.amd64.tar.xz',
self.topdir + '/compose/Client/amd64/images/Fedora-Docker-Base-20160103.amd64.tar.xz',
link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.qcow2',
'/image_dir/Client/x86_64/Fedora-Docker-Base-20160103.x86_64.qcow2',
self.topdir + '/compose/Client/x86_64/images/Fedora-Docker-Base-20160103.x86_64.qcow2',
link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.tar.xz',
'/image_dir/Client/x86_64/Fedora-Docker-Base-20160103.x86_64.tar.xz',
self.topdir + '/compose/Client/x86_64/images/Fedora-Docker-Base-20160103.x86_64.tar.xz',
link_type='hardlink-or-copy')])
image_relative_paths = {
@ -434,16 +435,13 @@ class TestCreateImageBuildThread(unittest.TestCase):
self.assertEqual(data['format'], image.format)
self.assertEqual(data['type'], image.type)
self.assertItemsEqual(makedirs.mock_calls,
[mock.call('/image_dir/Client/amd64'),
mock.call('/image_dir/Client/amd64'),
mock.call('/image_dir/Client/x86_64'),
mock.call('/image_dir/Client/x86_64')])
self.assertTrue(os.path.isdir(self.topdir + '/compose/Client/amd64/images'))
self.assertTrue(os.path.isdir(self.topdir + '/compose/Client/x86_64/images'))
@mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker')
def test_process_handle_fail(self, Linker, KojiWrapper):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji',
'failable_deliverables': [
('^.*$', {
@ -494,7 +492,7 @@ class TestCreateImageBuildThread(unittest.TestCase):
@mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker')
def test_process_handle_exception(self, Linker, KojiWrapper):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji',
'failable_deliverables': [
('^.*$', {

View File

@ -13,13 +13,13 @@ import shutil
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from pungi.phases.image_checksum import ImageChecksumPhase, dump_checksums
from tests.helpers import _DummyCompose
from tests.helpers import _DummyCompose, PungiTestCase
class TestImageChecksumPhase(unittest.TestCase):
class TestImageChecksumPhase(PungiTestCase):
def test_config_skip_individual_with_multiple_algorithms(self):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'media_checksums': ['md5', 'sha1'],
'media_checksum_one_file': True
})
@ -32,7 +32,7 @@ class TestImageChecksumPhase(unittest.TestCase):
@mock.patch('kobo.shortcuts.compute_file_checksums')
@mock.patch('pungi.phases.image_checksum.dump_checksums')
def test_checksum_one_file(self, dump, cc, exists):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'media_checksums': ['sha256'],
'media_checksum_one_file': True,
})
@ -44,15 +44,15 @@ class TestImageChecksumPhase(unittest.TestCase):
phase.run()
dump.assert_called_once_with('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'cafebabe'}, 'CHECKSUM')
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['sha256'])
dump.assert_called_once_with(self.topdir + '/compose/Client/i386/iso', 'sha256', {'image.iso': 'cafebabe'}, 'CHECKSUM')
cc.assert_called_once_with(self.topdir + '/compose/Client/i386/iso/image.iso', ['sha256'])
compose.image.add_checksum.assert_called_once_with(None, 'sha256', 'cafebabe')
@mock.patch('os.path.exists')
@mock.patch('kobo.shortcuts.compute_file_checksums')
@mock.patch('pungi.phases.image_checksum.dump_checksums')
def test_checksum_save_individuals(self, dump, cc, exists):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'media_checksums': ['md5', 'sha256'],
})
@ -64,13 +64,17 @@ class TestImageChecksumPhase(unittest.TestCase):
phase.run()
dump.assert_has_calls(
[mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'}, 'image.iso.MD5SUM'),
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'}, 'image.iso.SHA256SUM'),
mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'}, 'MD5SUM'),
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'}, 'SHA256SUM')],
[mock.call(self.topdir + '/compose/Client/i386/iso', 'md5',
{'image.iso': 'cafebabe'}, 'image.iso.MD5SUM'),
mock.call(self.topdir + '/compose/Client/i386/iso', 'sha256',
{'image.iso': 'deadbeef'}, 'image.iso.SHA256SUM'),
mock.call(self.topdir + '/compose/Client/i386/iso', 'md5',
{'image.iso': 'cafebabe'}, 'MD5SUM'),
mock.call(self.topdir + '/compose/Client/i386/iso', 'sha256',
{'image.iso': 'deadbeef'}, 'SHA256SUM')],
any_order=True
)
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['md5', 'sha256'])
cc.assert_called_once_with(self.topdir + '/compose/Client/i386/iso/image.iso', ['md5', 'sha256'])
compose.image.add_checksum.assert_has_calls([mock.call(None, 'sha256', 'deadbeef'),
mock.call(None, 'md5', 'cafebabe')],
any_order=True)
@ -79,7 +83,7 @@ class TestImageChecksumPhase(unittest.TestCase):
@mock.patch('kobo.shortcuts.compute_file_checksums')
@mock.patch('pungi.phases.image_checksum.dump_checksums')
def test_checksum_one_file_custom_name(self, dump, cc, exists):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'media_checksums': ['sha256'],
'media_checksum_one_file': True,
'media_checksum_base_filename': '%(release_short)s-%(variant)s-%(version)s-%(date)s%(type_suffix)s.%(respin)s'
@ -92,17 +96,17 @@ class TestImageChecksumPhase(unittest.TestCase):
phase.run()
dump.assert_called_once_with('/a/b/Client/i386/iso', 'sha256',
dump.assert_called_once_with(self.topdir + '/compose/Client/i386/iso', 'sha256',
{'image.iso': 'cafebabe'},
'test-Client-1.0-20151203.t.0-CHECKSUM')
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['sha256'])
cc.assert_called_once_with(self.topdir + '/compose/Client/i386/iso/image.iso', ['sha256'])
compose.image.add_checksum.assert_called_once_with(None, 'sha256', 'cafebabe')
@mock.patch('os.path.exists')
@mock.patch('kobo.shortcuts.compute_file_checksums')
@mock.patch('pungi.phases.image_checksum.dump_checksums')
def test_checksum_save_individuals_custom_name(self, dump, cc, exists):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'media_checksums': ['md5', 'sha256'],
'media_checksum_base_filename': '%(release_short)s-%(variant)s-%(version)s-%(date)s%(type_suffix)s.%(respin)s'
})
@ -115,15 +119,17 @@ class TestImageChecksumPhase(unittest.TestCase):
phase.run()
dump.assert_has_calls(
[mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'}, 'image.iso.MD5SUM'),
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'}, 'image.iso.SHA256SUM'),
mock.call('/a/b/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'},
[mock.call(self.topdir + '/compose/Client/i386/iso', 'md5',
{'image.iso': 'cafebabe'}, 'image.iso.MD5SUM'),
mock.call(self.topdir + '/compose/Client/i386/iso', 'sha256',
{'image.iso': 'deadbeef'}, 'image.iso.SHA256SUM'),
mock.call(self.topdir + '/compose/Client/i386/iso', 'md5', {'image.iso': 'cafebabe'},
'test-Client-1.0-20151203.t.0-MD5SUM'),
mock.call('/a/b/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'},
mock.call(self.topdir + '/compose/Client/i386/iso', 'sha256', {'image.iso': 'deadbeef'},
'test-Client-1.0-20151203.t.0-SHA256SUM')],
any_order=True
)
cc.assert_called_once_with('/a/b/Client/i386/iso/image.iso', ['md5', 'sha256'])
cc.assert_called_once_with(self.topdir + '/compose/Client/i386/iso/image.iso', ['md5', 'sha256'])
compose.image.add_checksum.assert_has_calls([mock.call(None, 'sha256', 'deadbeef'),
mock.call(None, 'md5', 'cafebabe')],
any_order=True)

View File

@ -11,14 +11,14 @@ import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from pungi.phases.live_images import LiveImagesPhase, CreateLiveImageThread
from tests.helpers import _DummyCompose
from tests.helpers import _DummyCompose, PungiTestCase
class TestLiveImagesPhase(unittest.TestCase):
class TestLiveImagesPhase(PungiTestCase):
@mock.patch('pungi.phases.live_images.ThreadPool')
def test_live_image_build(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_images': [
('^Client$', {
'amd64': {
@ -42,11 +42,11 @@ class TestLiveImagesPhase(unittest.TestCase):
[mock.call((compose,
{'ks_file': 'test.ks',
'build_arch': 'amd64',
'dest_dir': '/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'repos': [self.topdir + '/compose/Client/amd64/os',
'http://example.com/repo/',
'/repo/amd64/Everything'],
self.topdir + '/compose/Everything/amd64/os'],
'label': '',
'name': None,
'filename': 'image-name',
@ -61,7 +61,7 @@ class TestLiveImagesPhase(unittest.TestCase):
@mock.patch('pungi.phases.live_images.ThreadPool')
def test_live_image_build_without_rename(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_images_no_rename': True,
'live_images': [
('^Client$', {
@ -86,11 +86,11 @@ class TestLiveImagesPhase(unittest.TestCase):
[mock.call((compose,
{'ks_file': 'test.ks',
'build_arch': 'amd64',
'dest_dir': '/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'repos': [self.topdir + '/compose/Client/amd64/os',
'http://example.com/repo/',
'/repo/amd64/Everything'],
self.topdir + '/compose/Everything/amd64/os'],
'label': '',
'name': None,
'filename': None,
@ -105,7 +105,7 @@ class TestLiveImagesPhase(unittest.TestCase):
@mock.patch('pungi.phases.live_images.ThreadPool')
def test_live_image_build_two_images(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_images': [
('^Client$', {
'amd64': [{
@ -132,11 +132,11 @@ class TestLiveImagesPhase(unittest.TestCase):
[mock.call((compose,
{'ks_file': 'test.ks',
'build_arch': 'amd64',
'dest_dir': '/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'repos': [self.topdir + '/compose/Client/amd64/os',
'http://example.com/repo/',
'/repo/amd64/Everything'],
self.topdir + '/compose/Everything/amd64/os'],
'label': '',
'name': None,
'filename': 'image-name',
@ -151,11 +151,11 @@ class TestLiveImagesPhase(unittest.TestCase):
mock.call((compose,
{'ks_file': 'another.ks',
'build_arch': 'amd64',
'dest_dir': '/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'repos': [self.topdir + '/compose/Client/amd64/os',
'http://example.com/repo/',
'/repo/amd64/Everything'],
self.topdir + '/compose/Everything/amd64/os'],
'label': '',
'name': None,
'filename': 'image-name',
@ -171,7 +171,7 @@ class TestLiveImagesPhase(unittest.TestCase):
@mock.patch('pungi.phases.live_images.ThreadPool')
@mock.patch('pungi.phases.live_images.resolve_git_url')
def test_spin_appliance(self, resolve_git_url, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_images': [
('^Client$', {
'amd64': {
@ -198,11 +198,11 @@ class TestLiveImagesPhase(unittest.TestCase):
[mock.call((compose,
{'ks_file': 'test.ks',
'build_arch': 'amd64',
'dest_dir': '/image_dir/Client/amd64',
'dest_dir': self.topdir + '/compose/Client/amd64/images',
'scratch': False,
'repos': ['/repo/amd64/Client',
'repos': [self.topdir + '/compose/Client/amd64/os',
'http://example.com/repo/',
'/repo/amd64/Everything'],
self.topdir + '/compose/Everything/amd64/os'],
'label': '',
'name': None,
'filename': 'image-name',
@ -218,19 +218,19 @@ class TestLiveImagesPhase(unittest.TestCase):
[mock.call('https://git.example.com/kickstarts.git?#HEAD')])
class TestCreateLiveImageThread(unittest.TestCase):
class TestCreateLiveImageThread(PungiTestCase):
@mock.patch('pungi.phases.live_images.Image')
@mock.patch('shutil.copy2')
@mock.patch('pungi.phases.live_images.run')
@mock.patch('pungi.phases.live_images.KojiWrapper')
def test_process(self, KojiWrapper, run, copy2, Image):
compose = _DummyCompose({'koji_profile': 'koji'})
compose = _DummyCompose(self.topdir, {'koji_profile': 'koji'})
pool = mock.Mock()
cmd = {
'ks_file': '/path/to/ks_file',
'build_arch': 'amd64',
'dest_dir': '/top/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'http://example.com/repo/',
@ -255,21 +255,22 @@ class TestCreateLiveImageThread(unittest.TestCase):
koji_wrapper.get_image_path.return_value = ['/path/to/image.iso']
t = CreateLiveImageThread(pool)
with mock.patch('os.stat') as stat:
with mock.patch('os.path.getsize') as getsize:
with mock.patch('pungi.phases.live_images.get_file_size') as get_file_size:
get_file_size.return_value = 1024
with mock.patch('pungi.phases.live_images.get_mtime') as get_mtime:
get_mtime.return_value = 13579
with mock.patch('time.sleep'):
getsize.return_value = 1024
stat.return_value.st_mtime = 13579
t.process((compose, cmd, compose.variants['Client'], 'amd64'), 1)
self.assertEqual(koji_wrapper.run_blocking_cmd.mock_calls,
[mock.call('koji spin-livecd ...', log_file='/a/b/log/log_file')])
[mock.call('koji spin-livecd ...',
log_file=self.topdir + '/logs/amd64/createiso-None-None-None.amd64.log')])
self.assertEqual(koji_wrapper.get_image_path.mock_calls, [mock.call(123)])
self.assertEqual(copy2.mock_calls,
[mock.call('/path/to/image.iso', '/top/iso_dir/amd64/Client/image-name')])
[mock.call('/path/to/image.iso', self.topdir + '/compose/Client/amd64/iso/image-name')])
write_manifest_cmd = ' && '.join([
'cd /top/iso_dir/amd64/Client',
'cd ' + self.topdir + '/compose/Client/amd64/iso',
'isoinfo -R -f -i image-name | grep -v \'/TRANS.TBL$\' | sort >> image-name.manifest'
])
self.assertEqual(run.mock_calls, [mock.call(write_manifest_cmd)])
@ -287,7 +288,7 @@ class TestCreateLiveImageThread(unittest.TestCase):
ksurl='https://git.example.com/kickstarts.git?#CAFEBABE')])
self.assertEqual(Image.return_value.type, 'live')
self.assertEqual(Image.return_value.format, 'iso')
self.assertEqual(Image.return_value.path, '../../top/iso_dir/amd64/Client/image-name')
self.assertEqual(Image.return_value.path, 'Client/amd64/iso/image-name')
self.assertEqual(Image.return_value.size, 1024)
self.assertEqual(Image.return_value.mtime, 13579)
self.assertEqual(Image.return_value.arch, 'amd64')
@ -302,12 +303,12 @@ class TestCreateLiveImageThread(unittest.TestCase):
@mock.patch('pungi.phases.live_images.run')
@mock.patch('pungi.phases.live_images.KojiWrapper')
def test_process_no_rename(self, KojiWrapper, run, copy2, Image):
compose = _DummyCompose({'koji_profile': 'koji'})
compose = _DummyCompose(self.topdir, {'koji_profile': 'koji'})
pool = mock.Mock()
cmd = {
'ks_file': '/path/to/ks_file',
'build_arch': 'amd64',
'dest_dir': '/top/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'http://example.com/repo/',
@ -332,25 +333,22 @@ class TestCreateLiveImageThread(unittest.TestCase):
koji_wrapper.get_image_path.return_value = ['/path/to/image.iso']
t = CreateLiveImageThread(pool)
with mock.patch('os.stat') as stat:
with mock.patch('os.path.getsize') as getsize:
getsize.return_value = 1024
getsize.return_value = 1024
getsize.return_value = 1024
getsize.return_value = 1024
with mock.patch('pungi.phases.live_images.get_file_size') as get_file_size:
get_file_size.return_value = 1024
with mock.patch('pungi.phases.live_images.get_mtime') as get_mtime:
get_mtime.return_value = 13579
with mock.patch('time.sleep'):
getsize.return_value = 1024
stat.return_value.st_mtime = 13579
t.process((compose, cmd, compose.variants['Client'], 'amd64'), 1)
self.assertEqual(koji_wrapper.run_blocking_cmd.mock_calls,
[mock.call('koji spin-livecd ...', log_file='/a/b/log/log_file')])
[mock.call('koji spin-livecd ...',
log_file=self.topdir + '/logs/amd64/createiso-None-None-None.amd64.log')])
self.assertEqual(koji_wrapper.get_image_path.mock_calls, [mock.call(123)])
self.assertEqual(copy2.mock_calls,
[mock.call('/path/to/image.iso', '/top/iso_dir/amd64/Client/image.iso')])
[mock.call('/path/to/image.iso', self.topdir + '/compose/Client/amd64/iso/image.iso')])
write_manifest_cmd = ' && '.join([
'cd /top/iso_dir/amd64/Client',
'cd ' + self.topdir + '/compose/Client/amd64/iso',
'isoinfo -R -f -i image.iso | grep -v \'/TRANS.TBL$\' | sort >> image.iso.manifest'
])
self.assertEqual(run.mock_calls, [mock.call(write_manifest_cmd)])
@ -369,7 +367,7 @@ class TestCreateLiveImageThread(unittest.TestCase):
self.assertEqual(Image.return_value.type, 'live')
self.assertEqual(Image.return_value.format, 'iso')
self.assertEqual(Image.return_value.path, '../../top/iso_dir/amd64/Client/image.iso')
self.assertEqual(Image.return_value.path, 'Client/amd64/iso/image.iso')
self.assertEqual(Image.return_value.size, 1024)
self.assertEqual(Image.return_value.mtime, 13579)
self.assertEqual(Image.return_value.arch, 'amd64')
@ -384,12 +382,12 @@ class TestCreateLiveImageThread(unittest.TestCase):
@mock.patch('pungi.phases.live_images.run')
@mock.patch('pungi.phases.live_images.KojiWrapper')
def test_process_applicance(self, KojiWrapper, run, copy2, Image):
compose = _DummyCompose({'koji_profile': 'koji'})
compose = _DummyCompose(self.topdir, {'koji_profile': 'koji'})
pool = mock.Mock()
cmd = {
'ks_file': '/path/to/ks_file',
'build_arch': 'amd64',
'dest_dir': '/top/iso_dir/amd64/Client',
'dest_dir': self.topdir + '/compose/Client/amd64/iso',
'scratch': False,
'repos': ['/repo/amd64/Client',
'http://example.com/repo/',
@ -414,21 +412,22 @@ class TestCreateLiveImageThread(unittest.TestCase):
koji_wrapper.get_image_path.return_value = ['/path/to/image.raw.xz']
t = CreateLiveImageThread(pool)
with mock.patch('os.stat') as stat:
with mock.patch('os.path.getsize') as getsize:
with mock.patch('pungi.phases.live_images.get_file_size') as get_file_size:
get_file_size.return_value = 1024
with mock.patch('pungi.phases.live_images.get_mtime') as get_mtime:
get_mtime.return_value = 13579
with mock.patch('time.sleep'):
getsize.return_value = 1024
stat.return_value.st_mtime = 13579
t.process((compose, cmd, compose.variants['Client'], 'amd64'), 1)
self.assertEqual(koji_wrapper.run_blocking_cmd.mock_calls,
[mock.call('koji spin-livecd ...', log_file='/a/b/log/log_file')])
[mock.call('koji spin-livecd ...',
log_file=self.topdir + '/logs/amd64/createiso-None-None-None.amd64.log')])
self.assertEqual(koji_wrapper.get_image_path.mock_calls, [mock.call(123)])
self.assertEqual(copy2.mock_calls,
[mock.call('/path/to/image.raw.xz', '/top/iso_dir/amd64/Client/image-name')])
[mock.call('/path/to/image.raw.xz', self.topdir + '/compose/Client/amd64/iso/image-name')])
write_manifest_cmd = ' && '.join([
'cd /top/iso_dir/amd64/Client',
'cd ' + self.topdir + '/compose/Client/amd64/iso',
'isoinfo -R -f -i image-name | grep -v \'/TRANS.TBL$\' | sort >> image-name.manifest'
])
self.assertEqual(run.mock_calls, [mock.call(write_manifest_cmd)])
@ -447,7 +446,7 @@ class TestCreateLiveImageThread(unittest.TestCase):
self.assertEqual(Image.return_value.type, 'appliance')
self.assertEqual(Image.return_value.format, 'raw.xz')
self.assertEqual(Image.return_value.path, '../../top/iso_dir/amd64/Client/image-name')
self.assertEqual(Image.return_value.path, 'Client/amd64/iso/image-name')
self.assertEqual(Image.return_value.size, 1024)
self.assertEqual(Image.return_value.mtime, 13579)
self.assertEqual(Image.return_value.arch, 'amd64')
@ -461,7 +460,7 @@ class TestCreateLiveImageThread(unittest.TestCase):
@mock.patch('pungi.phases.live_images.run')
@mock.patch('pungi.phases.live_images.KojiWrapper')
def test_process_handles_fail(self, KojiWrapper, run, copy2):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji',
'failable_deliverables': [('^.+$', {'*': ['live']})],
})
@ -498,7 +497,7 @@ class TestCreateLiveImageThread(unittest.TestCase):
@mock.patch('pungi.phases.live_images.run')
@mock.patch('pungi.phases.live_images.KojiWrapper')
def test_process_handles_exception(self, KojiWrapper, run, copy2):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji',
'failable_deliverables': [('^.+$', {'*': ['live']})],
})

View File

@ -10,13 +10,13 @@ import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from pungi.phases.livemedia_phase import LiveMediaPhase, LiveMediaThread
from tests.helpers import _DummyCompose
from tests.helpers import _DummyCompose, PungiTestCase
class TestLiveMediaPhase(unittest.TestCase):
class TestLiveMediaPhase(PungiTestCase):
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
def test_live_media_minimal(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_media': {
'^Server$': [
{
@ -45,18 +45,18 @@ class TestLiveMediaPhase(unittest.TestCase):
'ksversion': None,
'name': 'Fedora Server Live',
'release': None,
'repo': ['/repo/$basearch/Server'],
'repo': [self.topdir + '/compose/Server/$basearch/os'],
'scratch': False,
'skip_tag': None,
'target': 'f24',
'title': None,
'install_tree': '/ostree/$basearch/Server',
'install_tree': self.topdir + '/compose/Server/$basearch/os',
'version': 'Rawhide',
}))])
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
def test_live_media_non_existing_install_tree(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_media': {
'^Server$': [
{
@ -79,7 +79,7 @@ class TestLiveMediaPhase(unittest.TestCase):
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
def test_live_media_non_existing_repo(self, ThreadPool):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_media': {
'^Server$': [
{
@ -103,7 +103,7 @@ class TestLiveMediaPhase(unittest.TestCase):
@mock.patch('pungi.phases.livemedia_phase.resolve_git_url')
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
def test_live_media_full(self, ThreadPool, resolve_git_url):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'live_media': {
'^Server$': [
{
@ -143,24 +143,25 @@ class TestLiveMediaPhase(unittest.TestCase):
'name': 'Fedora Server Live',
'release': '20151203.0',
'repo': ['http://example.com/extra_repo',
'/repo/$basearch/Everything',
'/repo/$basearch/Server'],
self.topdir + '/compose/Everything/$basearch/os',
self.topdir + '/compose/Server/$basearch/os'],
'scratch': True,
'skip_tag': True,
'target': 'f24',
'title': 'Custom Title',
'install_tree': '/ostree/$basearch/Everything',
'install_tree': self.topdir + '/compose/Everything/$basearch/os',
'version': 'Rawhide',
}))])
class TestCreateImageBuildThread(unittest.TestCase):
class TestCreateImageBuildThread(PungiTestCase):
@mock.patch('pungi.phases.livemedia_phase.get_mtime')
@mock.patch('pungi.phases.livemedia_phase.get_file_size')
@mock.patch('pungi.phases.livemedia_phase.KojiWrapper')
@mock.patch('pungi.phases.livemedia_phase.Linker')
@mock.patch('pungi.phases.livemedia_phase.makedirs')
def test_process(self, makedirs, Linker, KojiWrapper):
compose = _DummyCompose({
def test_process(self, Linker, KojiWrapper, get_file_size, get_mtime):
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji'
})
config = {
@ -204,15 +205,15 @@ class TestCreateImageBuildThread(unittest.TestCase):
}
t = LiveMediaThread(pool)
with mock.patch('os.stat') as stat:
with mock.patch('os.path.getsize') as getsize:
with mock.patch('time.sleep'):
getsize.return_value = 1024
stat.return_value.st_mtime = 13579
t.process((compose, compose.variants['Server'], config), 1)
get_file_size.return_value = 1024
get_mtime.return_value = 13579
with mock.patch('time.sleep'):
t.process((compose, compose.variants['Server'], config), 1)
self.assertEqual(run_blocking_cmd.mock_calls,
[mock.call('koji-spin-livemedia', log_file='/a/b/log/log_file')])
self.assertEqual(
run_blocking_cmd.mock_calls,
[mock.call('koji-spin-livemedia',
log_file=self.topdir + '/logs/amd64-x86_64/livemedia-Server.amd64-x86_64.log')])
self.assertEqual(get_live_media_cmd.mock_calls,
[mock.call({'arch': 'amd64,x86_64',
'ksfile': 'file.ks',
@ -228,21 +229,20 @@ class TestCreateImageBuildThread(unittest.TestCase):
'version': 'Rawhide'})])
self.assertEqual(get_image_paths.mock_calls,
[mock.call(1234)])
self.assertItemsEqual(makedirs.mock_calls,
[mock.call('/iso_dir/x86_64/Server'),
mock.call('/iso_dir/amd64/Server')])
self.assertTrue(os.path.isdir(self.topdir + '/compose/Server/x86_64/iso'))
self.assertTrue(os.path.isdir(self.topdir + '/compose/Server/amd64/iso'))
link = Linker.return_value.link
self.assertItemsEqual(link.mock_calls,
[mock.call('/koji/task/1235/Live-20160103.amd64.iso',
'/iso_dir/amd64/Server/Live-20160103.amd64.iso',
self.topdir + '/compose/Server/amd64/iso/Live-20160103.amd64.iso',
link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Live-20160103.x86_64.iso',
'/iso_dir/x86_64/Server/Live-20160103.x86_64.iso',
self.topdir + '/compose/Server/x86_64/iso/Live-20160103.x86_64.iso',
link_type='hardlink-or-copy')])
image_relative_paths = [
'iso_dir/amd64/Server/Live-20160103.amd64.iso',
'iso_dir/x86_64/Server/Live-20160103.x86_64.iso'
'Server/amd64/iso/Live-20160103.amd64.iso',
'Server/x86_64/iso/Live-20160103.x86_64.iso'
]
self.assertEqual(len(compose.im.add.call_args_list), 2)
@ -258,7 +258,7 @@ class TestCreateImageBuildThread(unittest.TestCase):
@mock.patch('pungi.phases.livemedia_phase.KojiWrapper')
def test_handle_koji_fail(self, KojiWrapper):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji',
'failable_deliverables': [
('^.+$', {'*': ['live-media']})
@ -297,7 +297,7 @@ class TestCreateImageBuildThread(unittest.TestCase):
@mock.patch('pungi.phases.livemedia_phase.KojiWrapper')
def test_handle_exception(self, KojiWrapper):
compose = _DummyCompose({
compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji',
'failable_deliverables': [
('^.+$', {'*': ['live-media']})