Merge #475 Allow failure for some arches
This commit is contained in:
commit
46f77403df
@ -864,13 +864,11 @@ provided; date, compose type and respin will be used.
|
|||||||
* ``image_build_release``
|
* ``image_build_release``
|
||||||
* ``live_images_release``
|
* ``live_images_release``
|
||||||
|
|
||||||
Each configuration block can also optionally specify a list of architectures
|
Each configuration block can also optionally specify a ``failable`` key. For
|
||||||
that are not release blocking with ``failable`` key. If any deliverable fails,
|
live images it should have a boolean value. For live media and image build it
|
||||||
it will not abort the whole compose. Due to limitations in how the tasks are
|
should be a list of strings containing architectures that are optional. If any
|
||||||
done in Koji, if any architecture fails, all of them fail. Until this is
|
deliverable fails on an optional architecture, it will not abort the whole
|
||||||
resolved, it is not possible to configure failability per architecture. An
|
compose. If the list contains only ``"*"``, all arches will be substituted.
|
||||||
empty list means required deliverable, non-empty list means non-blocking
|
|
||||||
deliverable.
|
|
||||||
|
|
||||||
|
|
||||||
Live Images Settings
|
Live Images Settings
|
||||||
|
@ -120,6 +120,12 @@ class ImageBuildPhase(base.PhaseLoggerMixin, base.ImageConfigMixin, base.ConfigG
|
|||||||
image_conf["image-build"]["format"] = ",".join([x[0] for x in image_conf["image-build"]["format"]])
|
image_conf["image-build"]["format"] = ",".join([x[0] for x in image_conf["image-build"]["format"]])
|
||||||
image_conf["image-build"]['repo'] = self._get_repo(image_conf['image-build'], variant)
|
image_conf["image-build"]['repo'] = self._get_repo(image_conf['image-build'], variant)
|
||||||
|
|
||||||
|
can_fail = image_conf['image-build'].pop('failable', [])
|
||||||
|
if can_fail == ['*']:
|
||||||
|
can_fail = image_conf['image-build']['arches']
|
||||||
|
if can_fail:
|
||||||
|
image_conf['image-build']['can_fail'] = ','.join(sorted(can_fail))
|
||||||
|
|
||||||
cmd = {
|
cmd = {
|
||||||
"format": format,
|
"format": format,
|
||||||
"image_conf": image_conf,
|
"image_conf": image_conf,
|
||||||
@ -134,7 +140,6 @@ class ImageBuildPhase(base.PhaseLoggerMixin, base.ImageConfigMixin, base.ConfigG
|
|||||||
),
|
),
|
||||||
"link_type": self.compose.conf["link_type"],
|
"link_type": self.compose.conf["link_type"],
|
||||||
"scratch": image_conf['image-build'].pop('scratch', False),
|
"scratch": image_conf['image-build'].pop('scratch', False),
|
||||||
"failable_arches": image_conf['image-build'].pop('failable', []),
|
|
||||||
}
|
}
|
||||||
self.pool.add(CreateImageBuildThread(self.pool))
|
self.pool.add(CreateImageBuildThread(self.pool))
|
||||||
self.pool.queue_put((self.compose, cmd))
|
self.pool.queue_put((self.compose, cmd))
|
||||||
@ -150,15 +155,15 @@ class CreateImageBuildThread(WorkerThread):
|
|||||||
compose, cmd = item
|
compose, cmd = item
|
||||||
variant = cmd["image_conf"]["image-build"]["variant"]
|
variant = cmd["image_conf"]["image-build"]["variant"]
|
||||||
subvariant = cmd["image_conf"]["image-build"].get("subvariant", variant.uid)
|
subvariant = cmd["image_conf"]["image-build"].get("subvariant", variant.uid)
|
||||||
failable_arches = cmd.get('failable_arches', [])
|
self.failable_arches = cmd["image_conf"]['image-build'].get('can_fail', '')
|
||||||
self.can_fail = bool(failable_arches)
|
self.can_fail = self.failable_arches == cmd['image_conf']['image-build']['arches']
|
||||||
# TODO handle failure per architecture; currently not possible in single task
|
|
||||||
with failable(compose, self.can_fail, variant, '*', 'image-build', subvariant,
|
with failable(compose, self.can_fail, variant, '*', 'image-build', subvariant,
|
||||||
logger=self.pool._logger):
|
logger=self.pool._logger):
|
||||||
self.worker(num, compose, variant, subvariant, cmd)
|
self.worker(num, compose, variant, subvariant, cmd)
|
||||||
|
|
||||||
def worker(self, num, compose, variant, subvariant, cmd):
|
def worker(self, num, compose, variant, subvariant, cmd):
|
||||||
arches = cmd["image_conf"]["image-build"]['arches'].split(',')
|
arches = cmd["image_conf"]["image-build"]['arches'].split(',')
|
||||||
|
failable_arches = self.failable_arches.split(',')
|
||||||
dash_arches = '-'.join(arches)
|
dash_arches = '-'.join(arches)
|
||||||
log_file = compose.paths.log.log_file(
|
log_file = compose.paths.log.log_file(
|
||||||
dash_arches,
|
dash_arches,
|
||||||
@ -202,7 +207,7 @@ class CreateImageBuildThread(WorkerThread):
|
|||||||
image_infos.append({'path': path, 'suffix': suffix, 'type': format, 'arch': arch})
|
image_infos.append({'path': path, 'suffix': suffix, 'type': format, 'arch': arch})
|
||||||
break
|
break
|
||||||
|
|
||||||
if len(image_infos) != len(cmd['format']) * len(arches):
|
if len(image_infos) != len(cmd['format']) * (len(arches) - len(failable_arches)):
|
||||||
self.pool.log_error(
|
self.pool.log_error(
|
||||||
"Error in koji task %s. Expected to find same amount of images "
|
"Error in koji task %s. Expected to find same amount of images "
|
||||||
"as in suffixes attr in image-build (%s) for each arch (%s). Got '%s'." %
|
"as in suffixes attr in image-build (%s) for each arch (%s). Got '%s'." %
|
||||||
|
@ -152,7 +152,6 @@ class CreateLiveImageThread(WorkerThread):
|
|||||||
def process(self, item, num):
|
def process(self, item, num):
|
||||||
compose, cmd, variant, arch = item
|
compose, cmd, variant, arch = item
|
||||||
self.failable_arches = cmd.get('failable_arches', [])
|
self.failable_arches = cmd.get('failable_arches', [])
|
||||||
# TODO handle failure per architecture; currently not possible in single task
|
|
||||||
self.can_fail = bool(self.failable_arches)
|
self.can_fail = bool(self.failable_arches)
|
||||||
with failable(compose, self.can_fail, variant, arch, 'live', cmd.get('subvariant'),
|
with failable(compose, self.can_fail, variant, arch, 'live', cmd.get('subvariant'),
|
||||||
logger=self.pool._logger):
|
logger=self.pool._logger):
|
||||||
|
@ -90,6 +90,8 @@ class LiveMediaPhase(PhaseLoggerMixin, ImageConfigMixin, ConfigGuardedPhase):
|
|||||||
'version': self.get_version(image_conf),
|
'version': self.get_version(image_conf),
|
||||||
'failable_arches': image_conf.get('failable', []),
|
'failable_arches': image_conf.get('failable', []),
|
||||||
}
|
}
|
||||||
|
if config['failable_arches'] == ['*']:
|
||||||
|
config['failable_arches'] = config['arches']
|
||||||
self.pool.add(LiveMediaThread(self.pool))
|
self.pool.add(LiveMediaThread(self.pool))
|
||||||
self.pool.queue_put((self.compose, variant, config))
|
self.pool.queue_put((self.compose, variant, config))
|
||||||
|
|
||||||
@ -102,8 +104,8 @@ class LiveMediaThread(WorkerThread):
|
|||||||
subvariant = config.pop('subvariant')
|
subvariant = config.pop('subvariant')
|
||||||
self.failable_arches = config.pop('failable_arches')
|
self.failable_arches = config.pop('failable_arches')
|
||||||
self.num = num
|
self.num = num
|
||||||
# TODO handle failure per architecture; currently not possible in single task
|
can_fail = set(self.failable_arches) == set(config['arches'])
|
||||||
with failable(compose, bool(self.failable_arches), variant, '*', 'live-media', subvariant,
|
with failable(compose, can_fail, variant, '*', 'live-media', subvariant,
|
||||||
logger=self.pool._logger):
|
logger=self.pool._logger):
|
||||||
self.worker(compose, variant, subvariant, config)
|
self.worker(compose, variant, subvariant, config)
|
||||||
|
|
||||||
@ -126,6 +128,7 @@ class LiveMediaThread(WorkerThread):
|
|||||||
"""Replace `arches` (as list) with `arch` as a comma-separated string."""
|
"""Replace `arches` (as list) with `arch` as a comma-separated string."""
|
||||||
copy = dict(config)
|
copy = dict(config)
|
||||||
copy['arch'] = ','.join(copy.pop('arches', []))
|
copy['arch'] = ','.join(copy.pop('arches', []))
|
||||||
|
copy['can_fail'] = self.failable_arches
|
||||||
return koji_wrapper.get_live_media_cmd(copy)
|
return koji_wrapper.get_live_media_cmd(copy)
|
||||||
|
|
||||||
def worker(self, compose, variant, subvariant, config):
|
def worker(self, compose, variant, subvariant, config):
|
||||||
@ -149,9 +152,10 @@ class LiveMediaThread(WorkerThread):
|
|||||||
if path.endswith('.iso'):
|
if path.endswith('.iso'):
|
||||||
image_infos.append({'path': path, 'arch': arch})
|
image_infos.append({'path': path, 'arch': arch})
|
||||||
|
|
||||||
if len(image_infos) != len(config['arches']):
|
if len(image_infos) < len(config['arches']) - len(self.failable_arches):
|
||||||
self.pool.log_error(
|
self.pool.log_error(
|
||||||
'Error in koji task %s. Expected to find one image for each arch (%s). Got %s.'
|
'Error in koji task %s. Expected to find at least one image '
|
||||||
|
'for each required arch (%s). Got %s.'
|
||||||
% (output['task_id'], len(config['arches']), len(image_infos)))
|
% (output['task_id'], len(config['arches']), len(image_infos)))
|
||||||
raise RuntimeError('Image count mismatch in task %s.' % output['task_id'])
|
raise RuntimeError('Image count mismatch in task %s.' % output['task_id'])
|
||||||
|
|
||||||
|
@ -191,6 +191,9 @@ class KojiWrapper(object):
|
|||||||
if 'release' in options:
|
if 'release' in options:
|
||||||
cmd.append('--release=%s' % options['release'])
|
cmd.append('--release=%s' % options['release'])
|
||||||
|
|
||||||
|
if 'can_fail' in options:
|
||||||
|
cmd.append('--can-fail=%s' % ','.join(options['can_fail']))
|
||||||
|
|
||||||
if wait:
|
if wait:
|
||||||
cmd.append('--wait')
|
cmd.append('--wait')
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
||||||
'distro': 'Fedora-20',
|
'distro': 'Fedora-20',
|
||||||
|
'can_fail': 'x86_64',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"conf_file": self.topdir + '/work/image-build/Client/docker_Fedora-Docker-Base.cfg',
|
"conf_file": self.topdir + '/work/image-build/Client/docker_Fedora-Docker-Base.cfg',
|
||||||
@ -77,7 +78,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Client/%(arch)s/images',
|
"relative_image_dir": 'Client/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": ['x86_64'],
|
|
||||||
}
|
}
|
||||||
server_args = {
|
server_args = {
|
||||||
"format": [('docker', 'tar.xz')],
|
"format": [('docker', 'tar.xz')],
|
||||||
@ -95,6 +95,7 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
||||||
'distro': 'Fedora-20',
|
'distro': 'Fedora-20',
|
||||||
|
'can_fail': 'x86_64',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
|
"conf_file": self.topdir + '/work/image-build/Server/docker_Fedora-Docker-Base.cfg',
|
||||||
@ -102,7 +103,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server/%(arch)s/images',
|
"relative_image_dir": 'Server/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": ['x86_64'],
|
|
||||||
}
|
}
|
||||||
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)),
|
||||||
@ -163,7 +163,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server/%(arch)s/images',
|
"relative_image_dir": 'Server/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": [],
|
|
||||||
}
|
}
|
||||||
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
||||||
[mock.call((compose, server_args))])
|
[mock.call((compose, server_args))])
|
||||||
@ -220,7 +219,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server/%(arch)s/images',
|
"relative_image_dir": 'Server/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": [],
|
|
||||||
}
|
}
|
||||||
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
||||||
[mock.call((compose, server_args))])
|
[mock.call((compose, server_args))])
|
||||||
@ -318,7 +316,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server/%(arch)s/images',
|
"relative_image_dir": 'Server/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": [],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@mock.patch('pungi.phases.image_build.ThreadPool')
|
@mock.patch('pungi.phases.image_build.ThreadPool')
|
||||||
@ -383,7 +380,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server/%(arch)s/images',
|
"relative_image_dir": 'Server/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": [],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@mock.patch('pungi.phases.image_build.ThreadPool')
|
@mock.patch('pungi.phases.image_build.ThreadPool')
|
||||||
@ -445,7 +441,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server/%(arch)s/images',
|
"relative_image_dir": 'Server/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": [],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@mock.patch('pungi.phases.image_build.ThreadPool')
|
@mock.patch('pungi.phases.image_build.ThreadPool')
|
||||||
@ -612,6 +607,7 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
||||||
'distro': 'Fedora-20',
|
'distro': 'Fedora-20',
|
||||||
|
'can_fail': 'x86_64',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"conf_file": self.topdir + '/work/image-build/Server-optional/docker_Fedora-Docker-Base.cfg',
|
"conf_file": self.topdir + '/work/image-build/Server-optional/docker_Fedora-Docker-Base.cfg',
|
||||||
@ -619,7 +615,6 @@ class TestImageBuildPhase(PungiTestCase):
|
|||||||
"relative_image_dir": 'Server-optional/%(arch)s/images',
|
"relative_image_dir": 'Server-optional/%(arch)s/images',
|
||||||
"link_type": 'hardlink-or-copy',
|
"link_type": 'hardlink-or-copy',
|
||||||
"scratch": False,
|
"scratch": False,
|
||||||
"failable_arches": ['x86_64'],
|
|
||||||
}
|
}
|
||||||
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
||||||
[mock.call((compose, server_args))])
|
[mock.call((compose, server_args))])
|
||||||
@ -781,6 +776,7 @@ class TestCreateImageBuildThread(PungiTestCase):
|
|||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
||||||
'distro': 'Fedora-20',
|
'distro': 'Fedora-20',
|
||||||
|
"can_fail": 'amd64,x86_64',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
|
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
|
||||||
@ -788,7 +784,6 @@ class TestCreateImageBuildThread(PungiTestCase):
|
|||||||
"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,
|
||||||
"failable_arches": ['*'],
|
|
||||||
}
|
}
|
||||||
koji_wrapper = KojiWrapper.return_value
|
koji_wrapper = KojiWrapper.return_value
|
||||||
koji_wrapper.run_blocking_cmd.return_value = {
|
koji_wrapper.run_blocking_cmd.return_value = {
|
||||||
@ -829,6 +824,7 @@ class TestCreateImageBuildThread(PungiTestCase):
|
|||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
'ksurl': 'git://git.fedorahosted.org/git/spin-kickstarts.git',
|
||||||
'distro': 'Fedora-20',
|
'distro': 'Fedora-20',
|
||||||
|
'can_fail': 'amd64,x86_64',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
|
"conf_file": 'amd64,x86_64-Client-Fedora-Docker-Base-docker',
|
||||||
@ -836,7 +832,6 @@ class TestCreateImageBuildThread(PungiTestCase):
|
|||||||
"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,
|
||||||
"failable_arches": ['*'],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
koji_wrapper = KojiWrapper.return_value
|
koji_wrapper = KojiWrapper.return_value
|
||||||
@ -851,6 +846,49 @@ class TestCreateImageBuildThread(PungiTestCase):
|
|||||||
mock.call('BOOM'),
|
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 = {
|
||||||
|
"format": [('docker', 'tar.xz'), ('qcow2', 'qcow2')],
|
||||||
|
"image_conf": {
|
||||||
|
'image-build': {
|
||||||
|
'install_tree': '/ostree/$arch/Client',
|
||||||
|
'kickstart': 'fedora-docker-base.ks',
|
||||||
|
'format': 'docker',
|
||||||
|
'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)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -59,6 +59,51 @@ class TestLiveMediaPhase(PungiTestCase):
|
|||||||
'failable_arches': [],
|
'failable_arches': [],
|
||||||
}))])
|
}))])
|
||||||
|
|
||||||
|
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
|
||||||
|
def test_expand_failable(self, ThreadPool):
|
||||||
|
compose = DummyCompose(self.topdir, {
|
||||||
|
'live_media': {
|
||||||
|
'^Server$': [
|
||||||
|
{
|
||||||
|
'target': 'f24',
|
||||||
|
'kickstart': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git',
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'version': 'Rawhide',
|
||||||
|
'failable': ['*'],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'koji_profile': 'koji',
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertValidConfig(compose.conf)
|
||||||
|
|
||||||
|
phase = LiveMediaPhase(compose)
|
||||||
|
|
||||||
|
phase.run()
|
||||||
|
self.assertTrue(phase.pool.add.called)
|
||||||
|
self.assertEqual(phase.pool.queue_put.call_args_list,
|
||||||
|
[mock.call((compose,
|
||||||
|
compose.variants['Server'],
|
||||||
|
{
|
||||||
|
'arches': ['amd64', 'x86_64'],
|
||||||
|
'ksfile': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git',
|
||||||
|
'ksversion': None,
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'release': None,
|
||||||
|
'repo': [self.topdir + '/compose/Server/$basearch/os'],
|
||||||
|
'scratch': False,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'install_tree': self.topdir + '/compose/Server/$basearch/os',
|
||||||
|
'version': 'Rawhide',
|
||||||
|
'subvariant': 'Server',
|
||||||
|
'failable_arches': ['amd64', 'x86_64'],
|
||||||
|
}))])
|
||||||
|
|
||||||
@mock.patch('pungi.util.resolve_git_url')
|
@mock.patch('pungi.util.resolve_git_url')
|
||||||
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
|
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
|
||||||
def test_live_media_with_phase_global_opts(self, ThreadPool, resolve_git_url):
|
def test_live_media_with_phase_global_opts(self, ThreadPool, resolve_git_url):
|
||||||
@ -368,7 +413,7 @@ class TestLiveMediaPhase(PungiTestCase):
|
|||||||
'install_tree': self.topdir + '/compose/Server-optional/$basearch/os',
|
'install_tree': self.topdir + '/compose/Server-optional/$basearch/os',
|
||||||
'version': '25',
|
'version': '25',
|
||||||
'subvariant': 'Something',
|
'subvariant': 'Something',
|
||||||
'failable_arches': ['*'],
|
'failable_arches': ['x86_64'],
|
||||||
}))])
|
}))])
|
||||||
|
|
||||||
|
|
||||||
@ -446,7 +491,8 @@ class TestLiveMediaThread(PungiTestCase):
|
|||||||
'skip_tag': None,
|
'skip_tag': None,
|
||||||
'target': 'f24',
|
'target': 'f24',
|
||||||
'title': None,
|
'title': None,
|
||||||
'version': 'Rawhide'})])
|
'version': 'Rawhide',
|
||||||
|
'can_fail': []})])
|
||||||
self.assertEqual(get_image_paths.mock_calls,
|
self.assertEqual(get_image_paths.mock_calls,
|
||||||
[mock.call(1234)])
|
[mock.call(1234)])
|
||||||
self.assertTrue(os.path.isdir(self.topdir + '/compose/Server/x86_64/iso'))
|
self.assertTrue(os.path.isdir(self.topdir + '/compose/Server/x86_64/iso'))
|
||||||
@ -498,7 +544,7 @@ class TestLiveMediaThread(PungiTestCase):
|
|||||||
'title': None,
|
'title': None,
|
||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'subvariant': 'KDE',
|
'subvariant': 'KDE',
|
||||||
'failable_arches': ['*'],
|
'failable_arches': ['amd64', 'x86_64'],
|
||||||
}
|
}
|
||||||
pool = mock.Mock()
|
pool = mock.Mock()
|
||||||
|
|
||||||
@ -520,6 +566,22 @@ class TestLiveMediaThread(PungiTestCase):
|
|||||||
mock.call('Live media task failed: 1234. See %s for more details.'
|
mock.call('Live media task failed: 1234. See %s for more details.'
|
||||||
% (os.path.join(self.topdir, 'logs/amd64-x86_64/livemedia-Server-KDE.amd64-x86_64.log')))
|
% (os.path.join(self.topdir, 'logs/amd64-x86_64/livemedia-Server-KDE.amd64-x86_64.log')))
|
||||||
])
|
])
|
||||||
|
self.assertEqual(KojiWrapper.return_value.get_live_media_cmd.mock_calls,
|
||||||
|
[mock.call({
|
||||||
|
'arch': 'amd64,x86_64',
|
||||||
|
'ksfile': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git',
|
||||||
|
'ksversion': None,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'release': None,
|
||||||
|
'version': 'Rawhide',
|
||||||
|
'scratch': False,
|
||||||
|
'can_fail': ['amd64', 'x86_64'],
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'repo': ['/repo/$basearch/Server'],
|
||||||
|
})])
|
||||||
|
|
||||||
@mock.patch('pungi.phases.livemedia_phase.get_mtime')
|
@mock.patch('pungi.phases.livemedia_phase.get_mtime')
|
||||||
@mock.patch('pungi.phases.livemedia_phase.get_file_size')
|
@mock.patch('pungi.phases.livemedia_phase.get_file_size')
|
||||||
@ -545,7 +607,7 @@ class TestLiveMediaThread(PungiTestCase):
|
|||||||
'title': None,
|
'title': None,
|
||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
'subvariant': 'KDE',
|
'subvariant': 'KDE',
|
||||||
'failable_arches': ['*'],
|
'failable_arches': ['amd64', 'x86_64'],
|
||||||
}
|
}
|
||||||
pool = mock.Mock()
|
pool = mock.Mock()
|
||||||
|
|
||||||
@ -562,6 +624,77 @@ class TestLiveMediaThread(PungiTestCase):
|
|||||||
mock.call('[FAIL] Live media (variant Server, arch *, subvariant KDE) failed, but going on anyway.'),
|
mock.call('[FAIL] Live media (variant Server, arch *, subvariant KDE) failed, but going on anyway.'),
|
||||||
mock.call('BOOM')
|
mock.call('BOOM')
|
||||||
])
|
])
|
||||||
|
self.assertEqual(KojiWrapper.return_value.get_live_media_cmd.mock_calls,
|
||||||
|
[mock.call({
|
||||||
|
'arch': 'amd64,x86_64',
|
||||||
|
'ksfile': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git',
|
||||||
|
'ksversion': None,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'release': None,
|
||||||
|
'version': 'Rawhide',
|
||||||
|
'scratch': False,
|
||||||
|
'can_fail': ['amd64', 'x86_64'],
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'repo': ['/repo/$basearch/Server'],
|
||||||
|
})])
|
||||||
|
|
||||||
|
@mock.patch('pungi.phases.livemedia_phase.get_mtime')
|
||||||
|
@mock.patch('pungi.phases.livemedia_phase.get_file_size')
|
||||||
|
@mock.patch('pungi.phases.livemedia_phase.KojiWrapper')
|
||||||
|
def test_handle_exception_only_one_arch_optional(self, KojiWrapper, get_file_size, get_mtime):
|
||||||
|
compose = DummyCompose(self.topdir, {
|
||||||
|
'koji_profile': 'koji',
|
||||||
|
'failable_deliverables': [
|
||||||
|
('^.+$', {'*': ['live-media']})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
config = {
|
||||||
|
'arches': ['amd64', 'x86_64'],
|
||||||
|
'ksfile': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git',
|
||||||
|
'ksversion': None,
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'release': None,
|
||||||
|
'repo': ['/repo/$basearch/Server'],
|
||||||
|
'scratch': False,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'version': 'Rawhide',
|
||||||
|
'subvariant': 'KDE',
|
||||||
|
'failable_arches': ['amd64'],
|
||||||
|
}
|
||||||
|
pool = mock.Mock()
|
||||||
|
|
||||||
|
run_blocking_cmd = KojiWrapper.return_value.run_blocking_cmd
|
||||||
|
run_blocking_cmd.side_effect = boom
|
||||||
|
get_file_size.return_value = 1024
|
||||||
|
get_mtime.return_value.st_mtime = 13579
|
||||||
|
|
||||||
|
t = LiveMediaThread(pool)
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
with mock.patch('time.sleep'):
|
||||||
|
t.process((compose, compose.variants['Server'], config), 1)
|
||||||
|
|
||||||
|
self.assertEqual(KojiWrapper.return_value.get_live_media_cmd.mock_calls,
|
||||||
|
[mock.call({
|
||||||
|
'arch': 'amd64,x86_64',
|
||||||
|
'ksfile': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git',
|
||||||
|
'ksversion': None,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'release': None,
|
||||||
|
'version': 'Rawhide',
|
||||||
|
'scratch': False,
|
||||||
|
'can_fail': ['amd64'],
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'repo': ['/repo/$basearch/Server'],
|
||||||
|
})])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
Reference in New Issue
Block a user