diff --git a/bugzilla2fedmsg/relay.py b/bugzilla2fedmsg/relay.py index a649810..f5dba0c 100644 --- a/bugzilla2fedmsg/relay.py +++ b/bugzilla2fedmsg/relay.py @@ -3,11 +3,12 @@ import pytz from bugzilla2fedmsg_schema import MessageV1, MessageV1BZ4 +from fasjson_client import Client as FasjsonClient from fedora_messaging.api import publish from fedora_messaging.exceptions import ConnectionException, PublishReturned from fedora_messaging.message import INFO -from .utils import convert_datetimes +from .utils import convert_datetimes, email_to_fas LOGGER = logging.getLogger(__name__) @@ -42,13 +43,49 @@ def _bz4_compat_transform(bug, event, objdict, obj): objdict[obj]["author"] = event.get("user", {}).get("login", "") +class DropMessage(Exception): + def __init__(self, message): + self.message = message + + def __str__(self): + return self.message + + class MessageRelay: def __init__(self, config): self.config = config self._allowed_products = self.config.get("bugzilla", {}).get("products", []) self._bz4_compat_mode = self.config.get("bugzilla", {}).get("bz4compat", True) + self._fasjson = FasjsonClient(self.config["fasjson_url"]) def on_stomp_message(self, body, headers): + try: + message_body = self._get_message_body(body, headers) + except DropMessage as e: + LOGGER.debug(f"DROP: {e}") + return + + topic = "bug.update" + if "bug.create" in headers["destination"]: + topic = "bug.new" + + LOGGER.debug("Republishing #%s", message_body["bug"]["id"]) + messageclass = MessageV1 + if self._bz4_compat_mode: + messageclass = MessageV1BZ4 + try: + message = messageclass( + topic=f"bugzilla.{topic}", + body=message_body, + severity=INFO, + ) + publish(message) + except PublishReturned as e: + LOGGER.warning(f"Fedora Messaging broker rejected message {message.id}: {e}") + except ConnectionException as e: + LOGGER.warning(f"Error sending message {message.id}: {e}") + + def _get_message_body(self, body, headers): # in BZ 5.0+, public messages include a key for the 'object', # whatever the object is. So 'bug.*' messages have a 'bug' # dict...but 'comment.*' messages have a 'comment' dict, @@ -61,8 +98,7 @@ def on_stomp_message(self, body, headers): # this splits out the 'bug' part obj = headers["destination"].split("bugzilla.")[1].split(".")[0] if obj not in body: - LOGGER.debug("DROP: message has no object field. Non public.") - return + raise DropMessage("message has no object field. Non public.") objdict = {} bug = None if obj == "bug": @@ -78,8 +114,7 @@ def on_stomp_message(self, body, headers): # it. product_name = bug["product"]["name"] if product_name not in self._allowed_products: - LOGGER.debug("DROP: %r not in %r", product_name, self._allowed_products) - return + raise DropMessage(f"{product_name!r} not in {self._allowed_products}") body["timestamp"] = datetime.datetime.fromtimestamp( int(headers["timestamp"]) / 1000.0, pytz.UTC @@ -90,31 +125,63 @@ def on_stomp_message(self, body, headers): if self._bz4_compat_mode: _bz4_compat_transform(bug, event, objdict, obj) - topic = "bug.update" - if "bug.create" in headers["destination"]: - topic = "bug.new" - # construct message dict, add the object dict we got earlier # (for non-'bug' object messages) - body = dict( - bug=bug, - event=event, - headers=headers, - ) + body = dict(bug=bug, event=event, headers=headers) body.update(objdict) - LOGGER.debug("Republishing #%s", bug["id"]) - messageclass = MessageV1 + # user from the event dict: person who triggered the event + agent_name = email_to_fas(event["user"]["login"], self._fasjson) + body["agent_name"] = agent_name + + # usernames: all FAS usernames affected by the action + all_emails = self._get_all_emails(body) + usernames = set() + for email in all_emails: + username = email_to_fas(email, self._fasjson) + if username is None: + continue + usernames.add(username) + if agent_name is not None: + usernames.add(agent_name) + usernames = list(usernames) + usernames.sort() + body["usernames"] = usernames + + return body + + def _get_all_emails(self, body): + """List of email addresses of all users relevant to the action + that generated this message. + """ + emails = set() + + # bug reporter and assignee + emails.add(body["bug"]["reporter"]["login"]) if self._bz4_compat_mode: - messageclass = MessageV1BZ4 - try: - message = messageclass( - topic=f"bugzilla.{topic}", - body=body, - severity=INFO, - ) - publish(message) - except PublishReturned as e: - LOGGER.warning(f"Fedora Messaging broker rejected message {message.id}: {e}") - except ConnectionException as e: - LOGGER.warning(f"Error sending message {message.id}: {e}") + emails.add(body["bug"]["assigned_to"]) + else: + emails.add(body["bug"]["assigned_to"]["login"]) + + for change in body["event"].get("changes", []): + if change["field"] == "cc": + # anyone added to CC list + for email in change["added"].split(","): + email.strip() + if email: + emails.add(email) + elif change["field"] == "flag.needinfo": + # anyone for whom a 'needinfo' flag is set + # this is extracting the email from a value like: + # "? (senrique@redhat.com)" + email = change["added"].split("(", 1)[1].rsplit(")", 1)[0] + if email: + emails.add(email) + + # Strip anything that made it in erroneously + for email in list(emails): + if email.endswith("lists.fedoraproject.org"): + emails.remove(email) + + emails = list(emails) + return emails diff --git a/bugzilla2fedmsg/utils.py b/bugzilla2fedmsg/utils.py index 14cc510..d94d6f2 100644 --- a/bugzilla2fedmsg/utils.py +++ b/bugzilla2fedmsg/utils.py @@ -35,3 +35,13 @@ def convert_datetimes(obj): return ourdate.timestamp() except (ValueError, TypeError): return obj + + +def email_to_fas(email, fasjson): + """Try to get a FAS username from an email address, return None if no FAS username is found""" + if email.endswith("@fedoraproject.org"): + return email.rsplit("@", 1)[0] + results = fasjson.search(rhbzemail=email).result + if len(results) == 1: + return results[0]["username"] + return None diff --git a/devel/ansible/roles/dev/files/config.toml b/devel/ansible/roles/dev/files/config.toml index 0b9681b..ae36a9c 100644 --- a/devel/ansible/roles/dev/files/config.toml +++ b/devel/ansible/roles/dev/files/config.toml @@ -10,6 +10,8 @@ amqp_url = "amqp://" # certfile = "/my/client/cert.pem" [consumer_config] + fasjson_url = "https://fasjson.tinystage.test" + [consumer_config.stomp] # Broker URI # http://nikipore.github.io/stompest/protocol.html#stompest.protocol.failover.StompFailoverUri diff --git a/fedora-messaging.toml.example b/fedora-messaging.toml.example index cd69827..419dc7a 100644 --- a/fedora-messaging.toml.example +++ b/fedora-messaging.toml.example @@ -10,6 +10,7 @@ keyfile = "/my/client/key.pem" certfile = "/my/client/cert.pem" [consumer_config] + fasjson_url = "https://fasjson.fedoraproject.org" [consumer_config.stomp] # Broker URI # http://nikipore.github.io/stompest/protocol.html#stompest.protocol.failover.StompFailoverUri diff --git a/poetry.lock b/poetry.lock index 431ba2f..f30bee1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,24 @@ # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + [[package]] name = "attrs" version = "23.2.0" @@ -94,6 +113,54 @@ files = [ {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, ] +[[package]] +name = "bravado" +version = "11.0.3" +description = "Library for accessing Swagger-enabled API's" +optional = false +python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,!=3.5.0" +files = [ + {file = "bravado-11.0.3-py2.py3-none-any.whl", hash = "sha256:8ac8bbb645e49607917a5c07808116c708521f51e80d9c29bc4a168ff4dd22c6"}, + {file = "bravado-11.0.3.tar.gz", hash = "sha256:1bb6ef75d84140c851fffe6420baaee5037d840070cfe11d60913be6ab8e0530"}, +] + +[package.dependencies] +bravado-core = ">=5.16.1" +monotonic = "*" +msgpack = "*" +python-dateutil = "*" +pyyaml = "*" +requests = ">=2.17" +simplejson = "*" +six = "*" +typing-extensions = "*" + +[package.extras] +fido = ["fido (>=4.2.1)"] +integration-tests = ["bottle", "ephemeral-port-reserve", "pytest"] + +[[package]] +name = "bravado-core" +version = "6.1.1" +description = "Library for adding Swagger support to clients and servers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "bravado-core-6.1.1.tar.gz", hash = "sha256:8cf1f7bbac2f7c696d37e970253938b5be4ddec92c8d5e64400b17469c3714b4"}, +] + +[package.dependencies] +jsonref = "*" +jsonschema = {version = ">=2.5.1", extras = ["format-nongpl"]} +msgpack = ">=0.5.2" +python-dateutil = "*" +pytz = "*" +pyyaml = "*" +requests = "*" +simplejson = "*" +six = "*" +swagger-spec-validator = ">=2.0.1" + [[package]] name = "bugzilla2fedmsg-schema" version = "1.0.0" @@ -108,6 +175,17 @@ files = [ [package.dependencies] fedora-messaging = ">=3.2.0,<4.0.0" +[[package]] +name = "certifi" +version = "2024.6.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, +] + [[package]] name = "cffi" version = "1.16.0" @@ -194,6 +272,105 @@ files = [ {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, ] +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + [[package]] name = "click" version = "8.1.7" @@ -366,6 +543,17 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + [[package]] name = "diff-cover" version = "9.0.0" @@ -411,6 +599,27 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "fasjson-client" +version = "1.0.8" +description = "An OpenAPI client for FASJSON" +optional = false +python-versions = ">=3.7.0,<4.0.0" +files = [ + {file = "fasjson-client-1.0.8.tar.gz", hash = "sha256:51dea1b809c6ff68f6ebd565e91e39447b2a0c48ef8bd3832fef9bae5f9ff6d6"}, + {file = "fasjson_client-1.0.8-py3-none-any.whl", hash = "sha256:2e47188963db3c04abf6ba24188b643aa3254a02b13ac814fdade6964a8b2521"}, +] + +[package.dependencies] +bravado = ">=10.6.0,<12" +gssapi = ">=1.5.1,<2.0.0" +requests = ">=2.20.0,<3.0.0" +requests-gssapi = ">=1.2.1,<2.0.0" +toml = ">=0.10.0,<0.11.0" + +[package.extras] +cli = ["click (>=6.7,<9)", "cryptography (>=2.3)"] + [[package]] name = "fedora-messaging" version = "3.5.0" @@ -450,6 +659,53 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1 testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] typing = ["typing-extensions (>=4.8)"] +[[package]] +name = "fqdn" +version = "1.5.1" +description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" +optional = false +python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" +files = [ + {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, + {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, +] + +[[package]] +name = "gssapi" +version = "1.8.3" +description = "Python GSSAPI Wrapper" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gssapi-1.8.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4e4a83e9b275fe69b5d40be6d5479889866b80333a12c51a9243f2712d4f0554"}, + {file = "gssapi-1.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8d57d67547e18f4e44a688bfb20abbf176d1b8df547da2b31c3f2df03cfdc269"}, + {file = "gssapi-1.8.3-cp310-cp310-win32.whl", hash = "sha256:3a3f63105f39c4af29ffc8f7b6542053d87fe9d63010c689dd9a9f5571facb8e"}, + {file = "gssapi-1.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:b031c0f186ab4275186da385b2c7470dd47c9b27522cb3b753757c9ac4bebf11"}, + {file = "gssapi-1.8.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b03d6b30f1fcd66d9a688b45a97e302e4dd3f1386d5c333442731aec73cdb409"}, + {file = "gssapi-1.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ca6ceb17fc15eda2a69f2e8c6cf10d11e2edb32832255e5d4c65b21b6db4680a"}, + {file = "gssapi-1.8.3-cp311-cp311-win32.whl", hash = "sha256:edc8ef3a9e397dbe18bb6016f8e2209969677b534316d20bb139da2865a38efe"}, + {file = "gssapi-1.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:8fdb1ff130cee49bc865ec1624dee8cf445cd6c6e93b04bffef2c6f363a60cb9"}, + {file = "gssapi-1.8.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:19c373b3ba63ce19cd3163aa1495635e3d01b0de6cc4ff1126095eded1df6e01"}, + {file = "gssapi-1.8.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37f1a8046d695f2c9b8d640a6e385780d3945c0741571ed6fee6f94c31e431dc"}, + {file = "gssapi-1.8.3-cp312-cp312-win32.whl", hash = "sha256:338db18612e3e6ed64e92b6d849242a535fdc98b365f21122992fb8cae737617"}, + {file = "gssapi-1.8.3-cp312-cp312-win_amd64.whl", hash = "sha256:5731c5b40ecc3116cfe7fb7e1d1e128583ec8b3df1e68bf8cd12073160793acd"}, + {file = "gssapi-1.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e556878da197ad115a566d36e46a8082d0079731d9c24d1ace795132d725ff2a"}, + {file = "gssapi-1.8.3-cp37-cp37m-win32.whl", hash = "sha256:e2bb081f2db2111377effe7d40ba23f9a87359b9d2f4881552b731e9da88b36b"}, + {file = "gssapi-1.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4d9ed83f2064cda60aad90e6840ae282096801b2c814b8cbd390bf0df4635aab"}, + {file = "gssapi-1.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7d91fe6e2a5c89b32102ea8e374b8ae13b9031d43d7b55f3abc1f194ddce820d"}, + {file = "gssapi-1.8.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d5b28237afc0668046934792756dd4b6b7e957b0d95a608d02f296734a2819ad"}, + {file = "gssapi-1.8.3-cp38-cp38-win32.whl", hash = "sha256:791e44f7bea602b8e3da1ec56fbdb383b8ee3326fdeb736f904c2aa9af13a67d"}, + {file = "gssapi-1.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:5b4bf84d0a6d7779a4bf11dacfd3db57ae02dd53562e2aeadac4219a68eaee07"}, + {file = "gssapi-1.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e40efc88ccefefd6142f8c47b8af498731938958b808bad49990442a91f45160"}, + {file = "gssapi-1.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee74b9211c977b9181ff4652d886d7712c9a221560752a35393b58e5ea07887a"}, + {file = "gssapi-1.8.3-cp39-cp39-win32.whl", hash = "sha256:465c6788f2ac6ef7c738394ba8fde1ede6004e5721766f386add63891d8c90af"}, + {file = "gssapi-1.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:8fb8ee70458f47b51ed881a6881f30b187c987c02af16cc0fff0079255d4d465"}, + {file = "gssapi-1.8.3.tar.gz", hash = "sha256:aa3c8d0b1526f52559552bb2c9d2d6be013d76a8e5db00b39a1db5727e93b0b0"}, +] + +[package.dependencies] +decorator = "*" + [[package]] name = "hyperlink" version = "21.0.0" @@ -515,6 +771,20 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "isoduration" +version = "20.11.0" +description = "Operations with ISO 8601 durations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, + {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, +] + +[package.dependencies] +arrow = ">=0.15.0" + [[package]] name = "jinja2" version = "3.1.4" @@ -532,6 +802,28 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "jsonref" +version = "1.1.0" +description = "jsonref is a library for automatic dereferencing of JSON Reference objects for Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonref-1.1.0-py3-none-any.whl", hash = "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9"}, + {file = "jsonref-1.1.0.tar.gz", hash = "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552"}, +] + [[package]] name = "jsonschema" version = "4.22.0" @@ -545,9 +837,17 @@ files = [ [package.dependencies] attrs = ">=22.2.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} jsonschema-specifications = ">=2023.03.6" referencing = ">=0.28.4" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} rpds-py = ">=0.7.1" +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -651,6 +951,82 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "monotonic" +version = "1.6" +description = "An implementation of time.monotonic() for Python 2 & < 3.3" +optional = false +python-versions = "*" +files = [ + {file = "monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c"}, + {file = "monotonic-1.6.tar.gz", hash = "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7"}, +] + +[[package]] +name = "msgpack" +version = "1.0.8" +description = "MessagePack serializer" +optional = false +python-versions = ">=3.8" +files = [ + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, +] + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -984,6 +1360,70 @@ files = [ attrs = ">=22.2.0" rpds-py = ">=0.7.0" +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-gssapi" +version = "1.3.0" +description = "A GSSAPI authentication handler for python-requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-gssapi-1.3.0.tar.gz", hash = "sha256:4d52bf8c2aa2a829130efcca85c14943fdd0aa75455aab985b2b8726159c20ca"}, + {file = "requests_gssapi-1.3.0-py3-none-any.whl", hash = "sha256:f36303cd989c54d54630c30f1ef73d7e23acdede2285c941631192e51b4da418"}, +] + +[package.dependencies] +gssapi = "*" +requests = ">=1.1.0" + +[package.extras] +dev = ["black (==24.2.0)", "isort (==5.13.2)", "pytest", "tox (>=4.0.0)"] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] + [[package]] name = "rpds-py" version = "0.18.1" @@ -1172,6 +1612,113 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "simplejson" +version = "3.19.2" +description = "Simple, fast, extensible JSON encoder/decoder for Python" +optional = false +python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "simplejson-3.19.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3471e95110dcaf901db16063b2e40fb394f8a9e99b3fe9ee3acc6f6ef72183a2"}, + {file = "simplejson-3.19.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3194cd0d2c959062b94094c0a9f8780ffd38417a5322450a0db0ca1a23e7fbd2"}, + {file = "simplejson-3.19.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:8a390e56a7963e3946ff2049ee1eb218380e87c8a0e7608f7f8790ba19390867"}, + {file = "simplejson-3.19.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1537b3dd62d8aae644f3518c407aa8469e3fd0f179cdf86c5992792713ed717a"}, + {file = "simplejson-3.19.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a8617625369d2d03766413bff9e64310feafc9fc4f0ad2b902136f1a5cd8c6b0"}, + {file = "simplejson-3.19.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:2c433a412e96afb9a3ce36fa96c8e61a757af53e9c9192c97392f72871e18e69"}, + {file = "simplejson-3.19.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f1c70249b15e4ce1a7d5340c97670a95f305ca79f376887759b43bb33288c973"}, + {file = "simplejson-3.19.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:287e39ba24e141b046812c880f4619d0ca9e617235d74abc27267194fc0c7835"}, + {file = "simplejson-3.19.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6f0a0b41dd05eefab547576bed0cf066595f3b20b083956b1405a6f17d1be6ad"}, + {file = "simplejson-3.19.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f98d918f7f3aaf4b91f2b08c0c92b1774aea113334f7cde4fe40e777114dbe6"}, + {file = "simplejson-3.19.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d74beca677623481810c7052926365d5f07393c72cbf62d6cce29991b676402"}, + {file = "simplejson-3.19.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f2398361508c560d0bf1773af19e9fe644e218f2a814a02210ac2c97ad70db0"}, + {file = "simplejson-3.19.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ad331349b0b9ca6da86064a3599c425c7a21cd41616e175ddba0866da32df48"}, + {file = "simplejson-3.19.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:332c848f02d71a649272b3f1feccacb7e4f7e6de4a2e6dc70a32645326f3d428"}, + {file = "simplejson-3.19.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25785d038281cd106c0d91a68b9930049b6464288cea59ba95b35ee37c2d23a5"}, + {file = "simplejson-3.19.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18955c1da6fc39d957adfa346f75226246b6569e096ac9e40f67d102278c3bcb"}, + {file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:11cc3afd8160d44582543838b7e4f9aa5e97865322844b75d51bf4e0e413bb3e"}, + {file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b01fda3e95d07a6148702a641e5e293b6da7863f8bc9b967f62db9461330562c"}, + {file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:778331444917108fa8441f59af45886270d33ce8a23bfc4f9b192c0b2ecef1b3"}, + {file = "simplejson-3.19.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9eb117db8d7ed733a7317c4215c35993b815bf6aeab67523f1f11e108c040672"}, + {file = "simplejson-3.19.2-cp310-cp310-win32.whl", hash = "sha256:39b6d79f5cbfa3eb63a869639cfacf7c41d753c64f7801efc72692c1b2637ac7"}, + {file = "simplejson-3.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:5675e9d8eeef0aa06093c1ff898413ade042d73dc920a03e8cea2fb68f62445a"}, + {file = "simplejson-3.19.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed628c1431100b0b65387419551e822987396bee3c088a15d68446d92f554e0c"}, + {file = "simplejson-3.19.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:adcb3332979cbc941b8fff07181f06d2b608625edc0a4d8bc3ffc0be414ad0c4"}, + {file = "simplejson-3.19.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:08889f2f597ae965284d7b52a5c3928653a9406d88c93e3161180f0abc2433ba"}, + {file = "simplejson-3.19.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef7938a78447174e2616be223f496ddccdbf7854f7bf2ce716dbccd958cc7d13"}, + {file = "simplejson-3.19.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a970a2e6d5281d56cacf3dc82081c95c1f4da5a559e52469287457811db6a79b"}, + {file = "simplejson-3.19.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554313db34d63eac3b3f42986aa9efddd1a481169c12b7be1e7512edebff8eaf"}, + {file = "simplejson-3.19.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d36081c0b1c12ea0ed62c202046dca11438bee48dd5240b7c8de8da62c620e9"}, + {file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a3cd18e03b0ee54ea4319cdcce48357719ea487b53f92a469ba8ca8e39df285e"}, + {file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:66e5dc13bfb17cd6ee764fc96ccafd6e405daa846a42baab81f4c60e15650414"}, + {file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:972a7833d4a1fcf7a711c939e315721a88b988553fc770a5b6a5a64bd6ebeba3"}, + {file = "simplejson-3.19.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3e74355cb47e0cd399ead3477e29e2f50e1540952c22fb3504dda0184fc9819f"}, + {file = "simplejson-3.19.2-cp311-cp311-win32.whl", hash = "sha256:1dd4f692304854352c3e396e9b5f0a9c9e666868dd0bdc784e2ac4c93092d87b"}, + {file = "simplejson-3.19.2-cp311-cp311-win_amd64.whl", hash = "sha256:9300aee2a8b5992d0f4293d88deb59c218989833e3396c824b69ba330d04a589"}, + {file = "simplejson-3.19.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b8d940fd28eb34a7084877747a60873956893e377f15a32ad445fe66c972c3b8"}, + {file = "simplejson-3.19.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4969d974d9db826a2c07671273e6b27bc48e940738d768fa8f33b577f0978378"}, + {file = "simplejson-3.19.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c594642d6b13d225e10df5c16ee15b3398e21a35ecd6aee824f107a625690374"}, + {file = "simplejson-3.19.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2f5a398b5e77bb01b23d92872255e1bcb3c0c719a3be40b8df146570fe7781a"}, + {file = "simplejson-3.19.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176a1b524a3bd3314ed47029a86d02d5a95cc0bee15bd3063a1e1ec62b947de6"}, + {file = "simplejson-3.19.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3c7363a8cb8c5238878ec96c5eb0fc5ca2cb11fc0c7d2379863d342c6ee367a"}, + {file = "simplejson-3.19.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:346820ae96aa90c7d52653539a57766f10f33dd4be609206c001432b59ddf89f"}, + {file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de9a2792612ec6def556d1dc621fd6b2073aff015d64fba9f3e53349ad292734"}, + {file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1c768e7584c45094dca4b334af361e43b0aaa4844c04945ac7d43379eeda9bc2"}, + {file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:9652e59c022e62a5b58a6f9948b104e5bb96d3b06940c6482588176f40f4914b"}, + {file = "simplejson-3.19.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9c1a4393242e321e344213a90a1e3bf35d2f624aa8b8f6174d43e3c6b0e8f6eb"}, + {file = "simplejson-3.19.2-cp312-cp312-win32.whl", hash = "sha256:7cb98be113911cb0ad09e5523d0e2a926c09a465c9abb0784c9269efe4f95917"}, + {file = "simplejson-3.19.2-cp312-cp312-win_amd64.whl", hash = "sha256:6779105d2fcb7fcf794a6a2a233787f6bbd4731227333a072d8513b252ed374f"}, + {file = "simplejson-3.19.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:061e81ea2d62671fa9dea2c2bfbc1eec2617ae7651e366c7b4a2baf0a8c72cae"}, + {file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4280e460e51f86ad76dc456acdbfa9513bdf329556ffc8c49e0200878ca57816"}, + {file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11c39fbc4280d7420684494373b7c5904fa72a2b48ef543a56c2d412999c9e5d"}, + {file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bccb3e88ec26ffa90f72229f983d3a5d1155e41a1171190fa723d4135523585b"}, + {file = "simplejson-3.19.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bb5b50dc6dd671eb46a605a3e2eb98deb4a9af787a08fcdddabe5d824bb9664"}, + {file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d94245caa3c61f760c4ce4953cfa76e7739b6f2cbfc94cc46fff6c050c2390c5"}, + {file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d0e5ffc763678d48ecc8da836f2ae2dd1b6eb2d27a48671066f91694e575173c"}, + {file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d222a9ed082cd9f38b58923775152003765016342a12f08f8c123bf893461f28"}, + {file = "simplejson-3.19.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8434dcdd347459f9fd9c526117c01fe7ca7b016b6008dddc3c13471098f4f0dc"}, + {file = "simplejson-3.19.2-cp36-cp36m-win32.whl", hash = "sha256:c9ac1c2678abf9270e7228133e5b77c6c3c930ad33a3c1dfbdd76ff2c33b7b50"}, + {file = "simplejson-3.19.2-cp36-cp36m-win_amd64.whl", hash = "sha256:92c4a4a2b1f4846cd4364855cbac83efc48ff5a7d7c06ba014c792dd96483f6f"}, + {file = "simplejson-3.19.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0d551dc931638e2102b8549836a1632e6e7cf620af3d093a7456aa642bff601d"}, + {file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73a8a4653f2e809049999d63530180d7b5a344b23a793502413ad1ecea9a0290"}, + {file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:40847f617287a38623507d08cbcb75d51cf9d4f9551dd6321df40215128325a3"}, + {file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be893258d5b68dd3a8cba8deb35dc6411db844a9d35268a8d3793b9d9a256f80"}, + {file = "simplejson-3.19.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9eb3cff1b7d71aa50c89a0536f469cb8d6dcdd585d8f14fb8500d822f3bdee4"}, + {file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d0f402e787e6e7ee7876c8b05e2fe6464820d9f35ba3f172e95b5f8b699f6c7f"}, + {file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fbbcc6b0639aa09b9649f36f1bcb347b19403fe44109948392fbb5ea69e48c3e"}, + {file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2fc697be37585eded0c8581c4788fcfac0e3f84ca635b73a5bf360e28c8ea1a2"}, + {file = "simplejson-3.19.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b0a3eb6dd39cce23801a50c01a0976971498da49bc8a0590ce311492b82c44b"}, + {file = "simplejson-3.19.2-cp37-cp37m-win32.whl", hash = "sha256:49f9da0d6cd17b600a178439d7d2d57c5ef01f816b1e0e875e8e8b3b42db2693"}, + {file = "simplejson-3.19.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c87c22bd6a987aca976e3d3e23806d17f65426191db36d40da4ae16a6a494cbc"}, + {file = "simplejson-3.19.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9e4c166f743bb42c5fcc60760fb1c3623e8fda94f6619534217b083e08644b46"}, + {file = "simplejson-3.19.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0a48679310e1dd5c9f03481799311a65d343748fe86850b7fb41df4e2c00c087"}, + {file = "simplejson-3.19.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0521e0f07cb56415fdb3aae0bbd8701eb31a9dfef47bb57206075a0584ab2a2"}, + {file = "simplejson-3.19.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d2d5119b1d7a1ed286b8af37357116072fc96700bce3bec5bb81b2e7057ab41"}, + {file = "simplejson-3.19.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c1467d939932901a97ba4f979e8f2642415fcf02ea12f53a4e3206c9c03bc17"}, + {file = "simplejson-3.19.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49aaf4546f6023c44d7e7136be84a03a4237f0b2b5fb2b17c3e3770a758fc1a0"}, + {file = "simplejson-3.19.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60848ab779195b72382841fc3fa4f71698a98d9589b0a081a9399904487b5832"}, + {file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0436a70d8eb42bea4fe1a1c32d371d9bb3b62c637969cb33970ad624d5a3336a"}, + {file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:49e0e3faf3070abdf71a5c80a97c1afc059b4f45a5aa62de0c2ca0444b51669b"}, + {file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ff836cd4041e16003549449cc0a5e372f6b6f871eb89007ab0ee18fb2800fded"}, + {file = "simplejson-3.19.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3848427b65e31bea2c11f521b6fc7a3145d6e501a1038529da2391aff5970f2f"}, + {file = "simplejson-3.19.2-cp38-cp38-win32.whl", hash = "sha256:3f39bb1f6e620f3e158c8b2eaf1b3e3e54408baca96a02fe891794705e788637"}, + {file = "simplejson-3.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:0405984f3ec1d3f8777c4adc33eac7ab7a3e629f3b1c05fdded63acc7cf01137"}, + {file = "simplejson-3.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:445a96543948c011a3a47c8e0f9d61e9785df2544ea5be5ab3bc2be4bd8a2565"}, + {file = "simplejson-3.19.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a8c3cc4f9dfc33220246760358c8265dad6e1104f25f0077bbca692d616d358"}, + {file = "simplejson-3.19.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af9c7e6669c4d0ad7362f79cb2ab6784d71147503e62b57e3d95c4a0f222c01c"}, + {file = "simplejson-3.19.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:064300a4ea17d1cd9ea1706aa0590dcb3be81112aac30233823ee494f02cb78a"}, + {file = "simplejson-3.19.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9453419ea2ab9b21d925d0fd7e3a132a178a191881fab4169b6f96e118cc25bb"}, + {file = "simplejson-3.19.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e038c615b3906df4c3be8db16b3e24821d26c55177638ea47b3f8f73615111c"}, + {file = "simplejson-3.19.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16ca9c90da4b1f50f089e14485db8c20cbfff2d55424062791a7392b5a9b3ff9"}, + {file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1018bd0d70ce85f165185d2227c71e3b1e446186f9fa9f971b69eee223e1e3cd"}, + {file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e8dd53a8706b15bc0e34f00e6150fbefb35d2fd9235d095b4f83b3c5ed4fa11d"}, + {file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:2d022b14d7758bfb98405672953fe5c202ea8a9ccf9f6713c5bd0718eba286fd"}, + {file = "simplejson-3.19.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:febffa5b1eda6622d44b245b0685aff6fb555ce0ed734e2d7b1c3acd018a2cff"}, + {file = "simplejson-3.19.2-cp39-cp39-win32.whl", hash = "sha256:4edcd0bf70087b244ba77038db23cd98a1ace2f91b4a3ecef22036314d77ac23"}, + {file = "simplejson-3.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:aad7405c033d32c751d98d3a65801e2797ae77fac284a539f6c3a3e13005edc4"}, + {file = "simplejson-3.19.2-py3-none-any.whl", hash = "sha256:bcedf4cae0d47839fee7de344f96b5694ca53c786f28b5f773d4f0b265a159eb"}, + {file = "simplejson-3.19.2.tar.gz", hash = "sha256:9eb442a2442ce417801c912df68e1f6ccfcd41577ae7274953ab3ad24ef7d82c"}, +] + [[package]] name = "six" version = "1.16.0" @@ -1196,6 +1743,22 @@ files = [ [package.extras] doc = ["sphinx"] +[[package]] +name = "swagger-spec-validator" +version = "3.0.3" +description = "Validation of Swagger specifications" +optional = false +python-versions = ">=3.7" +files = [ + {file = "swagger-spec-validator-3.0.3.tar.gz", hash = "sha256:16a5ce08c772824a77b1a4a05efc047d72eef1ed53fb969dfe0a18f437ac30a8"}, + {file = "swagger_spec_validator-3.0.3-py2.py3-none-any.whl", hash = "sha256:174b5de4ab0899df9a57d35c880aaa515511c4b8b578d9d519b09a9596537055"}, +] + +[package.dependencies] +jsonschema = "*" +pyyaml = "*" +typing-extensions = "*" + [[package]] name = "toml" version = "0.10.2" @@ -1282,6 +1845,17 @@ files = [ {file = "twisted_iocpsupport-1.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:300437af17396a945a58dcfffd77863303a8b6d9e65c6e81f1d2eed55b50d444"}, ] +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20240316" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, + {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1293,6 +1867,37 @@ files = [ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] +[[package]] +name = "uri-template" +version = "1.3.0" +description = "RFC 6570 URI Template Processor" +optional = false +python-versions = ">=3.7" +files = [ + {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, + {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, +] + +[package.extras] +dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] + +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "virtualenv" version = "20.26.2" @@ -1313,6 +1918,21 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +[[package]] +name = "webcolors" +version = "24.6.0" +description = "A library for working with the color formats defined by HTML and CSS." +optional = false +python-versions = ">=3.8" +files = [ + {file = "webcolors-24.6.0-py3-none-any.whl", hash = "sha256:8cf5bc7e28defd1d48b9e83d5fc30741328305a8195c29a8e668fa45586568a1"}, + {file = "webcolors-24.6.0.tar.gz", hash = "sha256:1d160d1de46b3e81e58d0a280d0c78b467dc80f47294b91b1ad8029d2cedb55b"}, +] + +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] +tests = ["coverage[toml]"] + [[package]] name = "wrapt" version = "1.16.0" @@ -1448,4 +2068,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "79573c68226220f22fe69549e0621da19430e955338e6b56ef377d1ccc13c438" +content-hash = "9d594e2c8e55791b6138f25d7c0718ab5fe7ddd32b93ba231a12a0d137984550" diff --git a/pyproject.toml b/pyproject.toml index 48a4836..85e78fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ stompest = "^2.3.0" pyasn1 = "^0.6.0" pytz = ">=2024.1" bugzilla2fedmsg-schema = "^1.0.0" +fasjson-client = "^1.0.8" [tool.poetry.group.dev.dependencies] pytest = ">=7.0.0" diff --git a/tests/conftest.py b/tests/conftest.py index e57cd12..7fa1f5e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,9 +4,42 @@ """ +from types import SimpleNamespace +from unittest import mock + import pytest +@pytest.fixture +def fakepublish(): + with mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) as _mock: + yield _mock + + +FASJSON_USER_MAP = { + "dgunchev@gmail.com": "dgunchev", + "lvrabec@redhat.com": "lv", + "awilliam@redhat.com": "adamw", + "peter@sonniger-tag.eu": "peter", + "joequant@gmail.com": "joe", +} + + +@pytest.fixture +def fakefasjson(): + client = mock.Mock(name="fasjson") + + def _search(rhbzemail): + try: + return SimpleNamespace(result=[{"username": FASJSON_USER_MAP[rhbzemail]}]) + except KeyError: + return SimpleNamespace(result=[]) + + client.search.side_effect = _search + with mock.patch("bugzilla2fedmsg.relay.FasjsonClient", return_value=client): + yield client + + @pytest.fixture(scope="function") def bug_create_message(request): """Sample upstream bug.create message.""" diff --git a/tests/test_consumer.py b/tests/test_consumer.py index f8b52da..cd97358 100644 --- a/tests/test_consumer.py +++ b/tests/test_consumer.py @@ -9,6 +9,7 @@ @pytest.fixture def consumer_config(): return { + "fasjson_url": "https://fasjson.example.com", "stomp": { "uri": "tcp://localhost:61613", "vhost": "/", diff --git a/tests/test_relay.py b/tests/test_relay.py index d2415e3..d320b0c 100644 --- a/tests/test_relay.py +++ b/tests/test_relay.py @@ -4,199 +4,212 @@ """ -from unittest import mock - import fedora_messaging.exceptions +import pytest import bugzilla2fedmsg.relay -class TestRelay: - relay = bugzilla2fedmsg.relay.MessageRelay( - {"bugzilla": {"products": ["Fedora", "Fedora EPEL"]}} +@pytest.fixture +def testrelay(fakefasjson): + return bugzilla2fedmsg.relay.MessageRelay( + { + "fasjson_url": "https://fasjson.example.com", + "bugzilla": {"products": ["Fedora", "Fedora EPEL"]}, + } ) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_create(self, fakepublish, bug_create_message): - """Check correct result for bug.create message.""" - self.relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.topic == "bugzilla.bug.new" - assert "product" in message.body["bug"] - assert message.body["event"]["routing_key"] == "bug.create" - # this tests convert_datetimes - createtime = message.body["bug"]["creation_time"] - assert createtime == 1555619221.0 - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_modify(self, fakepublish, bug_modify_message): - """Check correct result for bug.modify message.""" - self.relay.on_stomp_message(bug_modify_message["body"], bug_modify_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.topic == "bugzilla.bug.update" - assert "product" in message.body["bug"] - assert message.body["event"]["routing_key"] == "bug.modify" - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_comment_create(self, fakepublish, comment_create_message): - """Check correct result for comment.create message.""" - self.relay.on_stomp_message( - comment_create_message["body"], comment_create_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.topic == "bugzilla.bug.update" - assert message.body["comment"] == { - "author": "smooge@redhat.com", - "body": "qa09 and qa14 have 8 560 GB SAS drives which are RAID-6 together. \n\nThe systems we get from IBM come through a special contract which in the past required the system to be sent back to add hardware to it. When we added drives it also caused problems because the system didn't match the contract when we returned it. I am checking with IBM on the wearabouts for the systems.", - "creation_time": 1555602938.0, - "number": 8, - "id": 1691487, - "is_private": False, - } - # we probably don't need to check these whole things... - assert "product" in message.body["bug"] - assert message.body["event"]["routing_key"] == "comment.create" - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_attachment_create(self, fakepublish, attachment_create_message): - """Check correct result for attachment.create message.""" - self.relay.on_stomp_message( - attachment_create_message["body"], attachment_create_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.topic == "bugzilla.bug.update" - assert message.body["attachment"] == { - "description": "File: var_log_messages", - "file_name": "var_log_messages", - "is_patch": False, - "creation_time": 1555610511.0, - "id": 1556193, - "flags": [], - "last_change_time": 1555610511.0, - "content_type": "text/plain", - "is_obsolete": False, - "is_private": False, + +def test_bug_create(testrelay, fakepublish, fakefasjson, bug_create_message): + """Check correct result for bug.create message.""" + testrelay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.topic == "bugzilla.bug.new" + assert "product" in message.body["bug"] + assert message.body["event"]["routing_key"] == "bug.create" + # this tests convert_datetimes + createtime = message.body["bug"]["creation_time"] + assert createtime == 1555619221.0 + assert message.body["agent_name"] == "dgunchev" + assert message.body["usernames"] == ["dgunchev", "lv"] + + +def test_bug_modify(testrelay, fakepublish, bug_modify_message): + """Check correct result for bug.modify message.""" + testrelay.on_stomp_message(bug_modify_message["body"], bug_modify_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.topic == "bugzilla.bug.update" + assert "product" in message.body["bug"] + assert message.body["event"]["routing_key"] == "bug.modify" + assert message.body["agent_name"] is None + assert message.body["usernames"] == ["adamw", "upstream-release-monitoring"] + + +def test_comment_create(testrelay, fakepublish, comment_create_message): + """Check correct result for comment.create message.""" + testrelay.on_stomp_message(comment_create_message["body"], comment_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.topic == "bugzilla.bug.update" + assert message.body["comment"] == { + "author": "smooge@redhat.com", + "body": "qa09 and qa14 have 8 560 GB SAS drives which are RAID-6 together. \n\nThe systems we get from IBM come through a special contract which in the past required the system to be sent back to add hardware to it. When we added drives it also caused problems because the system didn't match the contract when we returned it. I am checking with IBM on the wearabouts for the systems.", + "creation_time": 1555602938.0, + "number": 8, + "id": 1691487, + "is_private": False, + } + # we probably don't need to check these whole things... + assert "product" in message.body["bug"] + assert message.body["event"]["routing_key"] == "comment.create" + assert message.body["agent_name"] is None + assert message.body["usernames"] == ["adamw"] + + +def test_attachment_create(testrelay, fakepublish, attachment_create_message): + """Check correct result for attachment.create message.""" + testrelay.on_stomp_message( + attachment_create_message["body"], attachment_create_message["headers"] + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.topic == "bugzilla.bug.update" + assert message.body["attachment"] == { + "description": "File: var_log_messages", + "file_name": "var_log_messages", + "is_patch": False, + "creation_time": 1555610511.0, + "id": 1556193, + "flags": [], + "last_change_time": 1555610511.0, + "content_type": "text/plain", + "is_obsolete": False, + "is_private": False, + } + # we probably don't need to check these whole things... + assert "product" in message.body["bug"] + assert message.body["event"]["routing_key"] == "attachment.create" + assert message.body["agent_name"] == "peter" + assert message.body["usernames"] == ["peter"] + + +def test_attachment_modify(testrelay, fakepublish, attachment_modify_message): + """Check correct result for attachment.modify message.""" + testrelay.on_stomp_message( + attachment_modify_message["body"], attachment_modify_message["headers"] + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.topic == "bugzilla.bug.update" + assert message.body["attachment"] == { + "description": "patch to turn off reset quirk for SP1064 touch pad", + "file_name": "kernel-diff.patch", + "is_patch": True, + "creation_time": 1556149017.0, + "id": 1558429, + "flags": [], + "last_change_time": 1556149017.0, + "content_type": "text/plain", + "is_obsolete": True, + "is_private": False, + } + # we probably don't need to check these whole things... + assert "product" in message.body["bug"] + assert message.body["event"]["routing_key"] == "attachment.modify" + assert message.body["agent_name"] == "joe" + assert message.body["usernames"] == ["joe"] + + +def test_private_drop(testrelay, fakepublish, private_message): + """Check that we drop (don't publish) a private message.""" + testrelay.on_stomp_message(private_message["body"], private_message["headers"]) + assert fakepublish.call_count == 0 + + +def test_other_product_drop(testrelay, fakepublish, other_product_message): + """Check that we drop (don't publish) a message for a product + we don't want to cover. As our fake hub doesn't really have a + config, the products we care about are the defaults: 'Fedora' + and 'Fedora EPEL'. + """ + testrelay.on_stomp_message(other_product_message["body"], other_product_message["headers"]) + assert fakepublish.call_count == 0 + + +def test_bz4_compat( + testrelay, fakefasjson, fakepublish, bug_create_message, comment_create_message +): + """This tests various modifications we make to the bug dict in + the name of 'backwards compatibility', i.e. making messages + look more like they did before Bugzilla 5. + """ + bz4relay = bugzilla2fedmsg.relay.MessageRelay( + { + "fasjson_url": "https://fasjson.example.com", + "bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": True}, } - # we probably don't need to check these whole things... - assert "product" in message.body["bug"] - assert message.body["event"]["routing_key"] == "attachment.create" - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_attachment_modify(self, fakepublish, attachment_modify_message): - """Check correct result for attachment.modify message.""" - self.relay.on_stomp_message( - attachment_modify_message["body"], attachment_modify_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.topic == "bugzilla.bug.update" - assert message.body["attachment"] == { - "description": "patch to turn off reset quirk for SP1064 touch pad", - "file_name": "kernel-diff.patch", - "is_patch": True, - "creation_time": 1556149017.0, - "id": 1558429, - "flags": [], - "last_change_time": 1556149017.0, - "content_type": "text/plain", - "is_obsolete": True, - "is_private": False, + ) + bz4relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.body["bug"]["assigned_to"] == "lvrabec@redhat.com" + assert message.body["bug"]["component"] == "selinux-policy" + assert message.body["bug"]["product"] == "Fedora" + assert message.body["bug"]["cc"] == [] + assert message.body["bug"]["creator"] == "dgunchev@gmail.com" + assert message.body["bug"]["op_sys"] == "Unspecified" + assert message.body["event"]["who"] == "dgunchev@gmail.com" + assert message.body["bug"]["weburl"] == "https://bugzilla.redhat.com/show_bug.cgi?id=1701391" + # we need a comment message to test this + fakepublish.reset_mock() + testrelay.on_stomp_message(comment_create_message["body"], comment_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert message.body["comment"]["author"] == "smooge@redhat.com" + + +def test_bz4_compat_disabled(fakefasjson, fakepublish, bug_create_message, comment_create_message): + """Test that we *don't* make Bugzilla 4 compat modifications + if the option is switched off. Tests only the destructive ones + as they're the ones we really want to avoid, and if these + aren't happening it's pretty certain the others aren't either. + """ + nobz4relay = bugzilla2fedmsg.relay.MessageRelay( + { + "fasjson_url": "https://fasjson.example.com", + "bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": False}, } - # we probably don't need to check these whole things... - assert "product" in message.body["bug"] - assert message.body["event"]["routing_key"] == "attachment.modify" - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_private_drop(self, fakepublish, private_message): - """Check that we drop (don't publish) a private message.""" - self.relay.on_stomp_message(private_message["body"], private_message["headers"]) - assert fakepublish.call_count == 0 - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_other_product_drop(self, fakepublish, other_product_message): - """Check that we drop (don't publish) a message for a product - we don't want to cover. As our fake hub doesn't really have a - config, the products we care about are the defaults: 'Fedora' - and 'Fedora EPEL'. - """ - self.relay.on_stomp_message(other_product_message["body"], other_product_message["headers"]) - assert fakepublish.call_count == 0 - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bz4_compat(self, fakepublish, bug_create_message, comment_create_message): - """This tests various modifications we make to the bug dict in - the name of 'backwards compatibility', i.e. making messages - look more like they did before Bugzilla 5. - """ - bz4relay = bugzilla2fedmsg.relay.MessageRelay( - {"bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": True}} - ) - bz4relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.body["bug"]["assigned_to"] == "lvrabec@redhat.com" - assert message.body["bug"]["component"] == "selinux-policy" - assert message.body["bug"]["product"] == "Fedora" - assert message.body["bug"]["cc"] == [] - assert message.body["bug"]["creator"] == "dgunchev@gmail.com" - assert message.body["bug"]["op_sys"] == "Unspecified" - assert message.body["event"]["who"] == "dgunchev@gmail.com" - assert ( - message.body["bug"]["weburl"] == "https://bugzilla.redhat.com/show_bug.cgi?id=1701391" - ) - # we need a comment message to test this - fakepublish.reset_mock() - self.relay.on_stomp_message( - comment_create_message["body"], comment_create_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert message.body["comment"]["author"] == "smooge@redhat.com" - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bz4_compat_disabled(self, fakepublish, bug_create_message, comment_create_message): - """Test that we *don't* make Bugzilla 4 compat modifications - if the option is switched off. Tests only the destructive ones - as they're the ones we really want to avoid, and if these - aren't happening it's pretty certain the others aren't either. - """ - nobz4relay = bugzilla2fedmsg.relay.MessageRelay( - {"bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": False}} - ) - nobz4relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - assert all( - item in message.body["bug"]["assigned_to"] for item in ("login", "id", "real_name") - ) - assert all(item in message.body["bug"]["component"] for item in ("id", "name")) - assert all(item in message.body["bug"]["product"] for item in ("id", "name")) - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_publish_exception_publishreturned(self, fakepublish, bug_create_message, caplog): - """Check that we handle PublishReturned exception from publish - correctly. - """ - fakepublish.side_effect = fedora_messaging.exceptions.PublishReturned("oops!") - # this should not raise any exception - self.relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - # check the logging worked - assert "Fedora Messaging broker rejected message" in caplog.text - - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_publish_exception_connectionexception(self, fakepublish, bug_create_message, caplog): - """Check that we handle ConnectionException from publish - correctly. - """ - # First test PublishReturned - fakepublish.side_effect = fedora_messaging.exceptions.ConnectionException("oops!") - # this should not raise any exception - self.relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - # check the logging worked - assert "Error sending message" in caplog.text + ) + nobz4relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + assert all(item in message.body["bug"]["assigned_to"] for item in ("login", "id", "real_name")) + assert all(item in message.body["bug"]["component"] for item in ("id", "name")) + assert all(item in message.body["bug"]["product"] for item in ("id", "name")) + + +def test_publish_exception_publishreturned(testrelay, fakepublish, bug_create_message, caplog): + """Check that we handle PublishReturned exception from publish + correctly. + """ + fakepublish.side_effect = fedora_messaging.exceptions.PublishReturned("oops!") + # this should not raise any exception + testrelay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + # check the logging worked + assert "Fedora Messaging broker rejected message" in caplog.text + + +def test_publish_exception_connectionexception(testrelay, fakepublish, bug_create_message, caplog): + """Check that we handle ConnectionException from publish + correctly. + """ + # First test PublishReturned + fakepublish.side_effect = fedora_messaging.exceptions.ConnectionException("oops!") + # this should not raise any exception + testrelay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + # check the logging worked + assert "Error sending message" in caplog.text diff --git a/tests/test_schemas.py b/tests/test_schemas.py index 8194b5a..1f3953d 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -1,262 +1,244 @@ """ Tests for bugzilla2fedmsg_schemas. +We are basically going to use the relays to construct messages +just as we do in test_relay, then check the messages validate +and test the various schema methods. We parametrize the tests +to test all the schema versions + Authors: Adam Williamson """ -from unittest import mock - import pytest from jsonschema.exceptions import ValidationError import bugzilla2fedmsg.relay -class TestSchemas: - # We are basically going to use the relays to construct messages - # just as we do in test_relay, then check the messages validate - # and test the various schema methods. We parametrize the tests - # to test all the schema versions - bz4relay = bugzilla2fedmsg.relay.MessageRelay( - {"bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": True}} +@pytest.fixture(params=[True, False]) +def testrelay(request, fakefasjson): + return bugzilla2fedmsg.relay.MessageRelay( + { + "fasjson_url": "https://fasjson.example.com", + "bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": request.param}, + } + ) + + +def test_bug_create_schema(fakepublish, bug_create_message, testrelay): + """Check bug.create message schema bits.""" + testrelay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert message.assigned_to_email == "lvrabec@redhat.com" + assert message.component_name == "selinux-policy" + assert message.product_name == "Fedora" + assert ( + message.summary + == "dgunchev@gmail.com filed a new bug RHBZ#1701391 'SELinux is preventing touch from 'write'...'" + ) + assert ( + str(message) + == "dgunchev@gmail.com filed a new bug RHBZ#1701391 'SELinux is preventing touch from 'write'...'" + ) + assert message.url == "https://bugzilla.redhat.com/show_bug.cgi?id=1701391" + assert ( + message.app_icon == "https://bugzilla.redhat.com/extensions/RedHat/web/css/favicon.ico?v=0" + ) + assert message.agent_name == "Doncho Gunchev" + assert message.app_name == "bugzilla2fedmsg" + # broken till we can do email2fas + assert message.usernames == [] + assert message.packages == ["selinux-policy"] + assert ( + message.agent_avatar + == "https://seccdn.libravatar.org/avatar/d4bfc5ec5260361c930aad299c8e14fe03af45109ea88e880a191851b8c83e7f?s=64&d=retro" ) - nobz4relay = bugzilla2fedmsg.relay.MessageRelay( - {"bugzilla": {"products": ["Fedora", "Fedora EPEL"], "bz4compat": False}} + assert message._primary_email == "dgunchev@gmail.com" + assert message._all_emails == ["dgunchev@gmail.com", "lvrabec@redhat.com"] + + +def test_bug_modify_schema(fakepublish, bug_modify_message, testrelay): + """Check bug.modify message schema bits.""" + testrelay.on_stomp_message(bug_modify_message["body"], bug_modify_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "mhroncok@redhat.com updated 'cc' on RHBZ#1699203 'python-pyramid-1.10.4 is available'" + ) + # here we test both picking up an address from a 'cc' change + # event, and filtering out lists.fedoraproject.org addresses + assert message._all_emails == [ + "awilliam@redhat.com", + "mhroncok@redhat.com", + "upstream-release-monitoring@fedoraproject.org", + ] + # here we test that we can at least derive usernames from + # fedoraproject.org email addresses + assert message.usernames == ["upstream-release-monitoring"] + + +def test_bug_modify_four_changes_schema(fakepublish, bug_modify_message_four_changes, testrelay): + """Check bug.modify message schema bits when the message + includes four changes (this exercises comma_join). + """ + testrelay.on_stomp_message( + bug_modify_message_four_changes["body"], + bug_modify_message_four_changes["headers"], + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "zebob.m@gmail.com updated 'assigned_to', 'bug_status', 'cc', and 'flag.needinfo' on RHBZ#1702701 'Review Request: perl-Class-AutoClass - D...'" + ) + # this tests gathering an address from a 'needinfo' change + assert message._all_emails == [ + "ppisar@redhat.com", + "rob@boberts.com", + "zebob.m@gmail.com", + ] + + +def test_bug_modify_two_changes_schema(fakepublish, bug_modify_message_four_changes, testrelay): + """Check bug.modify message schema bits when the message + includes two changes (this exercises a slightly different + comma_join path). + """ + # Just dump two changes from the 'four changes' message + bug_modify_message_four_changes["body"]["event"]["changes"] = bug_modify_message_four_changes[ + "body" + ]["event"]["changes"][:2] + testrelay.on_stomp_message( + bug_modify_message_four_changes["body"], + bug_modify_message_four_changes["headers"], + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "zebob.m@gmail.com updated 'assigned_to' and 'bug_status' on RHBZ#1702701 'Review Request: perl-Class-AutoClass - D...'" ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_create_schema(self, fakepublish, bug_create_message, relay): - """Check bug.create message schema bits.""" - relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert message.assigned_to_email == "lvrabec@redhat.com" - assert message.component_name == "selinux-policy" - assert message.product_name == "Fedora" - assert ( - message.summary - == "dgunchev@gmail.com filed a new bug RHBZ#1701391 'SELinux is preventing touch from 'write'...'" - ) - assert ( - str(message) - == "dgunchev@gmail.com filed a new bug RHBZ#1701391 'SELinux is preventing touch from 'write'...'" - ) - assert message.url == "https://bugzilla.redhat.com/show_bug.cgi?id=1701391" - assert ( - message.app_icon - == "https://bugzilla.redhat.com/extensions/RedHat/web/css/favicon.ico?v=0" - ) - assert message.agent_name == "Doncho Gunchev" - assert message.app_name == "bugzilla2fedmsg" - # broken till we can do email2fas - assert message.usernames == [] - assert message.packages == ["selinux-policy"] - assert ( - message.agent_avatar - == "https://seccdn.libravatar.org/avatar/d4bfc5ec5260361c930aad299c8e14fe03af45109ea88e880a191851b8c83e7f?s=64&d=retro" - ) - assert message._primary_email == "dgunchev@gmail.com" - assert message._all_emails == ["dgunchev@gmail.com", "lvrabec@redhat.com"] - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_modify_schema(self, fakepublish, bug_modify_message, relay): - """Check bug.modify message schema bits.""" - relay.on_stomp_message(bug_modify_message["body"], bug_modify_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "mhroncok@redhat.com updated 'cc' on RHBZ#1699203 'python-pyramid-1.10.4 is available'" - ) - # here we test both picking up an address from a 'cc' change - # event, and filtering out lists.fedoraproject.org addresses - assert message._all_emails == [ - "awilliam@redhat.com", - "mhroncok@redhat.com", - "upstream-release-monitoring@fedoraproject.org", - ] - # here we test that we can at least derive usernames from - # fedoraproject.org email addresses - assert message.usernames == ["upstream-release-monitoring"] +def test_bug_modify_no_changes_schema(fakepublish, bug_modify_message, testrelay): + """Check bug.modify message schema bits when event is missing + 'changes' - we often get messages like this, for some reason. + """ + # wipe the 'changes' dict from the sample message, to simulate + # one of these broken messages + del bug_modify_message["body"]["event"]["changes"] + testrelay.on_stomp_message(bug_modify_message["body"], bug_modify_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "mhroncok@redhat.com updated something unknown on RHBZ#1699203 'python-pyramid-1.10.4 is available'" + ) + assert message._all_emails == [ + "mhroncok@redhat.com", + "upstream-release-monitoring@fedoraproject.org", + ] + + +def test_comment_create_schema(fakepublish, comment_create_message, testrelay): + """Check comment.create message schema bits.""" + testrelay.on_stomp_message(comment_create_message["body"], comment_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "smooge@redhat.com added comment on RHBZ#1691487 'openQA transient test failure as duplica...'" + ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_modify_four_changes_schema( - self, fakepublish, bug_modify_message_four_changes, relay - ): - """Check bug.modify message schema bits when the message - includes four changes (this exercises comma_join). - """ - relay.on_stomp_message( - bug_modify_message_four_changes["body"], - bug_modify_message_four_changes["headers"], - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "zebob.m@gmail.com updated 'assigned_to', 'bug_status', 'cc', and 'flag.needinfo' on RHBZ#1702701 'Review Request: perl-Class-AutoClass - D...'" - ) - # this tests gathering an address from a 'needinfo' change - assert message._all_emails == [ - "ppisar@redhat.com", - "rob@boberts.com", - "zebob.m@gmail.com", - ] - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_modify_two_changes_schema( - self, fakepublish, bug_modify_message_four_changes, relay - ): - """Check bug.modify message schema bits when the message - includes two changes (this exercises a slightly different - comma_join path). - """ - # Just dump two changes from the 'four changes' message - bug_modify_message_four_changes["body"]["event"]["changes"] = ( - bug_modify_message_four_changes["body"]["event"]["changes"][:2] - ) - relay.on_stomp_message( - bug_modify_message_four_changes["body"], - bug_modify_message_four_changes["headers"], - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "zebob.m@gmail.com updated 'assigned_to' and 'bug_status' on RHBZ#1702701 'Review Request: perl-Class-AutoClass - D...'" - ) +def test_attachment_create_schema(fakepublish, attachment_create_message, testrelay): + """Check attachment.create message schema bits.""" + testrelay.on_stomp_message( + attachment_create_message["body"], attachment_create_message["headers"] + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "peter@sonniger-tag.eu added attachment on RHBZ#1701353 '[abrt] gnome-software: gtk_widget_unpare...'" + ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_modify_no_changes_schema(self, fakepublish, bug_modify_message, relay): - """Check bug.modify message schema bits when event is missing - 'changes' - we often get messages like this, for some reason. - """ - # wipe the 'changes' dict from the sample message, to simulate - # one of these broken messages - del bug_modify_message["body"]["event"]["changes"] - relay.on_stomp_message(bug_modify_message["body"], bug_modify_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "mhroncok@redhat.com updated something unknown on RHBZ#1699203 'python-pyramid-1.10.4 is available'" - ) - assert message._all_emails == [ - "mhroncok@redhat.com", - "upstream-release-monitoring@fedoraproject.org", - ] - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_comment_create_schema(self, fakepublish, comment_create_message, relay): - """Check comment.create message schema bits.""" - relay.on_stomp_message(comment_create_message["body"], comment_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "smooge@redhat.com added comment on RHBZ#1691487 'openQA transient test failure as duplica...'" - ) +def test_attachment_modify_schema(fakepublish, attachment_modify_message, testrelay): + """Check attachment.modify message schema bits.""" + testrelay.on_stomp_message( + attachment_modify_message["body"], attachment_modify_message["headers"] + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "joequant@gmail.com updated 'isobsolete' for attachment on RHBZ#1701766 'I2C_HID_QUIRK_NO_IRQ_AFTER_RESET caused ...'" + ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_attachment_create_schema(self, fakepublish, attachment_create_message, relay): - """Check attachment.create message schema bits.""" - relay.on_stomp_message( - attachment_create_message["body"], attachment_create_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "peter@sonniger-tag.eu added attachment on RHBZ#1701353 '[abrt] gnome-software: gtk_widget_unpare...'" - ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_attachment_modify_schema(self, fakepublish, attachment_modify_message, relay): - """Check attachment.modify message schema bits.""" - relay.on_stomp_message( - attachment_modify_message["body"], attachment_modify_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "joequant@gmail.com updated 'isobsolete' for attachment on RHBZ#1701766 'I2C_HID_QUIRK_NO_IRQ_AFTER_RESET caused ...'" - ) +def test_attachment_modify_no_changes_schema(fakepublish, attachment_modify_message, testrelay): + """Check attachment.modify message schema bits when event is + missing 'changes' - unlike the bug.modify case I have not + actually seen a message like this in the wild, but we do + handle it just in case. + """ + # wipe the 'changes' dict from the sample message, to simulate + # one of these broken messages + del attachment_modify_message["body"]["event"]["changes"] + testrelay.on_stomp_message( + attachment_modify_message["body"], attachment_modify_message["headers"] + ) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert ( + message.summary + == "joequant@gmail.com updated something unknown for attachment on RHBZ#1701766 'I2C_HID_QUIRK_NO_IRQ_AFTER_RESET caused ...'" + ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_attachment_modify_no_changes_schema( - self, fakepublish, attachment_modify_message, relay - ): - """Check attachment.modify message schema bits when event is - missing 'changes' - unlike the bug.modify case I have not - actually seen a message like this in the wild, but we do - handle it just in case. - """ - # wipe the 'changes' dict from the sample message, to simulate - # one of these broken messages - del attachment_modify_message["body"]["event"]["changes"] - relay.on_stomp_message( - attachment_modify_message["body"], attachment_modify_message["headers"] - ) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - message.validate() - assert ( - message.summary - == "joequant@gmail.com updated something unknown for attachment on RHBZ#1701766 'I2C_HID_QUIRK_NO_IRQ_AFTER_RESET caused ...'" - ) - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_component_not_package_schema(self, fakepublish, bug_create_message, relay): - """Check we filter out components that aren't packages.""" - # adjust the component in the sample message to one we should - # filter out - bug_create_message["body"]["bug"]["component"]["name"] = "distribution" - relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception +def test_component_not_package_schema(fakepublish, bug_create_message, testrelay): + """Check we filter out components that aren't packages.""" + # adjust the component in the sample message to one we should + # filter out + bug_create_message["body"]["bug"]["component"]["name"] = "distribution" + testrelay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + message.validate() + assert message.packages == [] + + +def test_bug_no_qa_contact(fakepublish, bug_create_message, testrelay): + """Check bug.create message schema bits when qa_contact is None.""" + bug_create_message["body"]["bug"]["qa_contact"] = None + testrelay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) + assert fakepublish.call_count == 1 + message = fakepublish.call_args[0][0] + # this should not raise an exception + try: message.validate() - assert message.packages == [] - - @pytest.mark.parametrize("relay", (bz4relay, nobz4relay)) - @mock.patch("bugzilla2fedmsg.relay.publish", autospec=True) - def test_bug_no_qa_contact(self, fakepublish, bug_create_message, relay): - """Check bug.create message schema bits when qa_contact is None.""" - bug_create_message["body"]["bug"]["qa_contact"] = None - relay.on_stomp_message(bug_create_message["body"], bug_create_message["headers"]) - assert fakepublish.call_count == 1 - message = fakepublish.call_args[0][0] - # this should not raise an exception - try: - message.validate() - except ValidationError as e: - pytest.fail(e) - assert message.bug["qa_contact"] is None + except ValidationError as e: + pytest.fail(e) + assert message.bug["qa_contact"] is None