This also moves common koji methods into koji_utils
Fixes: T49
| tflink |
This also moves common koji methods into koji_utils
Fixes: T49
Tests included
| Lint Skipped |
| Unit Tests Skipped |
| libtaskotron/directives/koji_directive.py | ||
|---|---|---|
| 41 | What if 'tag' and 'arch' are not in `input_data`? Should that be an error condition? Raise an exception? | |
I'd like to see some small changes but it looks pretty good overall.
| libtaskotron/directives/koji_directive.py | ||
|---|---|---|
| 23–26 | This removes some of the testability that used to be in the koji directive and I can't see a good reason for doing so. Passing in a mock object for testing is generally a better method than monkeypatching. Please change the constructor back to what it was and adjust the tests accordingly | |
| 41 | We still need to rework error handling across the codebase (T85) but yeah, both 'download' and 'download_tag' should throw exceptions if input data needs aren't met. | |
| libtaskotron/koji_utils.py | ||
| 81 | I'd prefer to see this variable be something more specific than 'data'. 'koji_tag_data', 'tag_data' or something that makes it more obvious what the data is. | |
| Path | |||
|---|---|---|---|
| P | libtaskotron/directives/koji_directive.py (120 lines) Copied to libtaskotron/koji_utils.py | ||
| P | libtaskotron/koji_utils.py (74 lines) Copied from libtaskotron/directives/koji_directive.py | ||
| M | libtaskotron/runner.py (1 line) | ||
| M | testing/functest_python_directive.py (15 lines) | ||
| P | testing/test_koji_directive.py (68 lines) Copied to testing/test_koji_utils.py | ||
| P | testing/test_koji_utils.py (34 lines) Copied from testing/test_koji_directive.py |
| Commit | Tree | Parents | Author | Summary | Date |
|---|---|---|---|---|---|
| 771140324de9 | 2c17c1e9c113 | 2a5dc7b7e7b8 | Martin Krizek | Add koji download tag directive (Show More…) | Feb 20 2014, 1:02 PM |
| 1 | import koji | 1 | from libtaskotron.koji_utils import KojiClient | ||
|---|---|---|---|---|---|
| 2 | | ||||
| 3 | from libtaskotron import file_utils | | |||
| 4 | from libtaskotron.logger import log | 2 | from libtaskotron.logger import log | ||
| 5 | from libtaskotron.directives import BaseDirective | 3 | from libtaskotron.directives import BaseDirective | ||
| 6 | 4 | | |||
| 7 | directive_class = 'KojiDirective' | 5 | directive_class = 'KojiDirective' | ||
| 8 | 6 | | |||
| 9 | koji_url = 'http://koji.fedoraproject.org/kojihub' | | |||
| 10 | pkg_url = 'http://kojipkgs.fedoraproject.org/packages' | | |||
| 11 | | ||||
| 12 | | ||||
| 13 | class KojiDirective(BaseDirective): | 7 | class KojiDirective(BaseDirective): | ||
| 14 | """The koji directive interfaces with Koji to facilitate various koji actions. | 8 | """The koji directive interfaces with Koji to facilitate various koji actions. | ||
| 15 | 9 | | |||
| 16 | format: "koji: command=[download] <command args> | 10 | format: "koji: command=[download] <command args> | ||
| 17 | 11 | | |||
| 18 | Valid Commands: | 12 | Valid Commands: | ||
| 19 | 13 | | |||
| 20 | download | 14 | download | ||
| 21 | Downloads the envr specified as "envr" | 15 | Downloads the envr specified as "envr" | ||
| 22 | format: "koji: command=download envr=<envr to download> arch=<desired arch> | 16 | format: "koji: command=download envr=<envr to download> arch=<desired arch> | ||
| 17 | download_tag | ||||
| 18 | Downloads rpms tagged by "tag" | ||||
| 19 | format: "koji: command=download_tag tag=<tag to download> arch=<desired arch> | ||||
| 23 | """ | 20 | """ | ||
| 24 | 21 | | |||
| 25 | def __init__(self, koji_session=None): | 22 | def __init__(self, koji_session=None): | ||
| 26 | self.session = koji_session | 23 | if koji_session == None: | ||
| 27 | 24 | self.koji = KojiClient(koji_session) | |||
| 28 | def get_koji_session(self): | 25 | else: | ||
| 29 | if self.session == None: | 26 | self.koji = koji_session | ||
| 30 | self.session = koji.ClientSession(koji_url) | | |||
| 31 | | ||||
| 32 | return self.session | | |||
| 33 | | ||||
| 34 | def nvr_to_urls(self, nvr, arches=None, debuginfo=False, src=True): | | |||
| 35 | '''Get list of URLs for RPMs corresponding to a build. | | |||
| 36 | @param nvr build NVR | | |||
| 37 | @param arches restrict the arches of builds to provide URLs for. If | | |||
| 38 | basearch i386 is in the list, i686 arch is automatically | | |||
| 39 | added (since that's the arch Koji API uses). | | |||
| 40 | ''' | | |||
| 41 | | ||||
| 42 | ksession = self.get_koji_session() | | |||
| 43 | | ||||
| 44 | # add i686 arch if i386 is present in arches | | |||
| 45 | if arches and 'i386' in arches and 'i686' not in arches: | | |||
| 46 | arches.append('i686') | | |||
| 47 | | ||||
| 48 | info = ksession.getBuild(nvr) | | |||
| 49 | if info == None: | | |||
| 50 | raise Exception("No build information found for %s" % nvr) | | |||
| 51 | | ||||
| 52 | baseurl = '/'.join((pkg_url, info['package_name'], | | |||
| 53 | info['version'], info['release'])) | | |||
| 54 | | ||||
| 55 | rpms = ksession.listRPMs(buildID=info['id'], arches=arches) | | |||
| 56 | if not debuginfo: | | |||
| 57 | rpms = filter(lambda r: not r['name'].endswith('-debuginfo'), rpms) | | |||
| 58 | if not src: | | |||
| 59 | rpms = filter(lambda r: not r['arch'] == 'src', rpms) | | |||
| 60 | | ||||
| 61 | urls = ['%s/%s' % (baseurl, koji.pathinfo.rpm(r)) for r in rpms] | | |||
| 62 | if len(urls) == 0: | | |||
| 63 | raise Exception("NO RPMS URLS FOUND!!!") | | |||
| 64 | | ||||
| 65 | return sorted(urls) | | |||
| 66 | | ||||
| 67 | def get_nvr_rpms(self, nvr, rpm_dir, arches=None, debuginfo=False, src=False): | | |||
| 68 | '''Retrieve the RPMs associated with a build NVR into the specified | | |||
| 69 | directory. | | |||
| 70 | | ||||
| 71 | @param nvr build NVR | | |||
| 72 | @param rpm_dir location where to store the RPMs | | |||
| 73 | @return list of local filenames of the grabbed RPMs | | |||
| 74 | @raise urlgrabber.grabber.URLGrabError if downloading failed | | |||
| 75 | ''' | | |||
| 76 | | ||||
| 77 | rpm_urls = self.nvr_to_urls(nvr, | | |||
| 78 | arches=arches, | | |||
| 79 | debuginfo=debuginfo, | | |||
| 80 | src=src) | | |||
| 81 | | ||||
| 82 | rpm_files = [] | | |||
| 83 | log.info('Fetching RPMs for: %s', nvr) | | |||
| 84 | for url in rpm_urls: | | |||
| 85 | log.info(' fetching %s', url) | | |||
| 86 | rpm_file = file_utils. download(url, rpm_dir) | | |||
| 87 | rpm_files.append(rpm_file) | | |||
| 88 | | ||||
| 89 | return rpm_files | | |||
| 90 | 27 | | |||
| 91 | def process(self, input_data, env_data): | 28 | def process(self, input_data, env_data): | ||
| 92 | valid_actions = ['download'] | 29 | valid_actions = ['download', 'download_tag'] | ||
| 93 | 30 | | |||
| 94 | output_data = {} | 31 | output_data = {} | ||
| 95 | 32 | | |||
| 96 | action = input_data['action'] | 33 | action = input_data['action'] | ||
| 97 | 34 | | |||
| 98 | if not action in valid_actions: | 35 | if not action in valid_actions: | ||
| 99 | raise Exception('%s is not a valid command for koji helper' % action) | 36 | raise Exception('%s is not a valid command for koji helper' % action) | ||
| 100 | 37 | | |||
| 101 | # for now, the only valid command is download, can simplify code | | |||
| 102 | | ||||
| 103 | if action == 'download': | 38 | if action == 'download': | ||
| 104 | if 'envr' in input_data and 'arch' in input_data: | 39 | if 'envr' not in input_data or 'arch' not in input_data: | ||
| 105 | # we need to find the tmpdir and nvr from input data | 40 | # TODO T85 | ||
| 106 | tmpdir = env_data['workdir'] | 41 | detected_args = ', '.join(input_data.keys()) | ||
We still need to rework error handling across the codebase (T85) but yeah, both 'download' and 'download_tag' should throw exceptions if input data needs aren't met. | |||||
| 107 | envr = input_data['envr'] | 42 | raise Exception("The koji directive requires both 'envr' and \ | ||
| 108 | arches = [input_data['arch']] | 43 | 'arch' arguments. Detected arguments: %s" % detected_args) | ||
| 109 | 44 | | |||
| 110 | log.info("getting koji builds for %s (%s) and downloading to %s", envr, arches, tmpdir) | 45 | tmpdir = env_data['workdir'] | ||
| 111 | output_data['downloaded_rpms'] = self.get_nvr_rpms(envr, | 46 | envr = input_data['envr'] | ||
| 112 | tmpdir, | 47 | arches = [input_data['arch']] | ||
| 113 | arches) | 48 | | ||
| 49 | log.info("getting koji builds for %s (%s) and downloading to %s", envr, arches, tmpdir) | ||||
| 50 | output_data['downloaded_rpms'] = self.koji.get_nvr_rpms(envr, | ||||
| 51 | tmpdir, | ||||
| 52 | arches) | ||||
| 53 | elif action == 'download_tag': | ||||
| 54 | if 'tag' not in input_data or 'arch' not in input_data: | ||||
| 55 | # TODO T85 | ||||
| 56 | detected_args = ', '.join(input_data.keys()) | ||||
| 57 | raise Exception("The koji directive requires both 'tag' and \ | ||||
| 58 | 'arch' arguments. Detected arguments: %s" % detected_args) | ||||
| 59 | | ||||
| 60 | tmpdir = env_data['workdir'] | ||||
| 61 | tag = input_data['tag'] | ||||
| 62 | arches = [input_data['arch']] | ||||
| 63 | | ||||
| 64 | log.info("getting koji builds for tag %s and downloading to %s", tag, tmpdir) | ||||
| 65 | output_data['downloaded_rpms'] = self.koji.get_tagged_rpms(tag, tmpdir, arches) | ||||
| 114 | 66 | | |||
| 115 | return output_data | 67 | return output_data | ||
| 1 | import koji | 1 | import koji | ||
|---|---|---|---|---|---|
| 2 | 2 | | |||
| 3 | from libtaskotron import file_utils | 3 | from libtaskotron import file_utils | ||
| 4 | from libtaskotron.logger import log | 4 | from libtaskotron.logger import log | ||
| 5 | from libtaskotron.directives import BaseDirective | | |||
| 6 | 5 | | |||
| 7 | directive_class = 'KojiDirective' | 6 | KOJI_URL = 'http://koji.fedoraproject.org/kojihub' | ||
| 8 | 7 | PKG_URL = 'http://kojipkgs.fedoraproject.org/packages' | |||
| 9 | koji_url = 'http://koji.fedoraproject.org/kojihub' | | |||
| 10 | pkg_url = 'http://kojipkgs.fedoraproject.org/packages' | | |||
| 11 | | ||||
| 12 | | ||||
| 13 | class KojiDirective(BaseDirective): | | |||
| 14 | """The koji directive interfaces with Koji to facilitate various koji actions. | | |||
| 15 | | ||||
| 16 | format: "koji: command=[download] <command args> | | |||
| 17 | | ||||
| 18 | Valid Commands: | | |||
| 19 | | ||||
| 20 | download | | |||
| 21 | Downloads the envr specified as "envr" | | |||
| 22 | format: "koji: command=download envr=<envr to download> arch=<desired arch> | | |||
| 23 | """ | | |||
| 24 | 8 | | |||
| 9 | class KojiClient(object): | ||||
| 25 | def __init__(self, koji_session=None): | 10 | def __init__(self, koji_session=None): | ||
| 26 | self.session = koji_session | 11 | self.session = koji_session | ||
| 27 | 12 | | |||
| 28 | def get_koji_session(self): | 13 | def get_koji_session(self): | ||
| 29 | if self.session == None: | 14 | if self.session == None: | ||
| 30 | self.session = koji.ClientSession(koji_url) | 15 | self.session = koji.ClientSession(KOJI_URL) | ||
| 31 | 16 | | |||
| 32 | return self.session | 17 | return self.session | ||
| 33 | 18 | | |||
| 34 | def nvr_to_urls(self, nvr, arches=None, debuginfo=False, src=True): | 19 | def nvr_to_urls(self, nvr, arches=None, debuginfo=False, src=True): | ||
| 35 | '''Get list of URLs for RPMs corresponding to a build. | 20 | '''Get list of URLs for RPMs corresponding to a build. | ||
| 36 | @param nvr build NVR | 21 | @param nvr build NVR | ||
| 37 | @param arches restrict the arches of builds to provide URLs for. If | 22 | @param arches restrict the arches of builds to provide URLs for. If | ||
| 38 | basearch i386 is in the list, i686 arch is automatically | 23 | basearch i386 is in the list, i686 arch is automatically | ||
| 39 | added (since that's the arch Koji API uses). | 24 | added (since that's the arch Koji API uses). | ||
| 40 | ''' | 25 | ''' | ||
| 41 | 26 | | |||
| 27 | log.info('Querying Koji for a list of RPMS for: %s', nvr) | ||||
| 28 | | ||||
| 42 | ksession = self.get_koji_session() | 29 | ksession = self.get_koji_session() | ||
| 43 | 30 | | |||
| 44 | # add i686 arch if i386 is present in arches | 31 | # add i686 arch if i386 is present in arches | ||
| 45 | if arches and 'i386' in arches and 'i686' not in arches: | 32 | if arches and 'i386' in arches and 'i686' not in arches: | ||
| 46 | arches.append('i686') | 33 | arches.append('i686') | ||
| 47 | 34 | | |||
| 48 | info = ksession.getBuild(nvr) | 35 | info = ksession.getBuild(nvr) | ||
| 49 | if info == None: | 36 | if info == None: | ||
| 50 | raise Exception("No build information found for %s" % nvr) | 37 | raise Exception("No build information found for %s" % nvr) | ||
| 51 | 38 | | |||
| 52 | baseurl = '/'.join((pkg_url, info['package_name'], | 39 | baseurl = '/'.join((PKG_URL, info['package_name'], | ||
| 53 | info['version'], info['release'])) | 40 | info['version'], info['release'])) | ||
| 54 | 41 | | |||
| 55 | rpms = ksession.listRPMs(buildID=info['id'], arches=arches) | 42 | rpms = ksession.listRPMs(buildID=info['id'], arches=arches) | ||
| 56 | if not debuginfo: | 43 | if not debuginfo: | ||
| 57 | rpms = filter(lambda r: not r['name'].endswith('-debuginfo'), rpms) | 44 | rpms = [r for r in rpms if not r['name'].endswith('-debuginfo')] | ||
| 58 | if not src: | 45 | if not src: | ||
| 59 | rpms = filter(lambda r: not r['arch'] == 'src', rpms) | 46 | rpms = [r for r in rpms if not r['arch'] == 'src'] | ||
| 60 | 47 | | |||
| 61 | urls = ['%s/%s' % (baseurl, koji.pathinfo.rpm(r)) for r in rpms] | 48 | urls = ['%s/%s' % (baseurl, koji.pathinfo.rpm(r)) for r in rpms] | ||
| 62 | if len(urls) == 0: | 49 | if len(urls) == 0: | ||
| 63 | raise Exception("NO RPMS URLS FOUND!!!") | 50 | raise Exception("NO RPMS URLS FOUND!!!") | ||
| 64 | 51 | | |||
| 65 | return sorted(urls) | 52 | return sorted(urls) | ||
| 66 | 53 | | |||
| 67 | def get_nvr_rpms(self, nvr, rpm_dir, arches=None, debuginfo=False, src=False): | 54 | def get_nvr_rpms(self, nvr, rpm_dir, arches=None, debuginfo=False, src=False): | ||
| Show All 10 Lines | 64 | rpm_urls = self.nvr_to_urls(nvr, | |||
| 78 | arches=arches, | 65 | arches=arches, | ||
| 79 | debuginfo=debuginfo, | 66 | debuginfo=debuginfo, | ||
| 80 | src=src) | 67 | src=src) | ||
| 81 | 68 | | |||
| 82 | rpm_files = [] | 69 | rpm_files = [] | ||
| 83 | log.info('Fetching RPMs for: %s', nvr) | 70 | log.info('Fetching RPMs for: %s', nvr) | ||
| 84 | for url in rpm_urls: | 71 | for url in rpm_urls: | ||
| 85 | log.info(' fetching %s', url) | 72 | log.info(' fetching %s', url) | ||
| 86 | rpm_file = file_utils. download(url, rpm_dir) | 73 | rpm_file = file_utils.download(url, rpm_dir) | ||
| 87 | rpm_files.append(rpm_file) | 74 | rpm_files.append(rpm_file) | ||
| 88 | 75 | | |||
| 89 | return rpm_files | 76 | return rpm_files | ||
| 90 | 77 | | |||
| 91 | def process(self, input_data, env_data): | 78 | def get_tagged_rpms(self, tag, dest, arches): | ||
| 92 | valid_actions = ['download'] | 79 | ksession = self.get_koji_session() | ||
| 93 | 80 | opts = {} | |||
| 94 | output_data = {} | 81 | tag_data = ksession.listTagged(tag, **opts) | ||
| 95 | 82 | | |||
| 96 | action = input_data['action'] | 83 | nvrs = ["%(nvr)s" % x for x in tag_data] | ||
| 97 | 84 | rpms = [] | |||
| 98 | if not action in valid_actions: | 85 | for nvr in nvrs: | ||
| 99 | raise Exception('%s is not a valid command for koji helper' % action) | 86 | try: | ||
| 100 | 87 | rpms.append(self.get_nvr_rpms(nvr, dest, arches)) | |||
| 101 | # for now, the only valid command is download, can simplify code | 88 | except Exception, e: | ||
| 102 | 89 | # TODO https://phab.qadevel.cloud.fedoraproject.org/T85 | |||
| 103 | if action == 'download': | 90 | if str(e) == 'NO RPMS URLS FOUND!!!': | ||
| 104 | if 'envr' in input_data and 'arch' in input_data: | 91 | log.info('no rpms of given arch') | ||
| 105 | # we need to find the tmpdir and nvr from input data | 92 | continue | ||
| 106 | tmpdir = env_data['workdir'] | 93 | return rpms | ||
| 107 | envr = input_data['envr'] | | |||
| 108 | arches = [input_data['arch']] | | |||
| 109 | | ||||
| 110 | log.info("getting koji builds for %s (%s) and downloading to %s", envr, arches, tmpdir) | | |||
| 111 | output_data['downloaded_rpms'] = self.get_nvr_rpms(envr, | | |||
| 112 | tmpdir, | | |||
| 113 | arches) | | |||
| 114 | | ||||
| 115 | return output_data | | |||
| Show First 20 Lines • Show All 111 Lines • ▼ Show 20 Line(s) | |||||
| 112 | def get_argparser(): | 112 | def get_argparser(): | ||
| 113 | parser = argparse.ArgumentParser() | 113 | parser = argparse.ArgumentParser() | ||
| 114 | parser.add_argument("task", nargs=1, help="task to run") | 114 | parser.add_argument("task", nargs=1, help="task to run") | ||
| 115 | parser.add_argument("-a", "--arch", choices=["i386", "x86_64", "armhfp", "noarch"], help=""" | 115 | parser.add_argument("-a", "--arch", choices=["i386", "x86_64", "armhfp", "noarch"], help=""" | ||
| 116 | Architecture to be used; support arches are x86, x86_64, and armhfp. | 116 | Architecture to be used; support arches are x86, x86_64, and armhfp. | ||
| 117 | If omitted, defaults to noarch. | 117 | If omitted, defaults to noarch. | ||
| 118 | """) | 118 | """) | ||
| 119 | parser.add_argument("-e", "--envr", help="envr to be used as input") | 119 | parser.add_argument("-e", "--envr", help="envr to be used as input") | ||
| 120 | parser.add_argument("-t", "--tag", help="koji tag to be used as input") | ||||
| 120 | return parser | 121 | return parser | ||
| 121 | 122 | | |||
| 122 | def main(): | 123 | def main(): | ||
| 123 | parser = get_argparser() | 124 | parser = get_argparser() | ||
| 124 | args = parser.parse_args() | 125 | args = parser.parse_args() | ||
| 125 | 126 | | |||
| 126 | logger.init(level=logging.DEBUG) | 127 | logger.init(level=logging.DEBUG) | ||
| 127 | 128 | | |||
| Show All 10 Lines | |||||
| 1 | import os | 1 | import os | ||
|---|---|---|---|---|---|
| 2 | import copy | 2 | import copy | ||
| 3 | from libtaskotron.directives import python_directive | 3 | from libtaskotron.directives import python_directive | ||
| 4 | 4 | | |||
| 5 | 5 | | |||
| 6 | class TestTaskMethod(object): | 6 | class TestTaskMethod(object): | ||
| 7 | def setup_method(self, method): | 7 | def setup_method(self, method): | ||
| 8 | self.ref_taskyaml = 'footask.yml' | ||||
| 8 | self.ref_pyfile = 'some_loadable_test.py' | 9 | self.ref_pyfile = 'some_loadable_test.py' | ||
| 9 | self.ref_env = {'basedir': os.path.dirname(os.path.abspath(__file__))} | 10 | self.ref_env = {'taskfile': os.path.join(os.path.dirname(os.path.abspath(__file__)), self.ref_taskyaml)} | ||
| 10 | self.test_directive = python_directive.PythonDirective() | 11 | self.test_directive = python_directive.PythonDirective() | ||
| 11 | 12 | | |||
| 12 | def testfunc_task_method(self): | 13 | def testfunc_task_method(self): | ||
| 13 | ref_input = {'callable': 'task_method'} | 14 | ref_input = {'file': self.ref_pyfile, 'callable': 'task_method'} | ||
| 14 | 15 | | |||
| 15 | test_output = self.test_directive.process(self.ref_pyfile, copy.copy(ref_input), self.ref_env) | 16 | test_output = self.test_directive.process(copy.copy(ref_input), self.ref_env) | ||
| 16 | 17 | | |||
| 17 | assert test_output == "I'm a task method!" | 18 | assert test_output == "I'm a task method!" | ||
| 18 | 19 | | |||
| 19 | def testfunc_class_embedded_call(self): | 20 | def testfunc_class_embedded_call(self): | ||
| 20 | ref_input = {'callable': 'embedded_task_target'} | 21 | ref_input = {'file': self.ref_pyfile, 'callable': 'embedded_task_target'} | ||
| 21 | 22 | | |||
| 22 | test_output = self.test_directive.process(self.ref_pyfile, copy.copy(ref_input), self.ref_env) | 23 | test_output = self.test_directive.process(copy.copy(ref_input), self.ref_env) | ||
| 23 | 24 | | |||
| 24 | assert test_output == "I'm a __call__ method in a class!" | 25 | assert test_output == "I'm a __call__ method in a class!" | ||
| 25 | 26 | | |||
| 26 | def testfunc_class_target(self): | 27 | def testfunc_class_target(self): | ||
| 27 | ref_input = {'callable': 'task_class_target'} | 28 | ref_input = {'file': self.ref_pyfile, 'callable': 'task_class_target'} | ||
| 28 | 29 | | |||
| 29 | test_output = self.test_directive.process(self.ref_pyfile, copy.copy(ref_input), self.ref_env) | 30 | test_output = self.test_directive.process(copy.copy(ref_input), self.ref_env) | ||
| 30 | 31 | | |||
| 31 | assert test_output == "I'm a task class method!" | 32 | assert test_output == "I'm a task class method!" | ||
| 1 | import pytest | 1 | import pytest | ||
|---|---|---|---|---|---|
| 2 | from dingus import Dingus | 2 | from dingus import Dingus | ||
| 3 | 3 | | |||
| 4 | from libtaskotron.directives import koji_directive | 4 | from libtaskotron.directives import koji_directive | ||
| 5 | 5 | | |||
| 6 | class TestKojiDownloads(): | 6 | class TestKojiDirective(): | ||
| 7 | def setup_method(self, method): | 7 | def setup_method(self, method): | ||
| 8 | self.ref_nvr = 'foo-1.2-3.fc99' | 8 | self.ref_nvr = 'foo-1.2-3.fc99' | ||
| 9 | self.ref_arch = 'noarch' | 9 | self.ref_arch = 'noarch' | ||
| 10 | self.ref_tag = 'tagfoo' | ||||
| 10 | self.ref_name = 'foo' | 11 | self.ref_name = 'foo' | ||
| 11 | self.ref_version = '1.2' | 12 | self.ref_version = '1.2' | ||
| 12 | self.ref_release = '3.fc99' | 13 | self.ref_release = '3.fc99' | ||
| 13 | self.ref_buildid = 123456 | 14 | self.ref_buildid = 123456 | ||
| 14 | 15 | | |||
| 15 | self.ref_build = {'package_name':self.ref_name, 'version':self.ref_version, | 16 | self.ref_build = {'package_name':self.ref_name, 'version':self.ref_version, | ||
| 16 | 'release':self.ref_release, 'id': self.ref_buildid} | 17 | 'release':self.ref_release, 'id': self.ref_buildid} | ||
| 17 | 18 | | |||
| 18 | self.ref_rpms = [{'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':self.ref_arch}, | 19 | self.ref_rpms = [{'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':self.ref_arch}, | ||
| 19 | {'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':'src'}] | 20 | {'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':'src'}] | ||
| 20 | 21 | | |||
| 22 | self.ref_tagged = [{'nvr': self.ref_nvr}] | ||||
| 23 | | ||||
| 21 | self.ref_url = 'http://downloads.example.com/builds/%s.noarch.rpm' % self.ref_nvr | 24 | self.ref_url = 'http://downloads.example.com/builds/%s.noarch.rpm' % self.ref_nvr | ||
| 22 | self.helper = koji_directive.KojiDirective() | 25 | self.helper = koji_directive.KojiDirective() | ||
| 23 | 26 | | |||
| 24 | def test_get_noarch_rpmurls_from_nvr(self): | 27 | def test_parse_download_command(self): | ||
| 25 | stub_koji = Dingus(getBuild__returns = self.ref_build, listRPMs__returns = self.ref_rpms) | 28 | self.ref_rpms = ['/var/tmp/fake/%s.%s.rpm' % (self.ref_nvr, self.ref_arch)] | ||
| 26 | | ||||
| 27 | test_koji = koji_directive.KojiDirective(stub_koji) | | |||
| 28 | | ||||
| 29 | test_urls = test_koji.nvr_to_urls(self.ref_nvr) | | |||
| 30 | | ||||
| 31 | koji_baseurl = koji_directive.pkg_url | | |||
| 32 | ref_urls = ['%s/%s/%s/%s/%s/%s.%s.rpm' % (koji_baseurl, self.ref_name, self.ref_version, self.ref_release, self.ref_arch, self.ref_nvr, self.ref_arch), | | |||
| 33 | '%s/%s/%s/%s/src/%s.src.rpm' % (koji_baseurl, self.ref_name, self.ref_version, self.ref_release, self.ref_nvr), | | |||
| 34 | ] | | |||
| 35 | | ||||
| 36 | assert test_urls == ref_urls | | |||
| 37 | | ||||
| 38 | def should_i386_rpmurls_query_i686(self): | | |||
| 39 | self.ref_arch = 'i386' | | |||
| 40 | | ||||
| 41 | stub_koji = Dingus(getBuild__returns = self.ref_build) | | |||
| 42 | | ||||
| 43 | test_koji = koji_directive.KojiDirective(stub_koji) | | |||
| 44 | | ||||
| 45 | # this isn't setup to actually return urls since we don't care about that for this test | | |||
| 46 | # it should throw an exception in this case. | | |||
| 47 | try: | | |||
| 48 | test_koji.nvr_to_urls(self.ref_nvr, arches = [self.ref_arch]) | | |||
| 49 | except Exception: | | |||
| 50 | pass | | |||
| 51 | 29 | | |||
| 52 | listrpm_calls = stub_koji.calls('listRPMs') | | |||
| 53 | requested_arches = listrpm_calls[0][2]['arches'] | | |||
| 54 | | ||||
| 55 | assert 'i686' in requested_arches | | |||
| 56 | assert 'i386' in requested_arches | | |||
| 57 | | ||||
| 58 | def test_parse_download_command(self, monkeypatch): | | |||
| 59 | ref_input = {'action': 'download', 'arch': self.ref_arch, 'envr': self.ref_nvr} | 30 | ref_input = {'action': 'download', 'arch': self.ref_arch, 'envr': self.ref_nvr} | ||
| 60 | ref_envdata = {'workdir':'/var/tmp/foo'} | 31 | ref_envdata = {'workdir':'/var/tmp/foo'} | ||
| 61 | 32 | | |||
| 62 | stub_koji = Dingus(getBuild__returns = self.ref_build, listRPMs__returns = self.ref_rpms) | 33 | stub_koji = Dingus(get_nvr_rpms__returns = self.ref_rpms) | ||
| 63 | ref_rpms = ['/var/tmp/fake/%s.%s.rpm' % (self.ref_nvr, self.ref_arch)] | | |||
| 64 | 34 | | |||
| 65 | stub_get_rpms = Dingus(get_nvr_rpms__returns=ref_rpms) | | |||
| 66 | test_helper = koji_directive.KojiDirective(stub_koji) | 35 | test_helper = koji_directive.KojiDirective(stub_koji) | ||
| 67 | 36 | | |||
| 68 | monkeypatch.setattr(test_helper, 'get_nvr_rpms', stub_get_rpms) | | |||
| 69 | test_helper.process(ref_input, ref_envdata) | 37 | test_helper.process(ref_input, ref_envdata) | ||
| 70 | 38 | | |||
| 71 | getrpm_calls = stub_get_rpms.calls() | 39 | getrpm_calls = stub_koji.calls() | ||
| 72 | print getrpm_calls | | |||
| 73 | requested_nvr = getrpm_calls[0][1][0] | 40 | requested_nvr = getrpm_calls[0][1][0] | ||
| 74 | 41 | | |||
| 75 | assert len(getrpm_calls) == 1 | 42 | assert len(getrpm_calls) == 1 | ||
| 76 | assert requested_nvr == self.ref_nvr | 43 | assert requested_nvr == self.ref_nvr | ||
| 77 | 44 | | |||
| 78 | def should_throw_exception_norpms(self): | 45 | def test_parse_download_tag_command(self): | ||
| 79 | stub_koji = Dingus(getBuild__returns = self.ref_build) | 46 | self.ref_rpms = ['/var/tmp/fake/%s.%s.rpm' % (self.ref_nvr, self.ref_arch)] | ||
| 80 | 47 | | |||
| 81 | test_koji = koji_directive.KojiDirective(stub_koji) | 48 | ref_input = {'action': 'download_tag', 'arch': self.ref_arch, 'tag': self.ref_tag} | ||
| 49 | ref_envdata = {'workdir':'/var/tmp/foo'} | ||||
| 82 | 50 | | |||
| 83 | with pytest.raises(Exception): | 51 | stub_koji = Dingus(get_tagged_rpms__returns=self.ref_rpms) | ||
| 84 | test_koji.nvr_to_urls(self.ref_nvr, arches = [self.ref_arch]) | 52 | | ||
| 53 | test_helper = koji_directive.KojiDirective(stub_koji) | ||||
| 85 | 54 | | |||
| 55 | test_helper.process(ref_input, ref_envdata) | ||||
| 56 | | ||||
| 57 | getrpm_calls = stub_koji.calls() | ||||
| 58 | requested_tag = getrpm_calls[0][1][0] | ||||
| 59 | | ||||
| 60 | assert len(getrpm_calls) == 1 | ||||
| 61 | assert requested_tag == self.ref_tag | ||||
| 1 | import pytest | 1 | import pytest | ||
|---|---|---|---|---|---|
| 2 | from dingus import Dingus | 2 | from dingus import Dingus | ||
| 3 | 3 | | |||
| 4 | from libtaskotron.directives import koji_directive | 4 | from libtaskotron import koji_utils | ||
| 5 | 5 | | |||
| 6 | class TestKojiDownloads(): | 6 | class TestKojiClient(): | ||
| 7 | def setup_method(self, method): | 7 | def setup_method(self, method): | ||
| 8 | self.ref_nvr = 'foo-1.2-3.fc99' | 8 | self.ref_nvr = 'foo-1.2-3.fc99' | ||
| 9 | self.ref_arch = 'noarch' | 9 | self.ref_arch = 'noarch' | ||
| 10 | self.ref_name = 'foo' | 10 | self.ref_name = 'foo' | ||
| 11 | self.ref_version = '1.2' | 11 | self.ref_version = '1.2' | ||
| 12 | self.ref_release = '3.fc99' | 12 | self.ref_release = '3.fc99' | ||
| 13 | self.ref_buildid = 123456 | 13 | self.ref_buildid = 123456 | ||
| 14 | 14 | | |||
| 15 | self.ref_build = {'package_name':self.ref_name, 'version':self.ref_version, | 15 | self.ref_build = {'package_name':self.ref_name, 'version':self.ref_version, | ||
| 16 | 'release':self.ref_release, 'id': self.ref_buildid} | 16 | 'release':self.ref_release, 'id': self.ref_buildid} | ||
| 17 | 17 | | |||
| 18 | self.ref_rpms = [{'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':self.ref_arch}, | 18 | self.ref_rpms = [{'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':self.ref_arch}, | ||
| 19 | {'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':'src'}] | 19 | {'name':self.ref_name, 'version':self.ref_version, 'release':self.ref_release, 'nvr':self.ref_nvr, 'arch':'src'}] | ||
| 20 | 20 | | |||
| 21 | self.ref_url = 'http://downloads.example.com/builds/%s.noarch.rpm' % self.ref_nvr | 21 | self.ref_url = 'http://downloads.example.com/builds/%s.noarch.rpm' % self.ref_nvr | ||
| 22 | self.helper = koji_directive.KojiDirective() | 22 | self.helper = koji_utils.KojiClient() | ||
| 23 | 23 | | |||
| 24 | def test_get_noarch_rpmurls_from_nvr(self): | 24 | def test_get_noarch_rpmurls_from_nvr(self): | ||
| 25 | stub_koji = Dingus(getBuild__returns = self.ref_build, listRPMs__returns = self.ref_rpms) | 25 | stub_koji = Dingus(getBuild__returns = self.ref_build, listRPMs__returns = self.ref_rpms) | ||
| 26 | 26 | | |||
| 27 | test_koji = koji_directive.KojiDirective(stub_koji) | 27 | test_koji = koji_utils.KojiClient(stub_koji) | ||
| 28 | 28 | | |||
| 29 | test_urls = test_koji.nvr_to_urls(self.ref_nvr) | 29 | test_urls = test_koji.nvr_to_urls(self.ref_nvr) | ||
| 30 | 30 | | |||
| 31 | koji_baseurl = koji_directive.pkg_url | 31 | koji_baseurl = koji_utils.PKG_URL | ||
| 32 | ref_urls = ['%s/%s/%s/%s/%s/%s.%s.rpm' % (koji_baseurl, self.ref_name, self.ref_version, self.ref_release, self.ref_arch, self.ref_nvr, self.ref_arch), | 32 | ref_urls = ['%s/%s/%s/%s/%s/%s.%s.rpm' % (koji_baseurl, self.ref_name, self.ref_version, self.ref_release, self.ref_arch, self.ref_nvr, self.ref_arch), | ||
| 33 | '%s/%s/%s/%s/src/%s.src.rpm' % (koji_baseurl, self.ref_name, self.ref_version, self.ref_release, self.ref_nvr), | 33 | '%s/%s/%s/%s/src/%s.src.rpm' % (koji_baseurl, self.ref_name, self.ref_version, self.ref_release, self.ref_nvr), | ||
| 34 | ] | 34 | ] | ||
| 35 | 35 | | |||
| 36 | assert test_urls == ref_urls | 36 | assert test_urls == ref_urls | ||
| 37 | 37 | | |||
| 38 | def should_i386_rpmurls_query_i686(self): | 38 | def should_i386_rpmurls_query_i686(self): | ||
| 39 | self.ref_arch = 'i386' | 39 | self.ref_arch = 'i386' | ||
| 40 | 40 | | |||
| 41 | stub_koji = Dingus(getBuild__returns = self.ref_build) | 41 | stub_koji = Dingus(getBuild__returns = self.ref_build) | ||
| 42 | 42 | | |||
| 43 | test_koji = koji_directive.KojiDirective(stub_koji) | 43 | test_koji = koji_utils.KojiClient(stub_koji) | ||
| 44 | 44 | | |||
| 45 | # this isn't setup to actually return urls since we don't care about that for this test | 45 | # this isn't setup to actually return urls since we don't care about that for this test | ||
| 46 | # it should throw an exception in this case. | 46 | # it should throw an exception in this case. | ||
| 47 | try: | 47 | try: | ||
| 48 | test_koji.nvr_to_urls(self.ref_nvr, arches = [self.ref_arch]) | 48 | test_koji.nvr_to_urls(self.ref_nvr, arches = [self.ref_arch]) | ||
| 49 | except Exception: | 49 | except Exception: | ||
| 50 | pass | 50 | pass | ||
| 51 | 51 | | |||
| 52 | listrpm_calls = stub_koji.calls('listRPMs') | 52 | listrpm_calls = stub_koji.calls('listRPMs') | ||
| 53 | requested_arches = listrpm_calls[0][2]['arches'] | 53 | requested_arches = listrpm_calls[0][2]['arches'] | ||
| 54 | 54 | | |||
| 55 | assert 'i686' in requested_arches | 55 | assert 'i686' in requested_arches | ||
| 56 | assert 'i386' in requested_arches | 56 | assert 'i386' in requested_arches | ||
| 57 | 57 | | |||
| 58 | def test_parse_download_command(self, monkeypatch): | | |||
| 59 | ref_input = {'action': 'download', 'arch': self.ref_arch, 'envr': self.ref_nvr} | | |||
| 60 | ref_envdata = {'workdir':'/var/tmp/foo'} | | |||
| 61 | | ||||
| 62 | stub_koji = Dingus(getBuild__returns = self.ref_build, listRPMs__returns = self.ref_rpms) | | |||
| 63 | ref_rpms = ['/var/tmp/fake/%s.%s.rpm' % (self.ref_nvr, self.ref_arch)] | | |||
| 64 | | ||||
| 65 | stub_get_rpms = Dingus(get_nvr_rpms__returns=ref_rpms) | | |||
| 66 | test_helper = koji_directive.KojiDirective(stub_koji) | | |||
| 67 | | ||||
| 68 | monkeypatch.setattr(test_helper, 'get_nvr_rpms', stub_get_rpms) | | |||
| 69 | test_helper.process(ref_input, ref_envdata) | | |||
| 70 | | ||||
| 71 | getrpm_calls = stub_get_rpms.calls() | | |||
| 72 | print getrpm_calls | | |||
| 73 | requested_nvr = getrpm_calls[0][1][0] | | |||
| 74 | | ||||
| 75 | assert len(getrpm_calls) == 1 | | |||
| 76 | assert requested_nvr == self.ref_nvr | | |||
| 77 | | ||||
| 78 | def should_throw_exception_norpms(self): | 58 | def should_throw_exception_norpms(self): | ||
| 79 | stub_koji = Dingus(getBuild__returns = self.ref_build) | 59 | stub_koji = Dingus(getBuild__returns = self.ref_build) | ||
| 80 | 60 | | |||
| 81 | test_koji = koji_directive.KojiDirective(stub_koji) | 61 | test_koji = koji_utils.KojiClient(stub_koji) | ||
| 82 | 62 | | |||
| 83 | with pytest.raises(Exception): | 63 | with pytest.raises(Exception): | ||
| 84 | test_koji.nvr_to_urls(self.ref_nvr, arches = [self.ref_arch]) | 64 | test_koji.nvr_to_urls(self.ref_nvr, arches = [self.ref_arch]) | ||
| 85 | 65 | | |||
This removes some of the testability that used to be in the koji directive and I can't see a good reason for doing so. Passing in a mock object for testing is generally a better method than monkeypatching. Please change the constructor back to what it was and adjust the tests accordingly