pungi/tests/test_imagebuildphase.py

997 lines
40 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
import mock
import six
import os
import sys
from pungi.phases.image_build import ImageBuildPhase, CreateImageBuildThread
from tests.helpers import DummyCompose, PungiTestCase, boom
class TestImageBuildPhase(PungiTestCase):
def setUp(self):
super(TestImageBuildPhase, self).setUp()
self.maxDiff = None
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Client|Server$': [
{
'image-build': {
'format': [('docker', 'tar.xz')],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'failable': ['x86_64'],
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
client_args = {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Client/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Client/$arch/os',
'variant': compose.variants['Client'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'can_fail': ['x86_64'],
}
},
"conf_file": self.topdir + '/work/image-build/Client/docker_Fedora-Docker-Base_amd64.cfg',
"image_dir": self.topdir + '/compose/Client/%(arch)s/images',
"relative_image_dir": 'Client/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
}
server_args = {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'can_fail': ['x86_64'],
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_amd64-x86_64.cfg',
"image_dir": self.topdir + '/compose/Server/%(arch)s/images',
"relative_image_dir": 'Server/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
}
six.assertCountEqual(
self,
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_phase_global_options(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build_ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'image_build_release': '!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN',
'image_build_target': 'f24',
'image_build_version': 'Rawhide',
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
server_args = {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'release': '20151203.t.0',
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_amd64-x86_64.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.assertEqual(
phase.pool.queue_put.mock_calls, [mock.call((compose, server_args))]
)
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_phase_missing_version(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build_ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'image_build_release': '!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN',
'image_build_target': 'f24',
'image_build': {
'^Server$': [
{
'image-build': {
'format': 'docker',
'name': 'Fedora-Docker-Base',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3
}
}
]
},
'koji_profile': 'koji',
})
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
server_args = {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': '25',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'release': '20151203.t.0',
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_amd64-x86_64.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.assertEqual(
phase.pool.queue_put.mock_calls, [mock.call((compose, server_args))]
)
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_filter_all_variants(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Client|Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['non-existing'],
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertFalse(phase.pool.add.called)
self.assertFalse(phase.pool.queue_put.called)
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_set_install_tree(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['x86_64'],
'install_tree_from': 'Server-optional',
}
}
]
},
'koji_profile': 'koji',
})
compose.setup_optional()
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][0], compose)
self.assertDictEqual(args[0][1], {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server-optional/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_x86_64.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_install_tree_from_path(self, ThreadPool):
compose = DummyCompose(self.topdir, {
"image_build": {
"^Server$": [
{
"image-build": {
"format": ["docker"],
"name": "Fedora-Docker-Base",
"target": "f24",
"version": "Rawhide",
"ksurl": "git://git.fedorahosted.org/git/spin-kickstarts.git",
"kickstart": "fedora-docker-base.ks",
"distro": "Fedora-20",
"disk_size": 3,
"arches": ["x86_64"],
"install_tree_from": "/my/tree",
}
}
]
},
"koji_profile": "koji",
"translate_paths": [("/my", "http://example.com")],
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][0], compose)
self.assertDictEqual(args[0][1], {
"image_conf": {
"image-build": {
"install_tree": "http://example.com/tree",
"kickstart": "fedora-docker-base.ks",
"format": ["docker"],
"repo": self.topdir + "/compose/Server/$arch/os",
"variant": compose.variants["Server"],
"target": "f24",
"disk_size": 3,
"name": "Fedora-Docker-Base",
"arches": ["x86_64"],
"version": "Rawhide",
"ksurl": "git://git.fedorahosted.org/git/spin-kickstarts.git",
"distro": "Fedora-20",
}
},
"conf_file": self.topdir + "/work/image-build/Server/docker_Fedora-Docker-Base_x86_64.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(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['x86_64'],
'repo_from': ['Everything', 'Server-optional'],
}
}
]
},
'koji_profile': 'koji',
})
compose.setup_optional()
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][0], compose)
self.assertDictEqual(args[0][1], {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': ','.join([self.topdir + '/compose/Everything/$arch/os',
self.topdir + '/compose/Server-optional/$arch/os',
self.topdir + '/compose/Server/$arch/os']),
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_x86_64.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_external_install_tree(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['x86_64'],
'install_tree_from': 'http://example.com/install-tree/',
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][0], compose)
self.assertDictEqual(args[0][1], {
"image_conf": {
'image-build': {
'install_tree': 'http://example.com/install-tree/',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': ','.join([self.topdir + '/compose/Server/$arch/os']),
'variant': compose.variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_x86_64.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(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['x86_64'],
'release': None,
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][1].get('image_conf', {}).get('image-build', {}).get('release'),
'20151203.t.0')
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_create_release_with_explicit_config(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['x86_64'],
'release': '!RELEASE_FROM_LABEL_DATE_TYPE_RESPIN',
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][1].get('image_conf', {}).get('image-build', {}).get('release'),
'20151203.t.0')
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_scratch_build(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'arches': ['x86_64'],
'scratch': True,
}
}
]
},
'koji_profile': 'koji',
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertTrue(args[0][1].get('scratch'))
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_optional(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Server-optional$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'failable': ['x86_64'],
}
}
]
},
'koji_profile': 'koji',
})
compose.setup_optional()
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
server_args = {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Server-optional/$arch/os',
'variant': compose.all_variants['Server-optional'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'can_fail': ['x86_64'],
}
},
"conf_file": self.topdir + '/work/image-build/Server-optional/docker_Fedora-Docker-Base_x86_64.cfg',
"image_dir": self.topdir + '/compose/Server-optional/%(arch)s/images',
"relative_image_dir": 'Server-optional/%(arch)s/images',
"link_type": 'hardlink-or-copy',
"scratch": False,
}
self.assertEqual(
phase.pool.queue_put.mock_calls, [mock.call((compose, server_args))]
)
@mock.patch('pungi.phases.image_build.ThreadPool')
def test_failable_star(self, ThreadPool):
compose = DummyCompose(self.topdir, {
'image_build': {
'^Server$': [
{
'image-build': {
'format': ['docker'],
'name': 'Fedora-Docker-Base',
'target': 'f24',
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'kickstart': "fedora-docker-base.ks",
'distro': 'Fedora-20',
'disk_size': 3,
'failable': ['*'],
}
}
]
},
'koji_profile': 'koji',
})
compose.setup_optional()
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
server_args = {
"image_conf": {
'image-build': {
'install_tree': self.topdir + '/compose/Server/$arch/os',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker'],
'repo': self.topdir + '/compose/Server/$arch/os',
'variant': compose.all_variants['Server'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'can_fail': ['amd64', 'x86_64'],
}
},
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base_amd64-x86_64.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.assertEqual(
phase.pool.queue_put.mock_calls, [mock.call((compose, server_args))]
)
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')
def test_process(self, Linker, KojiWrapper, get_file_size, get_mtime):
compose = DummyCompose(self.topdir, {
'koji_profile': 'koji'
})
pool = mock.Mock()
cmd = {
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Client',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker', 'qcow2'],
'repo': '/ostree/$arch/Client',
'variant': compose.variants['Client'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'subvariant': 'KDE',
}
},
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
"image_dir": self.topdir + '/compose/Client/%(arch)s/images',
"relative_image_dir": 'image_dir/Client/%(arch)s',
"link_type": 'hardlink-or-copy',
"scratch": False,
}
koji_wrapper = KojiWrapper.return_value
koji_wrapper.run_blocking_cmd.return_value = {
"retcode": 0,
"output": None,
"task_id": 1234,
}
koji_wrapper.get_image_paths.return_value = {
'amd64': [
'/koji/task/1235/tdl-amd64.xml',
'/koji/task/1235/Fedora-Docker-Base-20160103.amd64.qcow2',
'/koji/task/1235/Fedora-Docker-Base-20160103.amd64.tar.gz'
],
'x86_64': [
'/koji/task/1235/tdl-x86_64.xml',
'/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.qcow2',
'/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.tar.gz'
]
}
linker = Linker.return_value
get_file_size.return_value = 1024
get_mtime.return_value = 13579
t = CreateImageBuildThread(pool)
with mock.patch('time.sleep'):
t.process((compose, cmd), 1)
self.assertEqual(
koji_wrapper.get_image_build_cmd.call_args_list,
[mock.call(cmd['image_conf'],
conf_file_dest='amd64,x86_64-Client-Fedora-Docker-Base-docker',
scratch=False)]
)
self.assertEqual(
koji_wrapper.run_blocking_cmd.call_args_list,
[mock.call(koji_wrapper.get_image_build_cmd.return_value,
log_file=self.topdir + '/logs/amd64-x86_64/imagebuild-Client-KDE-docker-qcow2.amd64-x86_64.log')]
)
six.assertCountEqual(
self,
linker.mock_calls,
[mock.call.link(
'/koji/task/1235/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.link(
'/koji/task/1235/Fedora-Docker-Base-20160103.amd64.tar.gz',
self.topdir + '/compose/Client/amd64/images/Fedora-Docker-Base-20160103.amd64.tar.gz',
link_type='hardlink-or-copy'),
mock.call.link(
'/koji/task/1235/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.link(
'/koji/task/1235/Fedora-Docker-Base-20160103.x86_64.tar.gz',
self.topdir + '/compose/Client/x86_64/images/Fedora-Docker-Base-20160103.x86_64.tar.gz',
link_type='hardlink-or-copy')])
image_relative_paths = {
'image_dir/Client/amd64/Fedora-Docker-Base-20160103.amd64.qcow2': {
'format': 'qcow2',
'type': 'qcow2',
'arch': 'amd64',
},
'image_dir/Client/amd64/Fedora-Docker-Base-20160103.amd64.tar.gz': {
'format': 'tar.gz',
'type': 'docker',
'arch': 'amd64',
},
'image_dir/Client/x86_64/Fedora-Docker-Base-20160103.x86_64.qcow2': {
'format': 'qcow2',
'type': 'qcow2',
'arch': 'x86_64',
},
'image_dir/Client/x86_64/Fedora-Docker-Base-20160103.x86_64.tar.gz': {
'format': 'tar.gz',
'type': 'docker',
'arch': 'x86_64',
},
}
# Assert there are 4 images added to manifest and the arguments are sane
self.assertEqual(len(compose.im.add.call_args_list), 4)
for call in compose.im.add.call_args_list:
_, kwargs = call
image = kwargs['image']
self.assertEqual(kwargs['variant'], 'Client')
self.assertIn(kwargs['arch'], ('amd64', 'x86_64'))
self.assertEqual(kwargs['arch'], image.arch)
self.assertIn(image.path, image_relative_paths)
data = image_relative_paths.pop(image.path)
self.assertEqual(data['format'], image.format)
self.assertEqual(data['type'], image.type)
self.assertEqual('KDE', image.subvariant)
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(self.topdir, {'koji_profile': 'koji'})
pool = mock.Mock()
cmd = {
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Client',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker', 'qcow2'],
'repo': '/ostree/$arch/Client',
'variant': compose.variants['Client'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
"can_fail": ['amd64', 'x86_64'],
}
},
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Client/%(arch)s',
"relative_image_dir": 'image_dir/Client/%(arch)s',
"link_type": 'hardlink-or-copy',
'scratch': False,
}
koji_wrapper = KojiWrapper.return_value
koji_wrapper.run_blocking_cmd.return_value = {
"retcode": 1,
"output": None,
"task_id": 1234,
}
t = CreateImageBuildThread(pool)
with mock.patch('time.sleep'):
t.process((compose, cmd), 1)
pool._logger.error.assert_has_calls([
mock.call('[FAIL] Image build (variant Client, arch *, subvariant Client) failed, but going on anyway.'),
mock.call('ImageBuild task failed: 1234. See %s for more details.'
% (os.path.join(self.topdir,
'logs/amd64-x86_64/imagebuild-Client-Client-docker-qcow2.amd64-x86_64.log'))),
])
@mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker')
def test_process_handle_exception(self, Linker, KojiWrapper):
compose = DummyCompose(self.topdir, {'koji_profile': 'koji'})
pool = mock.Mock()
cmd = {
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Client',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker', 'qcow2'],
'repo': '/ostree/$arch/Client',
'variant': compose.variants['Client'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'can_fail': ['amd64', 'x86_64'],
}
},
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Client/%(arch)s',
"relative_image_dir": 'image_dir/Client/%(arch)s',
"link_type": 'hardlink-or-copy',
'scratch': False,
}
koji_wrapper = KojiWrapper.return_value
koji_wrapper.run_blocking_cmd.side_effect = boom
t = CreateImageBuildThread(pool)
with mock.patch('time.sleep'):
t.process((compose, cmd), 1)
pool._logger.error.assert_has_calls([
mock.call('[FAIL] Image build (variant Client, arch *, subvariant Client) failed, but going on anyway.'),
mock.call('BOOM'),
])
@mock.patch('pungi.phases.image_build.KojiWrapper')
@mock.patch('pungi.phases.image_build.Linker')
def test_process_handle_fail_only_one_optional(self, Linker, KojiWrapper):
compose = DummyCompose(self.topdir, {'koji_profile': 'koji'})
pool = mock.Mock()
cmd = {
"image_conf": {
'image-build': {
'install_tree': '/ostree/$arch/Client',
'kickstart': 'fedora-docker-base.ks',
'format': ['docker', 'qcow2'],
'repo': '/ostree/$arch/Client',
'variant': compose.variants['Client'],
'target': 'f24',
'disk_size': 3,
'name': 'Fedora-Docker-Base',
'arches': ['amd64', 'x86_64'],
'version': 'Rawhide',
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
'distro': 'Fedora-20',
'can_fail': ['amd64'],
}
},
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
"image_dir": '/image_dir/Client/%(arch)s',
"relative_image_dir": 'image_dir/Client/%(arch)s',
"link_type": 'hardlink-or-copy',
'scratch': False,
}
koji_wrapper = KojiWrapper.return_value
koji_wrapper.run_blocking_cmd.return_value = {
"retcode": 1,
"output": None,
"task_id": 1234,
}
t = CreateImageBuildThread(pool)
with self.assertRaises(RuntimeError):
with mock.patch('time.sleep'):
t.process((compose, cmd), 1)