From 6bb5d7aa5eca042c395368dc51ba164637a235f2 Mon Sep 17 00:00:00 2001 From: SAY-5 Date: Tue, 5 May 2026 03:17:13 -0700 Subject: [PATCH 1/2] fix: make create-replication action fail cleanly without async-replication relation Signed-off-by: SAY-5 --- src/relations/async_replication.py | 7 +++++++ tests/unit/test_async_replication.py | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/relations/async_replication.py b/src/relations/async_replication.py index 4518b7598e8..e9db11cd023 100644 --- a/src/relations/async_replication.py +++ b/src/relations/async_replication.py @@ -567,6 +567,13 @@ def _on_create_replication(self, event: ActionEvent) -> None: event.fail("There is already a replication set up.") return + if self._relation is None: + event.fail( + "No async-replication relation has been established." + " Create the offer and relate the two clusters before running this action." + ) + return + if self._relation.name == REPLICATION_CONSUMER_RELATION: event.fail("This action must be run in the cluster where the offer was created.") return diff --git a/tests/unit/test_async_replication.py b/tests/unit/test_async_replication.py index 0174a0080d1..4e6772c0e0f 100644 --- a/tests/unit/test_async_replication.py +++ b/tests/unit/test_async_replication.py @@ -571,6 +571,23 @@ def test_on_create_replication(): assert result is None + # 5. No async-replication relation established (regression for #1675). + mock_charm = MagicMock() + mock_event = MagicMock() + + relation = PostgreSQLAsyncReplication(mock_charm) + + relation._get_primary_cluster = MagicMock(return_value=None) + type(relation)._relation = PropertyMock(return_value=None) + + result = relation._on_create_replication(mock_event) + + assert result is None + mock_event.fail.assert_called_once_with( + "No async-replication relation has been established." + " Create the offer and relate the two clusters before running this action." + ) + def test_promote_to_primary(): # 1. From dd6495aa3239ed8701ed982e4639cfc2ea256ade Mon Sep 17 00:00:00 2001 From: SAY-5 Date: Tue, 5 May 2026 14:28:00 -0700 Subject: [PATCH 2/2] fix(test): scope PropertyMock to prevent class-level leak Signed-off-by: SAY-5 --- tests/unit/test_async_replication.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_async_replication.py b/tests/unit/test_async_replication.py index 4e6772c0e0f..379207dcfdd 100644 --- a/tests/unit/test_async_replication.py +++ b/tests/unit/test_async_replication.py @@ -578,9 +578,11 @@ def test_on_create_replication(): relation = PostgreSQLAsyncReplication(mock_charm) relation._get_primary_cluster = MagicMock(return_value=None) - type(relation)._relation = PropertyMock(return_value=None) - result = relation._on_create_replication(mock_event) + with patch.object( + PostgreSQLAsyncReplication, "_relation", new_callable=PropertyMock, return_value=None + ): + result = relation._on_create_replication(mock_event) assert result is None mock_event.fail.assert_called_once_with(