diff --git a/pyproject.toml b/pyproject.toml index 1c1ae2ae..ac35451c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta" [project] name = "ops-scenario" -version = "6.1.2" +version = "6.1.3" authors = [ { name = "Pietro Pasotti", email = "pietro.pasotti@canonical.com" } diff --git a/scenario/runtime.py b/scenario/runtime.py index 3cb67f0b..71b109a5 100644 --- a/scenario/runtime.py +++ b/scenario/runtime.py @@ -272,6 +272,8 @@ def _get_event_env(self, state: "State", event: "Event", charm_root: Path): "JUJU_SECRET_LABEL": secret.label or "", }, ) + if event.name in ("secret_remove", "secret_expired"): + env["JUJU_SECRET_REVISION"] = str(secret.revision) return env diff --git a/scenario/state.py b/scenario/state.py index 70c8e985..d8be99cb 100644 --- a/scenario/state.py +++ b/scenario/state.py @@ -106,7 +106,7 @@ SECRET_EVENTS = { "secret_changed", - "secret_removed", + "secret_remove", "secret_rotate", "secret_expired", } @@ -292,18 +292,18 @@ def expired_event(self): """Sugar to generate a secret-expired event.""" if not self.owner: raise ValueError( - "This unit will never receive secret-expire for a secret it does not own.", + "This unit will never receive secret-expired for a secret it does not own.", ) - return Event("secret_expire", secret=self) + return Event("secret_expired", secret=self) @property def remove_event(self): """Sugar to generate a secret-remove event.""" if not self.owner: raise ValueError( - "This unit will never receive secret-removed for a secret it does not own.", + "This unit will never receive secret-remove for a secret it does not own.", ) - return Event("secret_removed", secret=self) + return Event("secret_remove", secret=self) def _set_revision(self, revision: int): """Set a new tracked revision.""" diff --git a/tests/test_e2e/test_event.py b/tests/test_e2e/test_event.py index 07c8d30a..f30fc65a 100644 --- a/tests/test_e2e/test_event.py +++ b/tests/test_e2e/test_event.py @@ -19,7 +19,7 @@ ("foo_bar_baz_pebble_ready", _EventType.workload), ("foo_pebble_custom_notice", _EventType.workload), ("foo_bar_baz_pebble_custom_notice", _EventType.workload), - ("secret_removed", _EventType.secret), + ("secret_remove", _EventType.secret), ("pre_commit", _EventType.framework), ("commit", _EventType.framework), ("collect_unit_status", _EventType.framework), diff --git a/tests/test_e2e/test_secrets.py b/tests/test_e2e/test_secrets.py index 9ff80d29..26988245 100644 --- a/tests/test_e2e/test_secrets.py +++ b/tests/test_e2e/test_secrets.py @@ -2,6 +2,12 @@ import warnings import pytest +from ops import ( + SecretChangedEvent, + SecretExpiredEvent, + SecretRemoveEvent, + SecretRotateEvent, +) from ops.charm import CharmBase from ops.framework import Framework from ops.model import ModelError @@ -554,3 +560,31 @@ def __init__(self, *args): secret.remove_all_revisions() assert not mgr.output.secrets[0].contents # secret wiped + + +@pytest.mark.parametrize( + "evt,owner,cls", + ( + ("changed", None, SecretChangedEvent), + ("rotate", "app", SecretRotateEvent), + ("expired", "app", SecretExpiredEvent), + ("remove", "app", SecretRemoveEvent), + ), +) +def test_emit_event(evt, owner, cls): + class MyCharm(CharmBase): + def __init__(self, framework): + super().__init__(framework) + for evt in self.on.events().values(): + self.framework.observe(evt, self._on_event) + self.events = [] + + def _on_event(self, event): + self.events.append(event) + + ctx = Context(MyCharm, meta={"name": "local"}) + secret = Secret(contents={"foo": "bar"}, id="foo", owner=owner) + with ctx.manager(getattr(secret, evt + "_event"), State(secrets=[secret])) as mgr: + mgr.run() + juju_event = mgr.charm.events[0] # Ignore collect-status etc. + assert isinstance(juju_event, cls)