Cancel koji tasks when pungi terminated
JIRA: RHELCMP-4148 Signed-off-by: Haibo Lin <hlin@redhat.com>
This commit is contained in:
		
							parent
							
								
									edb4517e80
								
							
						
					
					
						commit
						035b37c566
					
				| @ -103,6 +103,16 @@ class LogPaths(object): | ||||
|             makedirs(path) | ||||
|         return path | ||||
| 
 | ||||
|     def koji_tasks_dir(self, create_dir=True): | ||||
|         """ | ||||
|         Examples: | ||||
|             logs/global/koji-tasks | ||||
|         """ | ||||
|         path = os.path.join(self.topdir(create_dir=create_dir), "koji-tasks") | ||||
|         if create_dir: | ||||
|             makedirs(path) | ||||
|         return path | ||||
| 
 | ||||
|     def log_file(self, arch, log_name, create_dir=True): | ||||
|         arch = arch or "global" | ||||
|         if log_name.endswith(".log"): | ||||
| @ -502,6 +512,9 @@ class WorkPaths(object): | ||||
|         """ | ||||
|         Returns the path to file in which the cached version of | ||||
|         PackageSetBase.file_cache should be stored. | ||||
| 
 | ||||
|         Example: | ||||
|             work/global/pkgset_f33-compose_file_cache.pickle | ||||
|         """ | ||||
|         filename = "pkgset_%s_file_cache.pickle" % pkgset_name | ||||
|         return os.path.join(self.topdir(arch="global"), filename) | ||||
|  | ||||
| @ -722,7 +722,7 @@ class BuildinstallThread(WorkerThread): | ||||
|         # Ask Koji for all the RPMs in the `runroot_tag` and check that | ||||
|         # those installed in the old buildinstall buildroot are still in the | ||||
|         # very same versions/releases. | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(compose) | ||||
|         rpms = koji_wrapper.koji_proxy.listTaggedRPMS( | ||||
|             compose.conf.get("runroot_tag"), inherit=True, latest=True | ||||
|         )[0] | ||||
|  | ||||
| @ -346,7 +346,7 @@ def run_createiso_command( | ||||
|     build_arch = arch | ||||
|     if runroot.runroot_method == "koji" and not bootable: | ||||
|         runroot_tag = compose.conf["runroot_tag"] | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(compose) | ||||
|         koji_proxy = koji_wrapper.koji_proxy | ||||
|         tag_info = koji_proxy.getTag(runroot_tag) | ||||
|         if not tag_info: | ||||
|  | ||||
| @ -607,7 +607,7 @@ def _make_lookaside_repo(compose, variant, arch, pkg_map, package_sets=None): | ||||
|         ) | ||||
|         + "/", | ||||
|         "koji": lambda: pungi.wrappers.kojiwrapper.KojiWrapper( | ||||
|             compose.conf["koji_profile"] | ||||
|             compose | ||||
|         ).koji_module.config.topdir.rstrip("/") | ||||
|         + "/", | ||||
|     } | ||||
|  | ||||
| @ -223,7 +223,7 @@ class CreateImageBuildThread(WorkerThread): | ||||
|         ) | ||||
|         self.pool.log_info("[BEGIN] %s" % msg) | ||||
| 
 | ||||
|         koji_wrapper = KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji_wrapper = KojiWrapper(compose) | ||||
| 
 | ||||
|         # writes conf file for koji image-build | ||||
|         self.pool.log_info( | ||||
|  | ||||
| @ -59,12 +59,14 @@ class ImageContainerThread(WorkerThread): | ||||
|         ] | ||||
| 
 | ||||
|         # Start task | ||||
|         koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji = kojiwrapper.KojiWrapper(compose) | ||||
|         koji.login() | ||||
|         task_id = koji.koji_proxy.buildContainer( | ||||
|             source, target, config, priority=priority | ||||
|         ) | ||||
| 
 | ||||
|         koji.save_task_id(task_id) | ||||
| 
 | ||||
|         # Wait for it to finish and capture the output into log file (even | ||||
|         # though there is not much there). | ||||
|         log_dir = os.path.join(compose.paths.log.topdir(), "image_container") | ||||
|  | ||||
| @ -186,7 +186,7 @@ class CreateLiveImageThread(WorkerThread): | ||||
|         ) | ||||
|         self.pool.log_info("[BEGIN] %s" % msg) | ||||
| 
 | ||||
