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

View File

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

View File

@ -4,7 +4,7 @@ import os
import time import time
from kobo import shortcuts 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.phases.base import PhaseBase
from pungi.linker import Linker from pungi.linker import Linker
from pungi.paths import translate_path from pungi.paths import translate_path
@ -122,7 +122,7 @@ class LiveMediaThread(WorkerThread):
def _get_log_file(self, compose, variant, config): def _get_log_file(self, compose, variant, config):
arches = '-'.join(config['arches']) 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): def _run_command(self, koji_wrapper, cmd, compose, log_file):
time.sleep(self.num * 3) time.sleep(self.num * 3)
@ -186,8 +186,8 @@ class LiveMediaThread(WorkerThread):
img.type = 'live' img.type = 'live'
img.format = 'iso' img.format = 'iso'
img.path = os.path.join(relative_image_dir, os.path.basename(image_dest)) img.path = os.path.join(relative_image_dir, os.path.basename(image_dest))
img.mtime = int(os.stat(image_dest).st_mtime) img.mtime = get_mtime(image_dest)
img.size = os.path.getsize(image_dest) img.size = get_file_size(image_dest)
img.arch = image_info['arch'] img.arch = image_info['arch']
img.disc_number = 1 # We don't expect multiple disks img.disc_number = 1 # We don't expect multiple disks
img.disc_count = 1 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: if volid and escape_spaces:
volid = volid.replace(" ", r"\x20") volid = volid.replace(" ", r"\x20")
return volid 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 -*- # -*- coding: utf-8 -*-
import mock import mock
import os import unittest
import tempfile
import shutil
from pungi.util import get_arch_variant_data 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): class _DummyCompose(object):
def __init__(self, config): def __init__(self, topdir, config):
self.compose_date = '20151203' self.compose_date = '20151203'
self.compose_type_suffix = '.t' self.compose_type_suffix = '.t'
self.compose_respin = 0 self.compose_respin = 0
@ -19,47 +30,17 @@ class _DummyCompose(object):
version='1.0', version='1.0',
), ),
) )
self.topdir = topdir
self.conf = config self.conf = config
self.paths = mock.Mock( self.paths = paths.Paths(self)
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._logger = mock.Mock() self._logger = mock.Mock()
self.variants = { self.variants = {
'Server': mock.Mock(uid='Server', arches=['x86_64', 'amd64'], is_empty=False), 'Server': mock.Mock(uid='Server', arches=['x86_64', 'amd64'],
'Client': mock.Mock(uid='Client', arches=['amd64'], is_empty=False), type='variant', is_empty=False),
'Everything': mock.Mock(uid='Everything', arches=['x86_64', 'amd64'], 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.log_error = mock.Mock()
self.get_image_name = mock.Mock(return_value='image-name') 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__), "..")) sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from pungi.phases.image_build import ImageBuildPhase, CreateImageBuildThread 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') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build(self, ThreadPool): def test_image_build(self, ThreadPool):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'image_build': { 'image_build': {
'^Client|Server$': [ '^Client|Server$': [
{ {
@ -49,10 +49,10 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')], "format": [('docker', 'tar.xz')],
"image_conf": { "image_conf": {
'image-build': { 'image-build': {
'install_tree': '/ostree/$arch/Client', 'install_tree': self.topdir + '/compose/Client/$arch/os',
'kickstart': 'fedora-docker-base.ks', 'kickstart': 'fedora-docker-base.ks',
'format': 'docker', 'format': 'docker',
'repo': '/ostree/$arch/Client', 'repo': self.topdir + '/compose/Client/$arch/os',
'variant': compose.variants['Client'], 'variant': compose.variants['Client'],
'target': 'f24', 'target': 'f24',
'disk_size': 3, 'disk_size': 3,
@ -63,9 +63,9 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20', 'distro': 'Fedora-20',
} }
}, },
"conf_file": 'Client-Fedora-Docker-Base-docker', "conf_file": self.topdir + '/work/image-build/Client/docker_Fedora-Docker-Base.cfg',
"image_dir": '/image_dir/Client/%(arch)s', "image_dir": self.topdir + '/compose/Client/%(arch)s/images',
"relative_image_dir": 'image_dir/Client/%(arch)s', "relative_image_dir": 'Client/%(arch)s/images',
"link_type": 'hardlink-or-copy', "link_type": 'hardlink-or-copy',
"scratch": False, "scratch": False,
} }
@ -73,10 +73,10 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')], "format": [('docker', 'tar.xz')],
"image_conf": { "image_conf": {
'image-build': { 'image-build': {
'install_tree': '/ostree/$arch/Server', 'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks', 'kickstart': 'fedora-docker-base.ks',
'format': 'docker', 'format': 'docker',
'repo': '/ostree/$arch/Server', 'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'], 'variant': compose.variants['Server'],
'target': 'f24', 'target': 'f24',
'disk_size': 3, 'disk_size': 3,
@ -87,19 +87,20 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20', 'distro': 'Fedora-20',
} }
}, },
"conf_file": 'Server-Fedora-Docker-Base-docker', "conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
"image_dir": '/image_dir/Server/%(arch)s', "image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'image_dir/Server/%(arch)s', "relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy', "link_type": 'hardlink-or-copy',
"scratch": False, "scratch": False,
} }
self.maxDiff = None
self.assertItemsEqual(phase.pool.queue_put.mock_calls, self.assertItemsEqual(phase.pool.queue_put.mock_calls,
[mock.call((compose, client_args)), [mock.call((compose, client_args)),
mock.call((compose, server_args))]) mock.call((compose, server_args))])
@mock.patch('pungi.phases.image_build.ThreadPool') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_filter_all_variants(self, ThreadPool): def test_image_build_filter_all_variants(self, ThreadPool):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'image_build': { 'image_build': {
'^Client|Server$': [ '^Client|Server$': [
{ {
@ -130,7 +131,7 @@ class TestImageBuildPhase(unittest.TestCase):
@mock.patch('pungi.phases.image_build.ThreadPool') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_set_install_tree(self, ThreadPool): def test_image_build_set_install_tree(self, ThreadPool):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'image_build': { 'image_build': {
'^Server$': [ '^Server$': [
{ {
@ -167,10 +168,10 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')], "format": [('docker', 'tar.xz')],
"image_conf": { "image_conf": {
'image-build': { 'image-build': {
'install_tree': '/ostree/$arch/Everything', 'install_tree': self.topdir + '/compose/Everything/$arch/os',
'kickstart': 'fedora-docker-base.ks', 'kickstart': 'fedora-docker-base.ks',
'format': 'docker', 'format': 'docker',
'repo': '/ostree/$arch/Server', 'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'], 'variant': compose.variants['Server'],
'target': 'f24', 'target': 'f24',
'disk_size': 3, 'disk_size': 3,
@ -181,16 +182,16 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20', 'distro': 'Fedora-20',
} }
}, },
"conf_file": 'Server-Fedora-Docker-Base-docker', "conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
"image_dir": '/image_dir/Server/%(arch)s', "image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'image_dir/Server/%(arch)s', "relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy', "link_type": 'hardlink-or-copy',
"scratch": False, "scratch": False,
}) })
@mock.patch('pungi.phases.image_build.ThreadPool') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_set_extra_repos(self, ThreadPool): def test_image_build_set_extra_repos(self, ThreadPool):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'image_build': { 'image_build': {
'^Server$': [ '^Server$': [
{ {
@ -227,10 +228,11 @@ class TestImageBuildPhase(unittest.TestCase):
"format": [('docker', 'tar.xz')], "format": [('docker', 'tar.xz')],
"image_conf": { "image_conf": {
'image-build': { 'image-build': {
'install_tree': '/ostree/$arch/Server', 'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks', 'kickstart': 'fedora-docker-base.ks',
'format': 'docker', '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'], 'variant': compose.variants['Server'],
'target': 'f24', 'target': 'f24',
'disk_size': 3, 'disk_size': 3,
@ -241,16 +243,16 @@ class TestImageBuildPhase(unittest.TestCase):
'distro': 'Fedora-20', 'distro': 'Fedora-20',
} }
}, },
"conf_file": 'Server-Fedora-Docker-Base-docker', "conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
"image_dir": '/image_dir/Server/%(arch)s', "image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'image_dir/Server/%(arch)s', "relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy', "link_type": 'hardlink-or-copy',
"scratch": False, "scratch": False,
}) })
@mock.patch('pungi.phases.image_build.ThreadPool') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_create_release(self, ThreadPool): def test_image_build_create_release(self, ThreadPool):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'image_build': { 'image_build': {
'^Server$': [ '^Server$': [
{ {
@ -286,7 +288,7 @@ class TestImageBuildPhase(unittest.TestCase):
@mock.patch('pungi.phases.image_build.ThreadPool') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_scratch_build(self, ThreadPool): def test_image_build_scratch_build(self, ThreadPool):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'image_build': { 'image_build': {
'^Server$': [ '^Server$': [
{ {
@ -320,13 +322,14 @@ class TestImageBuildPhase(unittest.TestCase):
self.assertTrue(args[0][1].get('scratch')) 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.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker') @mock.patch('pungi.phases.image_build.Linker')
@mock.patch('pungi.phases.image_build.makedirs') def test_process(self, Linker, KojiWrapper, get_file_size, get_mtime):
def test_process(self, makedirs, Linker, KojiWrapper): compose = _DummyCompose(self.topdir, {
compose = _DummyCompose({
'koji_profile': 'koji' 'koji_profile': 'koji'
}) })
pool = mock.Mock() pool = mock.Mock()
@ -349,7 +352,7 @@ class TestCreateImageBuildThread(unittest.TestCase):
} }
}, },
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker', "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', "relative_image_dir": 'image_dir/Client/%(arch)s',
"link_type": 'hardlink-or-copy', "link_type": 'hardlink-or-copy',
"scratch": False, "scratch": False,
@ -374,28 +377,26 @@ class TestCreateImageBuildThread(unittest.TestCase):
} }
linker = Linker.return_value linker = Linker.return_value
get_file_size.return_value = 1024
get_mtime.return_value = 13579
t = CreateImageBuildThread(pool) t = CreateImageBuildThread(pool)
with mock.patch('os.stat') as stat: with mock.patch('time.sleep'):
with mock.patch('os.path.getsize') as getsize: t.process((compose, cmd), 1)
with mock.patch('time.sleep'):
getsize.return_value = 1024
stat.return_value.st_mtime = 13579
t.process((compose, cmd), 1)
self.assertItemsEqual( self.assertItemsEqual(
linker.mock_calls, linker.mock_calls,
[mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.amd64.qcow2', [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'), link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.amd64.tar.xz', 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'), link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.qcow2', 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'), link_type='hardlink-or-copy'),
mock.call('/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.tar.xz', 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')]) link_type='hardlink-or-copy')])
image_relative_paths = { image_relative_paths = {
@ -434,16 +435,13 @@ class TestCreateImageBuildThread(unittest.TestCase):
self.assertEqual(data['format'], image.format) self.assertEqual(data['format'], image.format)
self.assertEqual(data['type'], image.type) self.assertEqual(data['type'], image.type)
self.assertItemsEqual(makedirs.mock_calls, self.assertTrue(os.path.isdir(self.topdir + '/compose/Client/amd64/images'))
[mock.call('/image_dir/Client/amd64'), self.assertTrue(os.path.isdir(self.topdir + '/compose/Client/x86_64/images'))
mock.call('/image_dir/Client/amd64'),
mock.call('/image_dir/Client/x86_64'),
mock.call('/image_dir/Client/x86_64')])
@mock.patch('pungi.phases.image_build.KojiWrapper') @mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker') @mock.patch('pungi.phases.image_build.Linker')
def test_process_handle_fail(self, Linker, KojiWrapper): def test_process_handle_fail(self, Linker, KojiWrapper):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji', 'koji_profile': 'koji',
'failable_deliverables': [ 'failable_deliverables': [
('^.*$', { ('^.*$', {
@ -494,7 +492,7 @@ class TestCreateImageBuildThread(unittest.TestCase):
@mock.patch('pungi.phases.image_build.KojiWrapper') @mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker') @mock.patch('pungi.phases.image_build.Linker')
def test_process_handle_exception(self, Linker, KojiWrapper): def test_process_handle_exception(self, Linker, KojiWrapper):
compose = _DummyCompose({ compose = _DummyCompose(self.topdir, {
'koji_profile': 'koji', 'koji_profile': 'koji',
'failable_deliverables': [ 'failable_deliverables': [
('^.*$', { ('^.*$', {

View File

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

View File

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

View File

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