From df856d226f19848a1906abfb2e331425da55d85b Mon Sep 17 00:00:00 2001 From: Tony Meyer Date: Mon, 16 Dec 2024 15:28:37 +1300 Subject: [PATCH] test: handle warnings generated by our own tests (#1469) Our tests currently end with a very large list of warnings. This PR fixes that: * All of the Harness tests emit a `PendingDeprecationWarning` telling us that Harness is going away and we should use Scenario. This seems like something to simply ignore in our own tests, so I've added a `-W` argument to Python to silence them in bulk. * One `test_main` test raises a warning about controller storage going away - there's another test that tests that warning happens, and the two tests are otherwise identical. I've merged the two - we don't need them both. * Two of the secret tests check that `SecretInfo` objects can still be created without providing the model UUID. I've added a `pytest.warns` to (a) ensure that there's the warning, and (b) stop it appearing in the tox output. * Scenario should provide the model UUID when creating `SecretInfo` objects. This is a one-line fix, so I've added it here - it stops deprecation warnings, but is really more the code than the tests, but since it's so small I think it's ok here. * The `context.on` Scenario tests check that pre- and post- series upgrade events work, and those raise warnings. I've split them off to a separate test that verifies (and silences) the warning. Fixes #1408 --- test/test_main.py | 6 ------ test/test_model.py | 6 ++++-- testing/src/scenario/mocking.py | 1 + testing/tests/test_context_on.py | 21 +++++++++++++++++++-- tox.ini | 3 ++- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/test/test_main.py b/test/test_main.py index 65172b00e..19565e27f 100644 --- a/test/test_main.py +++ b/test/test_main.py @@ -189,12 +189,6 @@ def test_storage_no_storage(self): def test_storage_with_storage(self): # here we patch juju_backend_available, so it gets set up and falls over when used - with patch('ops.storage.juju_backend_available') as juju_backend_available: - juju_backend_available.return_value = True - with pytest.raises(FileNotFoundError, match='state-get'): - self._check(ops.CharmBase, use_juju_for_storage=True) - - def test_controller_storage_deprecated(self): with patch('ops.storage.juju_backend_available') as juju_backend_available: juju_backend_available.return_value = True with pytest.warns(DeprecationWarning, match='Controller storage'): diff --git a/test/test_model.py b/test/test_model.py index 541eeb1f5..ae1fbaa81 100644 --- a/test/test_model.py +++ b/test/test_model.py @@ -3643,11 +3643,13 @@ def test_from_dict(self): assert info.rotates is None assert info.description is None - info = ops.SecretInfo.from_dict('5', {'revision': 9}) + with pytest.warns(DeprecationWarning, match='`model_uuid` should always be provided'): + info = ops.SecretInfo.from_dict('5', {'revision': 9}) assert info.id == 'secret:5' assert info.revision == 9 - info = ops.SecretInfo.from_dict('secret://abcd/6', {'revision': 9}) + with pytest.warns(DeprecationWarning, match='`model_uuid` should always be provided'): + info = ops.SecretInfo.from_dict('secret://abcd/6', {'revision': 9}) assert info.id == 'secret://abcd/6' assert info.revision == 9 diff --git a/testing/src/scenario/mocking.py b/testing/src/scenario/mocking.py index b95b553be..3e1bcd4f9 100644 --- a/testing/src/scenario/mocking.py +++ b/testing/src/scenario/mocking.py @@ -481,6 +481,7 @@ def secret_info_get( expires=secret.expire, rotation=secret.rotate, rotates=None, # not implemented yet. + model_uuid=self._state.model.uuid, ) def secret_set( diff --git a/testing/tests/test_context_on.py b/testing/tests/test_context_on.py index 402de45ce..521cfb973 100644 --- a/testing/tests/test_context_on.py +++ b/testing/tests/test_context_on.py @@ -56,8 +56,6 @@ def _on_event(self, event: ops.EventBase): ("update_status", ops.UpdateStatusEvent), ("config_changed", ops.ConfigChangedEvent), ("upgrade_charm", ops.UpgradeCharmEvent), - ("pre_series_upgrade", ops.PreSeriesUpgradeEvent), - ("post_series_upgrade", ops.PostSeriesUpgradeEvent), ("leader_elected", ops.LeaderElectedEvent), ], ) @@ -72,6 +70,25 @@ def test_simple_events(event_name: str, event_kind: typing.Type[ops.EventBase]): assert isinstance(mgr.charm.observed[0], event_kind) +@pytest.mark.parametrize( + "event_name, event_kind", + [ + ("pre_series_upgrade", ops.PreSeriesUpgradeEvent), + ("post_series_upgrade", ops.PostSeriesUpgradeEvent), + ], +) +def test_simple_deprecated_events(event_name, event_kind): + ctx = scenario.Context(ContextCharm, meta=META, actions=ACTIONS) + # These look like: + # ctx.run(ctx.on.pre_series_upgrade(), state) + with pytest.warns(DeprecationWarning): + with ctx(getattr(ctx.on, event_name)(), scenario.State()) as mgr: + mgr.run() + assert len(mgr.charm.observed) == 2 + assert isinstance(mgr.charm.observed[1], ops.CollectStatusEvent) + assert isinstance(mgr.charm.observed[0], event_kind) + + @pytest.mark.parametrize("as_kwarg", [True, False]) @pytest.mark.parametrize( "event_name,event_kind,owner", diff --git a/tox.ini b/tox.ini index 4594afbd4..fecaa4ba7 100644 --- a/tox.ini +++ b/tox.ini @@ -104,7 +104,8 @@ deps = -e . -e testing commands = - pytest -n auto --ignore={[vars]tst_path}smoke -v --tb native {posargs} + pytest -n auto --ignore={[vars]tst_path}smoke -v --tb native \ + -W 'ignore:Harness is deprecated:PendingDeprecationWarning' {posargs} [testenv:coverage] description = Run unit tests with coverage