|         koji_wrapper = KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji_wrapper = KojiWrapper(compose) | ||||
|         _, version = compose.compose_id.rsplit("-", 1) | ||||
|         name = cmd["name"] or imgname | ||||
|         version = cmd["version"] or version | ||||
|  | ||||
| @ -140,7 +140,7 @@ class LiveMediaThread(WorkerThread): | ||||
|         ) | ||||
|         self.pool.log_info("[BEGIN] %s" % msg) | ||||
| 
 | ||||
|         koji_wrapper = KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji_wrapper = KojiWrapper(compose) | ||||
|         cmd = self._get_cmd(koji_wrapper, config) | ||||
| 
 | ||||
|         log_file = self._get_log_file(compose, variant, subvariant, config) | ||||
|  | ||||
| @ -77,7 +77,7 @@ class OSBSThread(WorkerThread): | ||||
|     def worker(self, compose, variant, config): | ||||
|         msg = "OSBS task for variant %s" % variant.uid | ||||
|         self.pool.log_info("[BEGIN] %s" % msg) | ||||
|         koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji = kojiwrapper.KojiWrapper(compose) | ||||
|         koji.login() | ||||
| 
 | ||||
|         # Start task | ||||
| @ -98,6 +98,8 @@ class OSBSThread(WorkerThread): | ||||
|             source, target, config, priority=priority | ||||
|         ) | ||||
| 
 | ||||
|         koji.save_task_id(task_id) | ||||
| 
 | ||||
|         # Wait for it to finish and capture the output into log file (even | ||||
|         # though there is not much there). | ||||
|         log_dir = os.path.join(compose.paths.log.topdir(), "osbs") | ||||
| @ -173,7 +175,7 @@ def add_metadata(variant, task_id, compose, is_scratch): | ||||
|     # Create new Koji session. The task could take so long to finish that | ||||
|     # our session will expire. This second session does not need to be | ||||
|     # authenticated since it will only do reading operations. | ||||
|     koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|     koji = kojiwrapper.KojiWrapper(compose) | ||||
| 
 | ||||
|     # Create metadata | ||||
|     metadata = { | ||||
|  | ||||
| @ -110,7 +110,7 @@ class RunOSBuildThread(WorkerThread): | ||||
|     def worker(self, compose, variant, config, arches, version, release, target, repo): | ||||
|         msg = "OSBuild task for variant %s" % variant.uid | ||||
|         self.pool.log_info("[BEGIN] %s" % msg) | ||||
|         koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji = kojiwrapper.KojiWrapper(compose) | ||||
|         koji.login() | ||||
| 
 | ||||
|         # Start task | ||||
| @ -127,6 +127,8 @@ class RunOSBuildThread(WorkerThread): | ||||
|             opts=opts, | ||||
|         ) | ||||
| 
 | ||||
|         koji.save_task_id(task_id) | ||||
| 
 | ||||
|         # Wait for it to finish and capture the output into log file. | ||||
|         log_dir = os.path.join(compose.paths.log.topdir(), "osbuild") | ||||
|         util.makedirs(log_dir) | ||||
| @ -141,7 +143,7 @@ class RunOSBuildThread(WorkerThread): | ||||
|         # Refresh koji session which may have timed out while the task was | ||||
|         # running. Watching is done via a subprocess, so the session is | ||||
|         # inactive. | ||||
|         koji = kojiwrapper.KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji = kojiwrapper.KojiWrapper(compose) | ||||
| 
 | ||||
|         # Get build id via the task's result json data | ||||
|         result = koji.koji_proxy.getTaskResult(task_id) | ||||
|  | ||||
| @ -31,7 +31,6 @@ import kobo.rpmlib | ||||
| 
 | ||||
| from kobo.threads import WorkerThread, ThreadPool | ||||
| 
 | ||||
| import pungi.wrappers.kojiwrapper | ||||
| from pungi.util import pkg_is_srpm, copy_all | ||||
| from pungi.arch import get_valid_arches, is_excluded | ||||
| from pungi.errors import UnsignedPackagesError | ||||
| @ -391,7 +390,6 @@ class KojiPackageSet(PackageSetBase): | ||||
| 
 | ||||
