From 96f5ac53768b587156115d8de2e7d9166eaa8ce0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:28:59 -0300 Subject: [PATCH] Lock file maintenance Python dependencies (#752) * Lock file maintenance Python dependencies * Fix linting --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Dragomir Penev --- lib/charms/postgresql_k8s/v0/postgresql.py | 6 +- poetry.lock | 60 +++++++++---------- pyproject.toml | 6 +- src/backups.py | 16 ++--- src/charm.py | 2 +- src/relations/async_replication.py | 4 +- tests/integration/ha_tests/helpers.py | 42 ++++++------- .../ha_tests/test_async_replication.py | 2 +- .../integration/ha_tests/test_replication.py | 6 +- .../integration/ha_tests/test_self_healing.py | 42 ++++++------- tests/integration/ha_tests/test_upgrade.py | 6 +- .../ha_tests/test_upgrade_from_stable.py | 6 +- tests/integration/helpers.py | 38 ++++++------ tests/integration/new_relations/helpers.py | 2 +- .../new_relations/test_new_relations.py | 12 ++-- .../new_relations/test_relations_coherence.py | 16 ++--- tests/integration/test_backups.py | 18 +++--- tests/integration/test_backups_pitr.py | 48 +++++++-------- tests/integration/test_charm.py | 6 +- tests/integration/test_password_rotation.py | 6 +- tests/integration/test_tls.py | 6 +- 21 files changed, 176 insertions(+), 174 deletions(-) diff --git a/lib/charms/postgresql_k8s/v0/postgresql.py b/lib/charms/postgresql_k8s/v0/postgresql.py index 2f2b2f9990..8824f4dc38 100644 --- a/lib/charms/postgresql_k8s/v0/postgresql.py +++ b/lib/charms/postgresql_k8s/v0/postgresql.py @@ -36,7 +36,7 @@ # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 37 +LIBPATCH = 38 INVALID_EXTRA_USER_ROLE_BLOCKING_MESSAGE = "invalid role(s) for extra user roles" @@ -244,7 +244,7 @@ def create_user( privilege for privilege in privileges if privilege not in valid_privileges ] if len(invalid_privileges) > 0: - logger.error(f'Invalid extra user roles: {", ".join(privileges)}') + logger.error(f"Invalid extra user roles: {', '.join(privileges)}") raise PostgreSQLCreateUserError(INVALID_EXTRA_USER_ROLE_BLOCKING_MESSAGE) with self._connect_to_database() as connection, connection.cursor() as cursor: @@ -256,7 +256,7 @@ def create_user( user_definition = "CREATE ROLE {}" user_definition += f"WITH {'NOLOGIN' if user == 'admin' else 'LOGIN'}{' SUPERUSER' if admin else ''} ENCRYPTED PASSWORD '{password}'{'IN ROLE admin CREATEDB' if admin_role else ''}" if privileges: - user_definition += f' {" ".join(privileges)}' + user_definition += f" {' '.join(privileges)}" cursor.execute(sql.SQL("BEGIN;")) cursor.execute(sql.SQL("SET LOCAL log_statement = 'none';")) cursor.execute(sql.SQL(f"{user_definition};").format(sql.Identifier(user))) diff --git a/poetry.lock b/poetry.lock index 345ef505f4..79de6dd8de 100644 --- a/poetry.lock +++ b/poetry.lock @@ -162,17 +162,17 @@ typecheck = ["mypy"] [[package]] name = "boto3" -version = "1.35.47" +version = "1.35.50" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.35.47-py3-none-any.whl", hash = "sha256:0b307f685875e9c7857ce21c0d3050d8d4f3778455a6852d5f98ac75194b400e"}, - {file = "boto3-1.35.47.tar.gz", hash = "sha256:65b808e4cf1af8c2f405382d53656a0d92eee8f85c7388c43d64c7a5571b065f"}, + {file = "boto3-1.35.50-py3-none-any.whl", hash = "sha256:14724b905fd13f26d9d8f7cdcea0fa65a9acad79f60f41f7662667f4e233d97c"}, + {file = "boto3-1.35.50.tar.gz", hash = "sha256:4f15d1ccb481d66f6925b8c91c970ce41b956b6ecf7c479f23e2159531b37eec"}, ] [package.dependencies] -botocore = ">=1.35.47,<1.36.0" +botocore = ">=1.35.50,<1.36.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -181,13 +181,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.35.47" +version = "1.35.50" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.47-py3-none-any.whl", hash = "sha256:05f4493119a96799ff84d43e78691efac3177e1aec8840cca99511de940e342a"}, - {file = "botocore-1.35.47.tar.gz", hash = "sha256:f8f703463d3cd8b6abe2bedc443a7ab29f0e2ff1588a2e83164b108748645547"}, + {file = "botocore-1.35.50-py3-none-any.whl", hash = "sha256:965d3b99179ac04aa98e4c4baf4a970ebce77a5e02bb2a0a21cb6304e2bc0955"}, + {file = "botocore-1.35.50.tar.gz", hash = "sha256:136ecef8d5a1088f1ba485c0bbfca40abd42b9f9fe9e11d8cde4e53b4c05b188"}, ] [package.dependencies] @@ -829,13 +829,13 @@ tomli = {version = "*", markers = "python_version > \"3.6\" and python_version < [[package]] name = "ipython" -version = "8.28.0" +version = "8.29.0" description = "IPython: Productive Interactive Computing" optional = false python-versions = ">=3.10" files = [ - {file = "ipython-8.28.0-py3-none-any.whl", hash = "sha256:530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35"}, - {file = "ipython-8.28.0.tar.gz", hash = "sha256:0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a"}, + {file = "ipython-8.29.0-py3-none-any.whl", hash = "sha256:0188a1bd83267192123ccea7f4a8ed0a78910535dbaa3f37671dca76ebd429c8"}, + {file = "ipython-8.29.0.tar.gz", hash = "sha256:40b60e15b22591450eef73e40a027cf77bd652e757523eebc5bd7c7c498290eb"}, ] [package.dependencies] @@ -2099,29 +2099,29 @@ pyasn1 = ">=0.1.3" [[package]] name = "ruff" -version = "0.7.0" +version = "0.7.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, - {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, - {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, - {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, - {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, - {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, - {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, + {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, + {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, + {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, + {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, + {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, + {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, + {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, ] [[package]] @@ -2500,4 +2500,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "e690462427a55f6b4a04fad9f3cdf590a32be484c47cdb3a7ef1fb7fcc5ddd81" +content-hash = "7610b9ad787dcd54bee86041b3053b01c7148e1e46c864f228f37d9a5bc7f7fa" diff --git a/pyproject.toml b/pyproject.toml index 035e8ce60e..f6803cf8be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ package-mode = false python = "^3.10" ops = "^2.17.0" cryptography = "^43.0.3" -boto3 = "^1.35.47" +boto3 = "^1.35.50" pgconnstr = "^1.0.1" requests = "^2.32.3" tenacity = "^9.0.0" @@ -39,7 +39,7 @@ opentelemetry-exporter-otlp-proto-http = "1.21.0" optional = true [tool.poetry.group.format.dependencies] -ruff = "^0.7.0" +ruff = "^0.7.1" [tool.poetry.group.lint] optional = true @@ -72,7 +72,7 @@ allure-pytest-collection-report = {git = "https://github.com/canonical/data-plat # renovate caret doesn't work: https://github.com/renovatebot/renovate/issues/26940 juju = "<=3.5.2.0" psycopg2-binary = "^2.9.10" -boto3 = "^1.35.47" +boto3 = "^1.35.50" tenacity = "^9.0.0" allure-pytest = "^2.13.5" diff --git a/src/backups.py b/src/backups.py index 8cf2c3c7fd..d7e31cd442 100644 --- a/src/backups.py +++ b/src/backups.py @@ -177,7 +177,7 @@ def can_use_s3_repository(self) -> Tuple[bool, Optional[str]]: return False, ANOTHER_CLUSTER_REPOSITORY_ERROR_MESSAGE system_identifier_from_instance, error = self._execute_command([ - f'/usr/lib/postgresql/{self.charm._patroni.rock_postgresql_version.split(".")[0]}/bin/pg_controldata', + f"/usr/lib/postgresql/{self.charm._patroni.rock_postgresql_version.split('.')[0]}/bin/pg_controldata", "/var/lib/postgresql/data/pgdata", ]) if error != "": @@ -214,7 +214,7 @@ def _construct_endpoint(self, s3_parameters: Dict) -> str: # Use the built endpoint if it is an AWS endpoint. if endpoint_data and endpoint.endswith(endpoint_data["dnsSuffix"]): - endpoint = f'{endpoint.split("://")[0]}://{endpoint_data["hostname"]}' + endpoint = f"{endpoint.split('://')[0]}://{endpoint_data['hostname']}" return endpoint @@ -366,7 +366,7 @@ def _generate_backup_list_output(self) -> str: backup_reference = "None" if backup["reference"]: backup_reference, _ = self._parse_backup_id(backup["reference"][-1]) - lsn_start_stop = f'{backup["lsn"]["start"]} / {backup["lsn"]["stop"]}' + lsn_start_stop = f"{backup['lsn']['start']} / {backup['lsn']['stop']}" time_start, time_stop = ( datetime.strftime( datetime.fromtimestamp(stamp, timezone.utc), "%Y-%m-%dT%H:%M:%SZ" @@ -378,7 +378,7 @@ def _generate_backup_list_output(self) -> str: if backup["archive"] and backup["archive"]["start"] else "" ) - backup_path = f'/{self.stanza_name}/{backup["label"]}' + backup_path = f"/{self.stanza_name}/{backup['label']}" error = backup["error"] backup_status = "finished" if error: @@ -1060,16 +1060,16 @@ def _generate_fake_backup_id(self, backup_type: str) -> str: if last_full_backup is None: raise TypeError("Differential backup requested but no previous full backup") - return f'{last_full_backup}_{datetime.strftime(datetime.now(), "%Y%m%d-%H%M%SD")}' + return f"{last_full_backup}_{datetime.strftime(datetime.now(), '%Y%m%d-%H%M%SD')}" if backup_type == "incremental": backups = self._list_backups(show_failed=False, parse=False).keys() if not backups: raise TypeError("Incremental backup requested but no previous successful backup") - return f'{backups[-1]}_{datetime.strftime(datetime.now(), "%Y%m%d-%H%M%SI")}' + return f"{backups[-1]}_{datetime.strftime(datetime.now(), '%Y%m%d-%H%M%SI')}" def _fetch_backup_from_id(self, backup_id: str) -> str: """Fetches backup's pgbackrest label from backup id.""" - timestamp = f'{datetime.strftime(datetime.strptime(backup_id, "%Y-%m-%dT%H:%M:%SZ"), "%Y%m%d-%H%M%S")}' + timestamp = f"{datetime.strftime(datetime.strptime(backup_id, '%Y-%m-%dT%H:%M:%SZ'), '%Y%m%d-%H%M%S')}" backups = self._list_backups(show_failed=False, parse=False).keys() for label in backups: if timestamp in label: @@ -1253,7 +1253,7 @@ def _retrieve_s3_parameters(self) -> Tuple[Dict, List[str]]: # like Ceph Object Gateway (radosgw). s3_parameters["endpoint"] = s3_parameters["endpoint"].rstrip("/") s3_parameters["path"] = ( - f'/{s3_parameters["path"].strip("/")}' # The slash in the beginning is required by pgBackRest. + f"/{s3_parameters['path'].strip('/')}" # The slash in the beginning is required by pgBackRest. ) s3_parameters["bucket"] = s3_parameters["bucket"].strip("/") diff --git a/src/charm.py b/src/charm.py index 3135e8ba79..a9822fd06e 100755 --- a/src/charm.py +++ b/src/charm.py @@ -401,7 +401,7 @@ def postgresql(self) -> PostgreSQL: @property def endpoint(self) -> str: """Returns the endpoint of this instance's pod.""" - return f'{self._unit.replace("/", "-")}.{self._build_service_name("endpoints")}' + return f"{self._unit.replace('/', '-')}.{self._build_service_name('endpoints')}" @property def primary_endpoint(self) -> str: diff --git a/src/relations/async_replication.py b/src/relations/async_replication.py index c85b07ea5c..f10396c251 100644 --- a/src/relations/async_replication.py +++ b/src/relations/async_replication.py @@ -314,7 +314,7 @@ def get_system_identifier(self) -> Tuple[Optional[str], Optional[str]]: try: system_identifier, error = self.container.exec( [ - f'/usr/lib/postgresql/{self.charm._patroni.rock_postgresql_version.split(".")[0]}/bin/pg_controldata', + f"/usr/lib/postgresql/{self.charm._patroni.rock_postgresql_version.split('.')[0]}/bin/pg_controldata", POSTGRESQL_DATA_PATH, ], user=WORKLOAD_OS_USER, @@ -635,7 +635,7 @@ def _primary_cluster_endpoint(self) -> str: def _re_emit_async_relation_changed_event(self) -> None: """Re-emit the async relation changed event.""" relation = self._relation - getattr(self.charm.on, f'{relation.name.replace("-", "_")}_relation_changed').emit( + getattr(self.charm.on, f"{relation.name.replace('-', '_')}_relation_changed").emit( relation, app=relation.app, unit=[unit for unit in relation.units if unit.app == relation.app][0], diff --git a/tests/integration/ha_tests/helpers.py b/tests/integration/ha_tests/helpers.py index 49ba87c220..ab8ea58abc 100644 --- a/tests/integration/ha_tests/helpers.py +++ b/tests/integration/ha_tests/helpers.py @@ -177,9 +177,9 @@ async def change_wal_settings( async def is_cluster_updated(ops_test: OpsTest, primary_name: str) -> None: # Verify that the old primary is now a replica. - assert await is_replica( - ops_test, primary_name - ), "there are more than one primary in the cluster." + assert await is_replica(ops_test, primary_name), ( + "there are more than one primary in the cluster." + ) # Verify that all units are part of the same cluster. member_ips = await fetch_cluster_members(ops_test) @@ -194,9 +194,9 @@ async def is_cluster_updated(ops_test: OpsTest, primary_name: str) -> None: total_expected_writes = await check_writes(ops_test) # Verify that old primary is up-to-date. - assert await is_secondary_up_to_date( - ops_test, primary_name, total_expected_writes - ), f"secondary ({primary_name}) not up to date with the cluster after restarting." + assert await is_secondary_up_to_date(ops_test, primary_name, total_expected_writes), ( + f"secondary ({primary_name}) not up to date with the cluster after restarting." + ) def get_member_lag(cluster: Dict, member_name: str) -> int: @@ -230,9 +230,9 @@ async def check_writes(ops_test, extra_model: Model = None) -> int: total_expected_writes = await stop_continuous_writes(ops_test) actual_writes, max_number_written = await count_writes(ops_test, extra_model=extra_model) for member, count in actual_writes.items(): - assert ( - count == max_number_written[member] - ), f"{member}: writes to the db were missed: count of actual writes ({count}) on {member} different from the max number written ({max_number_written[member]})." + assert count == max_number_written[member], ( + f"{member}: writes to the db were missed: count of actual writes ({count}) on {member} different from the max number written ({max_number_written[member]})." + ) assert total_expected_writes == count, f"{member}: writes to the db were missed." return total_expected_writes @@ -256,9 +256,9 @@ async def are_writes_increasing( for member, count in writes.items(): if member in more_writes: members_checked.append(member) - assert ( - more_writes[member] > count - ), f"{member}: writes not continuing to DB (current writes: {more_writes[member]} - previous writes: {count})" + assert more_writes[member] > count, ( + f"{member}: writes not continuing to DB (current writes: {more_writes[member]} - previous writes: {count})" + ) assert len(members_checked), "No member checked from the initial writes" @@ -355,7 +355,7 @@ async def count_writes( f" host='{ip}' password='{password}' connect_timeout=10" ) - member_name = f'{member["model"]}.{member["name"]}' + member_name = f"{member['model']}.{member['name']}" connection = None try: with psycopg2.connect( @@ -703,9 +703,9 @@ async def modify_pebble_restart_delay( _preload_content=False, ) response.run_forever(timeout=5) - assert ( - response.returncode == 0 - ), f"Failed to add to pebble layer, unit={unit_name}, container={container_name}, service={service_name}" + assert response.returncode == 0, ( + f"Failed to add to pebble layer, unit={unit_name}, container={container_name}, service={service_name}" + ) for attempt in Retrying(stop=stop_after_delay(60), wait=wait_fixed(3), reraise=True): with attempt: @@ -732,9 +732,9 @@ async def modify_pebble_restart_delay( ) except (ProcessError, ProcessRunningError): pass - assert ( - response.returncode == 0 - ), f"Failed to replan pebble layer, unit={unit_name}, container={container_name}, service={service_name}" + assert response.returncode == 0, ( + f"Failed to replan pebble layer, unit={unit_name}, container={container_name}, service={service_name}" + ) async def is_postgresql_ready(ops_test, unit_name: str) -> bool: @@ -803,7 +803,7 @@ async def remove_charm_code(ops_test: OpsTest, unit_name: str) -> None: await run_command_on_unit( ops_test, unit_name, - f'rm /var/lib/juju/agents/unit-{unit_name.replace("/", "-")}/charm/src/charm.py', + f"rm /var/lib/juju/agents/unit-{unit_name.replace('/', '-')}/charm/src/charm.py", "charm", ) @@ -1045,7 +1045,7 @@ async def get_any_deatached_storage(ops_test: OpsTest) -> str: async def check_system_id_mismatch(ops_test: OpsTest, unit_name: str) -> bool: """Returns True if system id mismatch if found in logs.""" - log_str = f'CRITICAL: system ID mismatch, node {unit_name.replace("/", "-")} belongs to a different cluster' + log_str = f"CRITICAL: system ID mismatch, node {unit_name.replace('/', '-')} belongs to a different cluster" stdout = await run_command_on_unit( ops_test, unit_name, diff --git a/tests/integration/ha_tests/test_async_replication.py b/tests/integration/ha_tests/test_async_replication.py index fd113bda36..91cd0b1bf7 100644 --- a/tests/integration/ha_tests/test_async_replication.py +++ b/tests/integration/ha_tests/test_async_replication.py @@ -318,7 +318,7 @@ async def test_promote_standby( primary = await get_primary(ops_test) address = await get_unit_address(ops_test, primary) password = await get_password(ops_test) - database_name = f'{APPLICATION_NAME.replace("-", "_")}_database' + database_name = f"{APPLICATION_NAME.replace('-', '_')}_database" connection = None try: connection = psycopg2.connect( diff --git a/tests/integration/ha_tests/test_replication.py b/tests/integration/ha_tests/test_replication.py index c4a58297db..33ed3ed66b 100644 --- a/tests/integration/ha_tests/test_replication.py +++ b/tests/integration/ha_tests/test_replication.py @@ -134,8 +134,8 @@ async def test_no_data_replicated_between_clusters(ops_test: OpsTest, continuous "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'continuous_writes');" ) - assert not cursor.fetchone()[ - 0 - ], "table 'continuous_writes' was replicated to the second cluster" + assert not cursor.fetchone()[0], ( + "table 'continuous_writes' was replicated to the second cluster" + ) finally: connection.close() diff --git a/tests/integration/ha_tests/test_self_healing.py b/tests/integration/ha_tests/test_self_healing.py index 91a3408aa0..ba59e84764 100644 --- a/tests/integration/ha_tests/test_self_healing.py +++ b/tests/integration/ha_tests/test_self_healing.py @@ -196,9 +196,9 @@ async def test_full_cluster_restart( # they come back online they operate as expected. This check verifies that we meet the criteria # of all replicas being down at the same time. try: - assert await are_all_db_processes_down( - ops_test, process, signal - ), "Not all units down at the same time." + assert await are_all_db_processes_down(ops_test, process, signal), ( + "Not all units down at the same time." + ) finally: for unit in ops_test.model.applications[app].units: await modify_pebble_restart_delay( @@ -211,9 +211,9 @@ async def test_full_cluster_restart( # Verify all units are up and running. for unit in ops_test.model.applications[app].units: - assert await is_postgresql_ready( - ops_test, unit.name - ), f"unit {unit.name} not restarted after cluster restart." + assert await is_postgresql_ready(ops_test, unit.name), ( + f"unit {unit.name} not restarted after cluster restart." + ) await are_writes_increasing(ops_test) @@ -305,9 +305,9 @@ async def test_forceful_restart_without_data_and_transaction_logs( # Check that the WAL was correctly rotated. for unit_name in files: - assert not files[unit_name].intersection( - new_files - ), f"WAL segments weren't correctly rotated on {unit_name}" + assert not files[unit_name].intersection(new_files), ( + f"WAL segments weren't correctly rotated on {unit_name}" + ) # Database pebble service in old primary should recover after update-status run. async with ops_test.fast_forward("10s"): @@ -333,9 +333,9 @@ async def test_network_cut( # Verify that connection is possible. logger.info("checking whether the connectivity to the database is working") - assert await is_connection_possible( - ops_test, primary_name - ), f"Connection {primary_name} is not possible" + assert await is_connection_possible(ops_test, primary_name), ( + f"Connection {primary_name} is not possible" + ) # Confirm that the primary is not isolated from the cluster. logger.info("confirming that the primary is not isolated from the cluster") @@ -347,9 +347,9 @@ async def test_network_cut( # Verify that connection is not possible. logger.info("checking whether the connectivity to the database is not working") - assert not await is_connection_possible( - ops_test, primary_name - ), "Connection is possible after network cut" + assert not await is_connection_possible(ops_test, primary_name), ( + "Connection is possible after network cut" + ) logger.info("checking whether writes are increasing") await are_writes_increasing(ops_test, primary_name) @@ -376,9 +376,9 @@ async def test_network_cut( # Verify that connection is possible. logger.info("checking whether the connectivity to the database is working") - assert await is_connection_possible( - ops_test, primary_name - ), f"Connection is not possible to {primary_name} after network restore" + assert await is_connection_possible(ops_test, primary_name), ( + f"Connection is not possible to {primary_name} after network restore" + ) await is_cluster_updated(ops_test, primary_name) @@ -407,9 +407,9 @@ async def test_scaling_to_zero(ops_test: OpsTest, continuous_writes) -> None: # Verify all units are up and running. logger.info("waiting for the database service to start in all units") for unit in ops_test.model.applications[app].units: - assert await is_postgresql_ready( - ops_test, unit.name - ), f"unit {unit.name} not restarted after cluster restart." + assert await is_postgresql_ready(ops_test, unit.name), ( + f"unit {unit.name} not restarted after cluster restart." + ) logger.info("checking whether writes are increasing") await are_writes_increasing(ops_test) diff --git a/tests/integration/ha_tests/test_upgrade.py b/tests/integration/ha_tests/test_upgrade.py index 215ca65995..72c7ccf657 100644 --- a/tests/integration/ha_tests/test_upgrade.py +++ b/tests/integration/ha_tests/test_upgrade.py @@ -150,9 +150,9 @@ async def test_upgrade_from_edge(ops_test: OpsTest, continuous_writes) -> None: logger.info("checking the number of switchovers") final_number_of_switchovers = await count_switchovers(ops_test, primary_name) - assert ( - final_number_of_switchovers - initial_number_of_switchovers - ) <= 2, "Number of switchovers is greater than 2" + assert (final_number_of_switchovers - initial_number_of_switchovers) <= 2, ( + "Number of switchovers is greater than 2" + ) @pytest.mark.group(1) diff --git a/tests/integration/ha_tests/test_upgrade_from_stable.py b/tests/integration/ha_tests/test_upgrade_from_stable.py index b702ab2790..24e5d920af 100644 --- a/tests/integration/ha_tests/test_upgrade_from_stable.py +++ b/tests/integration/ha_tests/test_upgrade_from_stable.py @@ -153,6 +153,6 @@ async def test_upgrade_from_stable(ops_test: OpsTest, continuous_writes): if "pre-upgrade-check" in actions: logger.info("checking the number of switchovers") final_number_of_switchovers = await count_switchovers(ops_test, primary_name) - assert ( - final_number_of_switchovers - initial_number_of_switchovers - ) <= 2, "Number of switchovers is greater than 2" + assert (final_number_of_switchovers - initial_number_of_switchovers) <= 2, ( + "Number of switchovers is greater than 2" + ) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 778057d8d8..f44d695464 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -233,7 +233,7 @@ def construct_endpoint(endpoint: str, region: str) -> str: # Use the built endpoint if it is an AWS endpoint. if endpoint_data and endpoint.endswith(endpoint_data["dnsSuffix"]): - endpoint = f'{endpoint.split("://")[0]}://{endpoint_data["hostname"]}' + endpoint = f"{endpoint.split('://')[0]}://{endpoint_data['hostname']}" return endpoint @@ -967,23 +967,23 @@ async def backup_operations( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_1');" ) - assert cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_1' doesn't exist" + assert cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_1' doesn't exist" + ) cursor.execute( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_2');" ) - assert cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_2' doesn't exist" + assert cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_2' doesn't exist" + ) cursor.execute( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_3');" ) - assert not cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_3' exists" + assert not cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_3' exists" + ) connection.close() # Run the "restore backup" action for full backup. @@ -1012,21 +1012,21 @@ async def backup_operations( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_1');" ) - assert cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_1' doesn't exist" + assert cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_1' doesn't exist" + ) cursor.execute( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_2');" ) - assert not cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_2' exists" + assert not cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_2' exists" + ) cursor.execute( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_3');" ) - assert not cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_3' exists" + assert not cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_3' exists" + ) connection.close() diff --git a/tests/integration/new_relations/helpers.py b/tests/integration/new_relations/helpers.py index 8b00147dc1..5c4d270216 100644 --- a/tests/integration/new_relations/helpers.py +++ b/tests/integration/new_relations/helpers.py @@ -47,7 +47,7 @@ async def build_connection_string( """ # Get the connection data exposed to the application through the relation. if database is None: - database = f'{application_name.replace("-", "_")}_{relation_name.replace("-", "_")}' + database = f"{application_name.replace('-', '_')}_{relation_name.replace('-', '_')}" if secret_uri := await get_application_relation_data( ops_test, diff --git a/tests/integration/new_relations/test_new_relations.py b/tests/integration/new_relations/test_new_relations.py index e4e881f9db..d8d08733b8 100644 --- a/tests/integration/new_relations/test_new_relations.py +++ b/tests/integration/new_relations/test_new_relations.py @@ -496,15 +496,15 @@ async def test_admin_role(ops_test: OpsTest): should_fail = database == "postgres" cursor.execute(f"CREATE TABLE {random_name}(data TEXT);") if should_fail: - assert ( - False - ), f"failed to run a statement in the following database: {database}" + assert False, ( + f"failed to run a statement in the following database: {database}" + ) except psycopg2.errors.InsufficientPrivilege as e: if not should_fail: logger.exception(e) - assert ( - False - ), f"failed to connect to or run a statement in the following database: {database}" + assert False, ( + f"failed to connect to or run a statement in the following database: {database}" + ) finally: if connection is not None: connection.close() diff --git a/tests/integration/new_relations/test_relations_coherence.py b/tests/integration/new_relations/test_relations_coherence.py index cb08f2b560..4dc301bdd3 100644 --- a/tests/integration/new_relations/test_relations_coherence.py +++ b/tests/integration/new_relations/test_relations_coherence.py @@ -100,9 +100,9 @@ async def test_relations(ops_test: OpsTest, database_charm): ) cursor.execute(f"CREATE DATABASE {random_name};") except psycopg2.errors.InsufficientPrivilege: - assert ( - False - ), f"failed connect to {random_name} or run a statement in the following database" + assert False, ( + f"failed connect to {random_name} or run a statement in the following database" + ) finally: connection.close() @@ -141,13 +141,15 @@ async def test_relations(ops_test: OpsTest, database_charm): random_name = f"test_{''.join(secrets.choice(string.ascii_lowercase) for _ in range(10))}" cursor.execute(f"CREATE TABLE {random_name}(data TEXT);") if should_fail: - assert ( - False - ), f"failed to run a statement in the following database: {database}" + assert False, ( + f"failed to run a statement in the following database: {database}" + ) except psycopg2.errors.InsufficientPrivilege as e: if not should_fail: logger.exception(e) - assert False, f"failed to connect to or run a statement in the following database: {database}" + assert False, ( + f"failed to connect to or run a statement in the following database: {database}" + ) except psycopg2.OperationalError as e: if not should_fail: logger.exception(e) diff --git a/tests/integration/test_backups.py b/tests/integration/test_backups.py index b31c7120fa..8252d8811e 100644 --- a/tests/integration/test_backups.py +++ b/tests/integration/test_backups.py @@ -150,16 +150,16 @@ async def test_backup_aws(ops_test: OpsTest, cloud_configs: Tuple[Dict, Dict]) - "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_1');" ) - assert cursor.fetchone()[ - 0 - ], f"replication isn't working correctly: table 'backup_table_1' doesn't exist in {new_unit_name}" + assert cursor.fetchone()[0], ( + f"replication isn't working correctly: table 'backup_table_1' doesn't exist in {new_unit_name}" + ) cursor.execute( "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_2');" ) - assert not cursor.fetchone()[ - 0 - ], f"replication isn't working correctly: table 'backup_table_2' exists in {new_unit_name}" + assert not cursor.fetchone()[0], ( + f"replication isn't working correctly: table 'backup_table_2' exists in {new_unit_name}" + ) connection.close() old_primary = await get_primary(ops_test, database_app_name) @@ -312,9 +312,9 @@ async def test_restore_on_new_cluster(ops_test: OpsTest, github_secrets) -> None "SELECT EXISTS (SELECT FROM information_schema.tables" " WHERE table_schema = 'public' AND table_name = 'backup_table_1');" ) - assert cursor.fetchone()[ - 0 - ], "backup wasn't correctly restored: table 'backup_table_1' doesn't exist" + assert cursor.fetchone()[0], ( + "backup wasn't correctly restored: table 'backup_table_1' doesn't exist" + ) connection.close() diff --git a/tests/integration/test_backups_pitr.py b/tests/integration/test_backups_pitr.py index 1408d7f8b7..0ea579c884 100644 --- a/tests/integration/test_backups_pitr.py +++ b/tests/integration/test_backups_pitr.py @@ -192,9 +192,9 @@ async def pitr_backup_operations( "restore", **{"backup-id": backup_b1, "restore-to-time": "bad data"} ) await action.wait() - assert ( - action.status == "failed" - ), "1: restore must fail with bad restore-to-time parameter, but that action succeeded" + assert action.status == "failed", ( + "1: restore must fail with bad restore-to-time parameter, but that action succeeded" + ) logger.info("1: restoring the backup b1 with unreachable restore-to-time parameter") action = await ops_test.model.units.get(f"{database_app_name}/0").run_action( @@ -235,9 +235,9 @@ async def pitr_backup_operations( assert _check_test_data("test_data_td1", address, password), "2: test data td1 should exist" logger.info("2: checking not test data td2") - assert not _check_test_data( - "test_data_td2", address, password - ), "2: test data td2 shouldn't exist" + assert not _check_test_data("test_data_td2", address, password), ( + "2: test data td2 shouldn't exist" + ) logger.info("2: creating test data td3") _insert_test_data("test_data_td3", address, password) @@ -271,9 +271,9 @@ async def pitr_backup_operations( primary = await get_primary(ops_test, database_app_name) address = await get_unit_address(ops_test, primary) timeline_t3 = await _get_most_recent_backup(ops_test, remaining_unit) - assert ( - backup_b1 != timeline_t3 and timeline_t2 != timeline_t3 - ), "3: timeline 3 do not exist in list-backups action or bad" + assert backup_b1 != timeline_t3 and timeline_t2 != timeline_t3, ( + "3: timeline 3 do not exist in list-backups action or bad" + ) logger.info("3: checking test data td1") assert _check_test_data("test_data_td1", address, password), "3: test data td1 should exist" @@ -282,14 +282,14 @@ async def pitr_backup_operations( assert _check_test_data("test_data_td2", address, password), "3: test data td2 should exist" logger.info("3: checking not test data td3") - assert not _check_test_data( - "test_data_td3", address, password - ), "3: test data td3 shouldn't exist" + assert not _check_test_data("test_data_td3", address, password), ( + "3: test data td3 shouldn't exist" + ) logger.info("3: checking not test data td4") - assert not _check_test_data( - "test_data_td4", address, password - ), "3: test data td4 shouldn't exist" + assert not _check_test_data("test_data_td4", address, password), ( + "3: test data td4 shouldn't exist" + ) logger.info("3: switching wal") _switch_wal(address, password) @@ -319,9 +319,9 @@ async def pitr_backup_operations( assert _check_test_data("test_data_td1", address, password), "4: test data td1 should exist" logger.info("4: checking not test data td2") - assert not _check_test_data( - "test_data_td2", address, password - ), "4: test data td2 shouldn't exist" + assert not _check_test_data("test_data_td2", address, password), ( + "4: test data td2 shouldn't exist" + ) logger.info("4: checking test data td3") assert _check_test_data("test_data_td3", address, password), "4: test data td3 should exist" @@ -360,17 +360,17 @@ async def pitr_backup_operations( assert _check_test_data("test_data_td1", address, password), "5: test data td1 should exist" logger.info("5: checking not test data td2") - assert not _check_test_data( - "test_data_td2", address, password - ), "5: test data td2 shouldn't exist" + assert not _check_test_data("test_data_td2", address, password), ( + "5: test data td2 shouldn't exist" + ) logger.info("5: checking test data td3") assert _check_test_data("test_data_td3", address, password), "5: test data td3 should exist" logger.info("5: checking not test data td4") - assert not _check_test_data( - "test_data_td4", address, password - ), "5: test data td4 shouldn't exist" + assert not _check_test_data("test_data_td4", address, password), ( + "5: test data td4 shouldn't exist" + ) await ops_test.model.wait_for_idle(status="active", timeout=1000) diff --git a/tests/integration/test_charm.py b/tests/integration/test_charm.py index 41741681e1..d1dfdec2b9 100644 --- a/tests/integration/test_charm.py +++ b/tests/integration/test_charm.py @@ -90,9 +90,9 @@ async def test_exporter_is_up(ops_test: OpsTest, unit_id: int): host = await get_unit_address(ops_test, f"{APP_NAME}/{unit_id}") result = requests.get(f"http://{host}:9187/metrics") assert result.status_code == 200 - assert "pg_exporter_last_scrape_error 0" in result.content.decode( - "utf8" - ), "Scrape error in postgresql_prometheus_exporter" + assert "pg_exporter_last_scrape_error 0" in result.content.decode("utf8"), ( + "Scrape error in postgresql_prometheus_exporter" + ) @pytest.mark.group(1) diff --git a/tests/integration/test_password_rotation.py b/tests/integration/test_password_rotation.py index b2d4be63af..a9695a9469 100644 --- a/tests/integration/test_password_rotation.py +++ b/tests/integration/test_password_rotation.py @@ -183,6 +183,6 @@ async def test_no_password_exposed_on_logs(ops_test: OpsTest) -> None: continue regex = re.compile("(PASSWORD )(?!)") logs_without_false_positives = regex.findall(logs) - assert ( - len(logs_without_false_positives) == 0 - ), f"Sensitive information detected on {unit.name} logs" + assert len(logs_without_false_positives) == 0, ( + f"Sensitive information detected on {unit.name} logs" + ) diff --git a/tests/integration/test_tls.py b/tests/integration/test_tls.py index bb51644ed1..0b49d95ea2 100644 --- a/tests/integration/test_tls.py +++ b/tests/integration/test_tls.py @@ -72,9 +72,9 @@ async def check_tls_rewind(ops_test: OpsTest) -> None: continue if "connection authorized: user=rewind database=postgres SSL enabled" in logs: break - assert ( - "connection authorized: user=rewind database=postgres SSL enabled" in logs - ), "TLS is not being used on pg_rewind connections" + assert "connection authorized: user=rewind database=postgres SSL enabled" in logs, ( + "TLS is not being used on pg_rewind connections" + ) @pytest.mark.group(1)