pungi/tests/test_createiso_phase.py
Lubomír Sedlář b62b468ccf [createiso] Enable customizing media reserve
Add a documented and tested config options for setting ISO parameters
instead of hardcoding magic values.

Fixes: #256
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
2016-06-02 08:34:49 +02:00

637 lines
26 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 -*-
try:
import unittest2 as unittest
except ImportError:
import unittest
import mock
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from tests import helpers
from pungi.phases import createiso
class CreateisoPhaseTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.ThreadPool')
def test_skip_all(self, ThreadPool):
compose = helpers.DummyCompose(self.topdir, {
'createiso_skip': [
('^.*$', {'*': True, 'src': True})
]
})
pool = ThreadPool.return_value
phase = createiso.CreateisoPhase(compose)
phase.run()
self.assertEqual(len(pool.add.call_args_list), 0)
self.assertEqual(pool.queue_put.call_args_list, [])
@mock.patch('pungi.phases.createiso.ThreadPool')
def test_nothing_happens_without_rpms(self, ThreadPool):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'createiso_skip': [
]
})
pool = ThreadPool.return_value
phase = createiso.CreateisoPhase(compose)
phase.run()
self.assertEqual(len(pool.add.call_args_list), 0)
self.assertEqual(pool.queue_put.call_args_list, [])
self.assertItemsEqual(
compose.log_warning.call_args_list,
[mock.call('No RPMs found for Everything.x86_64, skipping ISO'),
mock.call('No RPMs found for Everything.amd64, skipping ISO'),
mock.call('No RPMs found for Everything.src, skipping ISO'),
mock.call('No RPMs found for Client.amd64, skipping ISO'),
mock.call('No RPMs found for Client.src, skipping ISO'),
mock.call('No RPMs found for Server.x86_64, skipping ISO'),
mock.call('No RPMs found for Server.amd64, skipping ISO'),
mock.call('No RPMs found for Server.src, skipping ISO')]
)
@mock.patch('pungi.phases.createiso.prepare_iso')
@mock.patch('pungi.phases.createiso.split_iso')
@mock.patch('pungi.phases.createiso.ThreadPool')
def test_start_one_worker(self, ThreadPool, split_iso, prepare_iso):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'createiso_skip': [
]
})
helpers.touch(os.path.join(
compose.paths.compose.os_tree('x86_64', compose.variants['Server']),
'dummy.rpm'))
disc_data = mock.Mock()
split_iso.return_value = [disc_data]
prepare_iso.return_value = 'dummy-graft-points'
pool = ThreadPool.return_value
phase = createiso.CreateisoPhase(compose)
phase.run()
self.assertEqual(prepare_iso.call_args_list,
[mock.call(compose, 'x86_64', compose.variants['Server'],
disc_count=1, disc_num=1, split_iso_data=disc_data)])
self.assertEqual(split_iso.call_args_list,
[mock.call(compose, 'x86_64', compose.variants['Server'])])
self.assertEqual(len(pool.add.call_args_list), 1)
self.maxDiff = None
self.assertItemsEqual(
pool.queue_put.call_args_list,
[mock.call((
compose,
{
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False,
'cmd': ['pungi-createiso',
'--output-dir=%s/compose/Server/x86_64/iso' % self.topdir,
'--iso-name=image-name', '--volid=test-1.0 Server.x86_64',
'--graft-points=dummy-graft-points',
'--arch=x86_64', '--supported',
'--jigdo-dir=%s/compose/Server/x86_64/jigdo' % self.topdir,
'--os-tree=%s/compose/Server/x86_64/os' % self.topdir],
'label': '',
'disc_num': 1,
'disc_count': 1,
},
compose.variants['Server'],
'x86_64'
))]
)
@mock.patch('pungi.phases.createiso.prepare_iso')
@mock.patch('pungi.phases.createiso.split_iso')
@mock.patch('pungi.phases.createiso.ThreadPool')
def test_bootable(self, ThreadPool, split_iso, prepare_iso):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'buildinstall_method': 'lorax',
'bootable': True,
'createiso_skip': [
]
})
helpers.touch(os.path.join(
compose.paths.compose.os_tree('x86_64', compose.variants['Server']),
'dummy.rpm'))
helpers.touch(os.path.join(
compose.paths.compose.os_tree('src', compose.variants['Server']),
'dummy.rpm'))
disc_data = mock.Mock()
split_iso.return_value = [disc_data]
prepare_iso.return_value = 'dummy-graft-points'
pool = ThreadPool.return_value
phase = createiso.CreateisoPhase(compose)
phase.run()
self.assertItemsEqual(
prepare_iso.call_args_list,
[mock.call(compose, 'x86_64', compose.variants['Server'],
disc_count=1, disc_num=1, split_iso_data=disc_data),
mock.call(compose, 'src', compose.variants['Server'],
disc_count=1, disc_num=1, split_iso_data=disc_data)])
self.assertItemsEqual(
split_iso.call_args_list,
[mock.call(compose, 'x86_64', compose.variants['Server']),
mock.call(compose, 'src', compose.variants['Server'])])
self.assertEqual(len(pool.add.call_args_list), 2)
self.maxDiff = None
self.assertItemsEqual(
pool.queue_put.call_args_list,
[mock.call((compose,
{'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': True,
'cmd': ['pungi-createiso',
'--output-dir=%s/compose/Server/x86_64/iso' % self.topdir,
'--iso-name=image-name', '--volid=test-1.0 Server.x86_64',
'--graft-points=dummy-graft-points',
'--arch=x86_64',
'--buildinstall-method=lorax',
'--supported',
'--jigdo-dir=%s/compose/Server/x86_64/jigdo' % self.topdir,
'--os-tree=%s/compose/Server/x86_64/os' % self.topdir],
'label': '',
'disc_num': 1,
'disc_count': 1},
compose.variants['Server'],
'x86_64')),
mock.call((compose,
{'iso_path': '%s/compose/Server/source/iso/image-name' % self.topdir,
'bootable': False,
'cmd': ['pungi-createiso',
'--output-dir=%s/compose/Server/source/iso' % self.topdir,
'--iso-name=image-name', '--volid=test-1.0 Server.src',
'--graft-points=dummy-graft-points',
'--arch=src', '--supported',
'--jigdo-dir=%s/compose/Server/source/jigdo' % self.topdir,
'--os-tree=%s/compose/Server/source/tree' % self.topdir],
'label': '',
'disc_num': 1,
'disc_count': 1},
compose.variants['Server'],
'src'))]
)
class CreateisoThreadTest(helpers.PungiTestCase):
@mock.patch('pungi.phases.createiso.IsoWrapper')
@mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper')
def test_process_in_runroot(self, KojiWrapper, get_file_size, get_mtime, IsoWrapper):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'runroot': True,
'runroot_tag': 'f25-build',
'koji_profile': 'koji',
})
cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False,
'cmd': mock.Mock(),
'label': '',
'disc_num': 1,
'disc_count': 1,
}
get_file_size.return_value = 1024
get_mtime.return_value = 13579
getTag = KojiWrapper.return_value.koji_proxy.getTag
getTag.return_value = {'arches': 'x86_64'}
get_runroot_cmd = KojiWrapper.return_value.get_runroot_cmd
run_runroot = KojiWrapper.return_value.run_runroot_cmd
run_runroot.return_value = {
'retcode': 0,
'output': 'whatever',
'task_id': 1234,
}
t = createiso.CreateIsoThread(mock.Mock())
with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
self.assertEqual(getTag.call_args_list, [mock.call('f25-build')])
self.assertEqual(get_runroot_cmd.call_args_list,
[mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None,
mounts=[self.topdir],
packages=['coreutils', 'genisoimage', 'isomd5sum',
'jigdo', 'pungi'],
task_id=True, use_shell=True)])
self.assertEqual(
run_runroot.call_args_list,
[mock.call(get_runroot_cmd.return_value,
log_file='%s/logs/x86_64/createiso-image-name.x86_64.log' % self.topdir)])
self.assertEqual(IsoWrapper.return_value.get_implanted_md5.call_args_list,
[mock.call(cmd['iso_path'])])
self.assertEqual(IsoWrapper.return_value.get_volume_id.call_args_list,
[mock.call(cmd['iso_path'])])
self.assertEqual(len(compose.im.add.call_args_list), 1)
args, _ = compose.im.add.call_args_list[0]
self.assertEqual(args[0], 'Server')
self.assertEqual(args[1], 'x86_64')
image = args[2]
self.assertEqual(image.arch, 'x86_64')
self.assertEqual(image.path, 'Server/x86_64/iso/image-name')
self.assertEqual(image.format, 'iso')
self.assertEqual(image.type, 'dvd')
self.assertEqual(image.subvariant, 'Server')
@mock.patch('pungi.phases.createiso.IsoWrapper')
@mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper')
def test_process_bootable(self, KojiWrapper, get_file_size, get_mtime, IsoWrapper):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'runroot': True,
'bootable': True,
'buildinstall_method': 'lorax',
'runroot_tag': 'f25-build',
'koji_profile': 'koji',
})
cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': True,
'cmd': mock.Mock(),
'label': '',
'disc_num': 1,
'disc_count': 1,
}
get_file_size.return_value = 1024
get_mtime.return_value = 13579
getTag = KojiWrapper.return_value.koji_proxy.getTag
getTag.return_value = {'arches': 'x86_64'}
get_runroot_cmd = KojiWrapper.return_value.get_runroot_cmd
run_runroot = KojiWrapper.return_value.run_runroot_cmd
run_runroot.return_value = {
'retcode': 0,
'output': 'whatever',
'task_id': 1234,
}
t = createiso.CreateIsoThread(mock.Mock())
with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
self.assertEqual(getTag.call_args_list, [mock.call('f25-build')])
self.assertEqual(get_runroot_cmd.call_args_list,
[mock.call('f25-build', 'x86_64', cmd['cmd'], channel=None,
mounts=[self.topdir],
packages=['coreutils', 'genisoimage', 'isomd5sum',
'jigdo', 'pungi', 'lorax'],
task_id=True, use_shell=True)])
self.assertEqual(
run_runroot.call_args_list,
[mock.call(get_runroot_cmd.return_value,
log_file='%s/logs/x86_64/createiso-image-name.x86_64.log' % self.topdir)])
self.assertEqual(IsoWrapper.return_value.get_implanted_md5.call_args_list,
[mock.call(cmd['iso_path'])])
self.assertEqual(IsoWrapper.return_value.get_volume_id.call_args_list,
[mock.call(cmd['iso_path'])])
self.assertEqual(len(compose.im.add.call_args_list), 1)
args, _ = compose.im.add.call_args_list[0]
self.assertEqual(args[0], 'Server')
self.assertEqual(args[1], 'x86_64')
image = args[2]
self.assertEqual(image.arch, 'x86_64')
self.assertEqual(image.path, 'Server/x86_64/iso/image-name')
self.assertEqual(image.format, 'iso')
self.assertEqual(image.type, 'dvd')
self.assertEqual(image.subvariant, 'Server')
@mock.patch('pungi.phases.createiso.IsoWrapper')
@mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper')
def test_process_in_runroot_crash(self, KojiWrapper, get_file_size, get_mtime, IsoWrapper):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'runroot': True,
'runroot_tag': 'f25-build',
'koji_profile': 'koji',
'failable_deliverables': [
('^.*$', {'*': 'iso'})
]
})
cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False,
'cmd': mock.Mock(),
'label': '',
'disc_num': 1,
'disc_count': 1,
}
getTag = KojiWrapper.return_value.koji_proxy.getTag
getTag.return_value = {'arches': 'x86_64'}
run_runroot = KojiWrapper.return_value.run_runroot_cmd
run_runroot.side_effect = helpers.boom
t = createiso.CreateIsoThread(mock.Mock())
with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
compose.log_info.assert_has_calls([
mock.call('[FAIL] Iso (variant Server, arch x86_64) failed, but going on anyway.'),
mock.call('BOOM')
])
@mock.patch('pungi.phases.createiso.IsoWrapper')
@mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.KojiWrapper')
def test_process_in_runroot_fail(self, KojiWrapper, get_file_size, get_mtime, IsoWrapper):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'runroot': True,
'runroot_tag': 'f25-build',
'koji_profile': 'koji',
'failable_deliverables': [
('^.*$', {'*': 'iso'})
]
})
cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False,
'cmd': mock.Mock(),
'label': '',
'disc_num': 1,
'disc_count': 1,
}
getTag = KojiWrapper.return_value.koji_proxy.getTag
getTag.return_value = {'arches': 'x86_64'}
run_runroot = KojiWrapper.return_value.run_runroot_cmd
run_runroot.return_value = {
'retcode': 1,
'output': 'Nope',
'task_id': '1234',
}
t = createiso.CreateIsoThread(mock.Mock())
with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
compose.log_info.assert_has_calls([
mock.call('[FAIL] Iso (variant Server, arch x86_64) failed, but going on anyway.'),
mock.call('Runroot task failed: 1234. See %s for more details.'
% (self.topdir + '/logs/x86_64/createiso-image-name.x86_64.log'))
])
@mock.patch('pungi.phases.createiso.IsoWrapper')
@mock.patch('pungi.phases.createiso.get_mtime')
@mock.patch('pungi.phases.createiso.get_file_size')
@mock.patch('pungi.phases.createiso.run')
@mock.patch('pungi.phases.createiso.KojiWrapper')
def test_process_locally(self, KojiWrapper, run, get_file_size, get_mtime, IsoWrapper):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'runroot': False,
})
cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False,
'cmd': mock.Mock(),
'label': '',
'disc_num': 1,
'disc_count': 1,
}
get_file_size.return_value = 1024
get_mtime.return_value = 13579
t = createiso.CreateIsoThread(mock.Mock())
with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
self.assertEqual(KojiWrapper.return_value.mock_calls, [])
self.assertEqual(
run.call_args_list,
[mock.call(cmd['cmd'], show_cmd=True,
logfile='%s/logs/x86_64/createiso-image-name.x86_64.log' % self.topdir)])
self.assertEqual(IsoWrapper.return_value.get_implanted_md5.call_args_list,
[mock.call(cmd['iso_path'])])
self.assertEqual(IsoWrapper.return_value.get_volume_id.call_args_list,
[mock.call(cmd['iso_path'])])
self.assertEqual(len(compose.im.add.call_args_list), 1)
args, _ = compose.im.add.call_args_list[0]
self.assertEqual(args[0], 'Server')
self.assertEqual(args[1], 'x86_64')
image = args[2]
self.assertEqual(image.arch, 'x86_64')
self.assertEqual(image.path, 'Server/x86_64/iso/image-name')
self.assertEqual(image.format, 'iso')
self.assertEqual(image.type, 'dvd')
self.assertEqual(image.subvariant, 'Server')
@mock.patch('pungi.phases.createiso.run')
@mock.patch('pungi.phases.createiso.KojiWrapper')
def test_process_locally_crash(self, KojiWrapper, run):
compose = helpers.DummyCompose(self.topdir, {
'release_short': 'test',
'release_version': '1.0',
'release_is_layered': False,
'runroot': False,
'failable_deliverables': [
('^.*$', {'*': 'iso'})
]
})
cmd = {
'iso_path': '%s/compose/Server/x86_64/iso/image-name' % self.topdir,
'bootable': False,
'cmd': mock.Mock(),
'label': '',
'disc_num': 1,
'disc_count': 1,
}
run.side_effect = helpers.boom
t = createiso.CreateIsoThread(mock.Mock())
with mock.patch('time.sleep'):
t.process((compose, cmd, compose.variants['Server'], 'x86_64'), 1)
compose.log_info.assert_has_calls([
mock.call('[FAIL] Iso (variant Server, arch x86_64) failed, but going on anyway.'),
mock.call('BOOM')
])
TREEINFO = '''
[header]
version = 1.0
[release]
name = Dummy Product
short = DP
version = 1.0
[tree]
arch = x86_64
platforms = x86_64
build_timestamp = 1464715102
variants = Server
[variant-Server]
id = Server
uid = Server
name = Server
type = variant
'''
class DummySize(object):
"""
This is intended as a replacement for os.path.getsize that returns
predefined sizes. The argument to __init__ should be a mapping from
substring of filepath to size.
"""
def __init__(self, sizes):
self.sizes = sizes
def __call__(self, path):
for fragment, size in self.sizes.iteritems():
if fragment in path:
return size
return 0
class SplitIsoTest(helpers.PungiTestCase):
def test_split_fits_on_single_disc(self):
compose = helpers.DummyCompose(self.topdir, {})
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/.treeinfo'),
TREEINFO)
helpers.touch(os.path.join(self.topdir, 'work/x86_64/Server/extra-files/GPL'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/GPL'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/repodata/repomd.xml'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/b/bash.rpm'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/n/media.repo'))
with mock.patch('os.path.getsize',
DummySize({'GPL': 20 * 2048, 'bash': 150 * 2048,
'media': 100 * 2048, 'treeinfo': 10 * 2048})):
data = createiso.split_iso(compose, 'x86_64', compose.variants['Server'])
base_path = os.path.join(self.topdir, 'compose/Server/x86_64/os')
# GPL is sticky file, it should be first at all times. Files are
# searched top-down, so nested ones are after top level ones.
self.assertEqual(data,
[{'files': [os.path.join(base_path, 'GPL'),
os.path.join(base_path, '.treeinfo'),
os.path.join(base_path, 'n/media.repo'),
os.path.join(base_path, 'Packages/b/bash.rpm')],
'size': 573440}])
def test_split_needs_two_discs(self):
compose = helpers.DummyCompose(self.topdir, {})
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/.treeinfo'),
TREEINFO)
helpers.touch(os.path.join(self.topdir, 'work/x86_64/Server/extra-files/GPL'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/GPL'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/repodata/repomd.xml'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/b/bash.rpm'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/n/media.repo'))
M = 1024 ** 2
G = 1024 ** 3
with mock.patch('os.path.getsize',
DummySize({'GPL': 20 * M, 'bash': 3 * G,
'media': 2 * G, 'treeinfo': 10 * M})):
data = createiso.split_iso(compose, 'x86_64', compose.variants['Server'])
base_path = os.path.join(self.topdir, 'compose/Server/x86_64/os')
# GPL is the only sticky file, it should be first at all times.
# Files are searched top-down, so nested ones are after top level ones.
self.assertEqual(data,
[{'files': [os.path.join(base_path, 'GPL'),
os.path.join(base_path, '.treeinfo'),
os.path.join(base_path, 'n/media.repo')],
'size': 2178940928},
{'files': [os.path.join(base_path, 'GPL'),
os.path.join(base_path, 'Packages/b/bash.rpm')],
'size': 3242196992}])
def test_keeps_reserve(self):
compose = helpers.DummyCompose(self.topdir, {})
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/.treeinfo'),
TREEINFO)
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/spacer.rpm'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/x/pad.rpm'))
M = 1024 ** 2
# treeinfo has size 0, spacer leaves 11M of free space, so with 10M
# reserve the padding package should be on second disk
with mock.patch('os.path.getsize', DummySize({'spacer': 4688465664, 'pad': 5 * M})):
data = createiso.split_iso(compose, 'x86_64', compose.variants['Server'])
base_path = os.path.join(self.topdir, 'compose/Server/x86_64/os')
self.assertEqual(len(data), 2)
self.assertEqual(data[0]['files'], [os.path.join(base_path, '.treeinfo'),
os.path.join(base_path, 'Packages/spacer.rpm')])
self.assertEqual(data[1]['files'], [os.path.join(base_path, 'Packages/x/pad.rpm')])
def test_can_customize_reserve(self):
compose = helpers.DummyCompose(self.topdir, {'split_iso_reserve': 1024 ** 2})
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/.treeinfo'),
TREEINFO)
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/spacer.rpm'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/x/pad.rpm'))
M = 1024 ** 2
with mock.patch('os.path.getsize', DummySize({'spacer': 4688465664, 'pad': 5 * M})):
data = createiso.split_iso(compose, 'x86_64', compose.variants['Server'])
self.assertEqual(len(data), 1)
def test_can_change_iso_size(self):
compose = helpers.DummyCompose(self.topdir, {'iso_size': '8G'})
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/.treeinfo'),
TREEINFO)
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/spacer.rpm'))
helpers.touch(os.path.join(self.topdir, 'compose/Server/x86_64/os/Packages/x/pad.rpm'))
M = 1024 ** 2
with mock.patch('os.path.getsize', DummySize({'spacer': 4688465664, 'pad': 5 * M})):
data = createiso.split_iso(compose, 'x86_64', compose.variants['Server'])
self.assertEqual(len(data), 1)
if __name__ == '__main__':
unittest.main()