|     def __getstate__(self): | ||||
|         result = self.__dict__.copy() | ||||
|         result["koji_profile"] = self.koji_wrapper.profile | ||||
|         del result["koji_wrapper"] | ||||
|         del result["_logger"] | ||||
|         if "cache_region" in result: | ||||
| @ -399,8 +397,6 @@ class KojiPackageSet(PackageSetBase): | ||||
|         return result | ||||
| 
 | ||||
|     def __setstate__(self, data): | ||||
|         koji_profile = data.pop("koji_profile") | ||||
|         self.koji_wrapper = pungi.wrappers.kojiwrapper.KojiWrapper(koji_profile) | ||||
|         self._logger = None | ||||
|         self.__dict__.update(data) | ||||
| 
 | ||||
|  | ||||
| @ -186,8 +186,7 @@ def get_koji_modules(compose, koji_wrapper, event, module_info_str): | ||||
| class PkgsetSourceKoji(pungi.phases.pkgset.source.PkgsetSourceBase): | ||||
|     def __call__(self): | ||||
|         compose = self.compose | ||||
|         koji_profile = compose.conf["koji_profile"] | ||||
|         self.koji_wrapper = pungi.wrappers.kojiwrapper.KojiWrapper(koji_profile) | ||||
|         self.koji_wrapper = pungi.wrappers.kojiwrapper.KojiWrapper(compose) | ||||
|         # path prefix must contain trailing '/' | ||||
|         path_prefix = self.koji_wrapper.koji_module.config.topdir.rstrip("/") + "/" | ||||
|         package_sets = get_pkgset_from_koji( | ||||
|  | ||||
| @ -110,7 +110,7 @@ class Runroot(kobo.log.LoggingBase): | ||||
|         runroot_tag = self.compose.conf["runroot_tag"] | ||||
|         log_dir = kwargs.pop("log_dir", None) | ||||
| 
 | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(self.compose.conf["koji_profile"]) | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(self.compose) | ||||
|         koji_cmd = koji_wrapper.get_runroot_cmd( | ||||
|             runroot_tag, | ||||
|             arch, | ||||
| @ -303,7 +303,7 @@ class Runroot(kobo.log.LoggingBase): | ||||
|         runroot_channel = self.compose.conf.get("runroot_channel") | ||||
|         runroot_tag = self.compose.conf["runroot_tag"] | ||||
| 
 | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(self.compose.conf["koji_profile"]) | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(self.compose) | ||||
|         koji_cmd = koji_wrapper.get_pungi_buildinstall_cmd( | ||||
|             runroot_tag, | ||||
|             arch, | ||||
| @ -337,7 +337,7 @@ class Runroot(kobo.log.LoggingBase): | ||||
|         runroot_channel = self.compose.conf.get("runroot_channel") | ||||
|         runroot_tag = self.compose.conf["runroot_tag"] | ||||
| 
 | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(self.compose.conf["koji_profile"]) | ||||
|         koji_wrapper = kojiwrapper.KojiWrapper(self.compose) | ||||
|         koji_cmd = koji_wrapper.get_pungi_ostree_cmd( | ||||
|             runroot_tag, arch, args, channel=runroot_channel, **kwargs | ||||
|         ) | ||||
|  | ||||
| @ -22,6 +22,7 @@ from six.moves import shlex_quote | ||||
| from pungi.phases import PHASES_NAMES | ||||
| from pungi import get_full_version, util | ||||
| from pungi.errors import UnsignedPackagesError | ||||
| from pungi.wrappers import kojiwrapper | ||||
| 
 | ||||
| 
 | ||||
| # force C locales | ||||
| @ -615,9 +616,25 @@ def try_kill_children(signal): | ||||
|             COMPOSE.log_warning("Failed to kill all subprocesses") | ||||
| 
 | ||||
| 
 | ||||
| def try_kill_koji_tasks(): | ||||
|     try: | ||||
|         if COMPOSE: | ||||
|             koji_tasks_dir = COMPOSE.paths.log.koji_tasks_dir(create_dir=False) | ||||
|             if os.path.exists(koji_tasks_dir): | ||||
|                 COMPOSE.log_warning("Trying to kill koji tasks") | ||||
|                 koji = kojiwrapper.KojiWrapper(COMPOSE) | ||||
|                 koji.login() | ||||
|                 for task_id in os.listdir(koji_tasks_dir): | ||||
|                     koji.koji_proxy.cancelTask(int(task_id)) | ||||
|     except Exception: | ||||
|         if COMPOSE: | ||||
|             COMPOSE.log_warning("Failed to kill koji tasks") | ||||
| 
 | ||||
| 
 | ||||
| def sigterm_handler(signum, frame): | ||||
|     if COMPOSE: | ||||
|         try_kill_children(signum) | ||||
|         try_kill_koji_tasks() | ||||
|         COMPOSE.log_error("Compose run failed: signal %s" % signum) | ||||
|         COMPOSE.log_error("Traceback:\n%s" % "\n".join(traceback.format_stack(frame))) | ||||
|         COMPOSE.log_critical("Compose failed: %s" % COMPOSE.topdir) | ||||
|  | ||||
| @ -36,10 +36,14 @@ KOJI_BUILD_DELETED = koji.BUILD_STATES["DELETED"] | ||||
| class KojiWrapper(object): | ||||
|     lock = threading.Lock() | ||||
| 
 | ||||
|     def __init__(self, profile): | ||||
|         self.profile = profile | ||||
|     def __init__(self, compose): | ||||
|         self.compose = compose | ||||
|         try: | ||||
|             self.profile = self.compose.conf["koji_profile"] | ||||
|         except KeyError: | ||||
|             raise RuntimeError("Koji profile must be configured") | ||||
|         with self.lock: | ||||
|             self.koji_module = koji.get_profile_module(profile) | ||||
|             self.koji_module = koji.get_profile_module(self.profile) | ||||
|             session_opts = {} | ||||
|             for key in ( | ||||
|                 "timeout", | ||||
| @ -300,6 +304,8 @@ class KojiWrapper(object): | ||||
| 
 | ||||
|         task_id = int(match.groups()[0]) | ||||
| 
 | ||||
|         self.save_task_id(task_id) | ||||
| 
 | ||||
|         retcode, output = self._wait_for_task(task_id, logfile=log_file) | ||||
| 
 | ||||
|         return { | ||||
| @ -542,6 +548,8 @@ class KojiWrapper(object): | ||||
|             ) | ||||
|         task_id = int(match.groups()[0]) | ||||
| 
 | ||||
|         self.save_task_id(task_id) | ||||
| 
 | ||||
|         if retcode != 0 and ( | ||||
|             self._has_connection_error(output) or self._has_offline_error(output) | ||||
|         ): | ||||
| @ -827,13 +835,22 @@ class KojiWrapper(object): | ||||
|         """ | ||||
|         return self.multicall_map(*args, **kwargs) | ||||
| 
 | ||||
|     def save_task_id(self, task_id): | ||||
|         """Save task id by creating a file using task_id as file name | ||||
| 
 | ||||
|         :param int task_id: ID of koji task | ||||
|         """ | ||||
|         log_dir = self.compose.paths.log.koji_tasks_dir() | ||||
|         with open(os.path.join(log_dir, str(task_id)), "w"): | ||||
|             pass | ||||
| 
 | ||||
| 
 | ||||
| def get_buildroot_rpms(compose, task_id): | ||||
|     """Get build root RPMs - either from runroot or local""" | ||||
|     result = [] | ||||
|     if task_id: | ||||
|         # runroot | ||||
|         koji = KojiWrapper(compose.conf["koji_profile"]) | ||||
|         koji = KojiWrapper(compose) | ||||
|         buildroot_infos = koji.koji_proxy.listBuildroots(taskID=task_id) | ||||
|         if not buildroot_infos: | ||||
|             children_tasks = koji.koji_proxy.getTaskChildren(task_id) | ||||
|  | ||||
| @ -265,11 +265,7 @@ class RpmScmWrapper(ScmBase): | ||||
| class KojiScmWrapper(ScmBase): | ||||
|     def __init__(self, *args, **kwargs): | ||||
|         super(KojiScmWrapper, self).__init__(*args, **kwargs) | ||||
|         try: | ||||
|             profile = kwargs["compose"].conf["koji_profile"] | ||||
|         except KeyError: | ||||
|             raise RuntimeError("Koji profile must be configured") | ||||
|         wrapper = KojiWrapper(profile) | ||||
|         wrapper = KojiWrapper(kwargs["compose"]) | ||||
|         self.koji = wrapper.koji_module | ||||
|         self.proxy = wrapper.koji_proxy | ||||
| 
 | ||||
|  | ||||
| @ -171,6 +171,7 @@ class ImageContainerThreadTest(helpers.PungiTestCase): | ||||
|                     opts, | ||||
|                     priority=None, | ||||
|                 ), | ||||
|                 mock.call.save_task_id(12345), | ||||
|                 mock.call.watch_task( | ||||
|                     12345, | ||||
|                     os.path.join( | ||||
|  | ||||
| @ -10,6 +10,7 @@ except ImportError: | ||||
| import tempfile | ||||
| 
 | ||||
| import os | ||||
| import shutil | ||||
| 
 | ||||
| import six | ||||
| 
 | ||||
| @ -33,7 +34,9 @@ def mock_imagebuild_path(id): | ||||
| class KojiWrapperBaseTestCase(unittest.TestCase): | ||||
|     def setUp(self): | ||||
|         _, self.tmpfile = tempfile.mkstemp() | ||||
|         self.koji_profile = mock.Mock() | ||||
|         compose = mock.Mock(conf={"koji_profile": "custom-koji"}) | ||||
|         self.tmpdir = tempfile.mkdtemp() | ||||
|         compose.paths.log.koji_tasks_dir.return_value = self.tmpdir | ||||
|         with mock.patch("pungi.wrappers.kojiwrapper.koji") as koji: | ||||
|             koji.gssapi_login = mock.Mock() | ||||
|             koji.get_profile_module = mock.Mock( | ||||
| @ -51,10 +54,11 @@ class KojiWrapperBaseTestCase(unittest.TestCase): | ||||
|                 ) | ||||
|             ) | ||||
|             self.koji_profile = koji.get_profile_module.return_value | ||||
|             self.koji = KojiWrapper("custom-koji") | ||||
|             self.koji = KojiWrapper(compose) | ||||
| 
 | ||||
|     def tearDown(self): | ||||
|         os.remove(self.tmpfile) | ||||
|         shutil.rmtree(self.tmpdir) | ||||
| 
 | ||||
| 
 | ||||
| class KojiWrapperTest(KojiWrapperBaseTestCase): | ||||
| @ -1163,7 +1167,7 @@ class TestGetBuildrootRPMs(unittest.TestCase): | ||||
| 
 | ||||
|         rpms = get_buildroot_rpms(compose, 1234) | ||||
| 
 | ||||
|         self.assertEqual(KojiWrapper.call_args_list, [mock.call("koji")]) | ||||
|         self.assertEqual(KojiWrapper.call_args_list, [mock.call(compose)]) | ||||
|         self.assertEqual( | ||||
|             KojiWrapper.return_value.mock_calls, | ||||
|             [ | ||||
|  | ||||
| @ -220,6 +220,7 @@ class OSBSThreadTest(helpers.PungiTestCase): | ||||
|                     options, | ||||
|                     priority=None, | ||||
|                 ), | ||||
|                 mock.call.save_task_id(12345), | ||||
|                 mock.call.watch_task( | ||||
|                     12345, self.topdir + "/logs/global/osbs/Server-1-watch-task.log" | ||||
|                 ), | ||||
|  | ||||
| @ -196,6 +196,7 @@ class RunOSBuildThreadTest(helpers.PungiTestCase): | ||||
|                         "repo": [self.topdir + "/compose/Everything/$arch/os"], | ||||
|                     }, | ||||
|                 ), | ||||
|                 mock.call.save_task_id(1234), | ||||
|                 mock.call.watch_task(1234, mock.ANY), | ||||
|                 mock.call.koji_proxy.getTaskResult(1234), | ||||
|                 mock.call.koji_proxy.getBuild(build_id), | ||||
| @ -312,6 +313,7 @@ class RunOSBuildThreadTest(helpers.PungiTestCase): | ||||
|                     ["aarch64", "x86_64"], | ||||
|                     opts={"repo": [self.topdir + "/compose/Everything/$arch/os"]}, | ||||
|                 ), | ||||
|                 mock.call.save_task_id(1234), | ||||
|                 mock.call.watch_task(1234, mock.ANY), | ||||
|                 mock.call.koji_proxy.getTaskResult(1234), | ||||
|                 mock.call.koji_proxy.getBuild(build_id), | ||||
|  | ||||
| @ -446,7 +446,7 @@ class TestSourceKoji(helpers.PungiTestCase): | ||||
| 
 | ||||
|         self.assertEqual(pkgsets, gpfk.return_value) | ||||
|         self.assertEqual(path_prefix, "/prefix/") | ||||
|         self.assertEqual(KojiWrapper.mock_calls, [mock.call("koji")]) | ||||
|         self.assertEqual(KojiWrapper.mock_calls, [mock.call(compose)]) | ||||
| 
 | ||||
| 
 | ||||
| class TestCorrectNVR(helpers.PungiTestCase): | ||||
|  | ||||
| @ -588,9 +588,8 @@ class CvsSCMTestCase(SCMBaseTest): | ||||
| 
 | ||||
| 
 | ||||
| @mock.patch("pungi.wrappers.scm.urlretrieve") | ||||
| @mock.patch("pungi.wrappers.scm.KojiWrapper") | ||||
| class KojiSCMTestCase(SCMBaseTest): | ||||
|     def test_without_koji_profile(self, KW, dl): | ||||
|     def test_without_koji_profile(self, dl): | ||||
|         compose = mock.Mock(conf={}) | ||||
| 
 | ||||
|         with self.assertRaises(RuntimeError) as ctx: | ||||
| @ -600,9 +599,9 @@ class KojiSCMTestCase(SCMBaseTest): | ||||
|                 compose=compose, | ||||
|             ) | ||||
|         self.assertIn("Koji profile must be configured", str(ctx.exception)) | ||||
|         self.assertEqual(KW.mock_calls, []) | ||||
|         self.assertEqual(dl.mock_calls, []) | ||||
| 
 | ||||
|     @mock.patch("pungi.wrappers.scm.KojiWrapper") | ||||
|     def test_doesnt_get_dirs(self, KW, dl): | ||||
|         compose = mock.Mock(conf={"koji_profile": "koji"}) | ||||
| 
 | ||||
| @ -613,7 +612,7 @@ class KojiSCMTestCase(SCMBaseTest): | ||||
|                 compose=compose, | ||||
|             ) | ||||
|         self.assertIn("Only files can be exported", str(ctx.exception)) | ||||
|         self.assertEqual(KW.mock_calls, [mock.call("koji")]) | ||||
|         self.assertEqual(KW.mock_calls, [mock.call(compose)]) | ||||
|         self.assertEqual(dl.mock_calls, []) | ||||
| 
 | ||||
|     def _setup_koji_wrapper(self, KW, build_id, files): | ||||
| @ -627,6 +626,7 @@ class KojiSCMTestCase(SCMBaseTest): | ||||
|         ] | ||||
|         KW.return_value.koji_proxy.listTagged.return_value = [buildinfo] | ||||
| 
 | ||||
|     @mock.patch("pungi.wrappers.scm.KojiWrapper") | ||||
|     def test_get_from_build(self, KW, dl): | ||||
|         compose = mock.Mock(conf={"koji_profile": "koji"}) | ||||
| 
 | ||||
| @ -646,7 +646,7 @@ class KojiSCMTestCase(SCMBaseTest): | ||||
|         self.assertEqual( | ||||
|             KW.mock_calls, | ||||
|             [ | ||||
|                 mock.call("koji"), | ||||
|                 mock.call(compose), | ||||
|                 mock.call().koji_proxy.getBuild("my-build-1.0-2"), | ||||
|                 mock.call().koji_proxy.listArchives(123), | ||||
|                 mock.call().koji_module.pathinfo.typedir({"build_id": 123}, "image"), | ||||
| @ -657,6 +657,7 @@ class KojiSCMTestCase(SCMBaseTest): | ||||
|             [mock.call("http://koji.local/koji/images/abc.tar", mock.ANY)], | ||||
|         ) | ||||
| 
 | ||||
|     @mock.patch("pungi.wrappers.scm.KojiWrapper") | ||||
|     def test_get_from_latest_build(self, KW, dl): | ||||
|         compose = mock.Mock(conf={"koji_profile": "koji"}) | ||||
| 
 | ||||
| @ -676,7 +677,7 @@ class KojiSCMTestCase(SCMBaseTest): | ||||
|         self.assertEqual( | ||||
|             KW.mock_calls, | ||||
|             [ | ||||
|                 mock.call("koji"), | ||||
|                 mock.call(compose), | ||||
|                 mock.call().koji_proxy.listTagged( | ||||
|                     "images", package="my-build", inherit=True, latest=True | ||||
|                 ), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user