Skip to content

Commit

Permalink
Add the snapshot data for all the events to deferred().
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyandrewmeyer committed Aug 14, 2024
1 parent c6f05db commit 7f9ae39
Showing 1 changed file with 51 additions and 14 deletions.
65 changes: 51 additions & 14 deletions scenario/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1570,12 +1570,18 @@ class DeferredEvent:
# needs to be marshal.dumps-able.
snapshot_data: Dict = dataclasses.field(default_factory=dict)

# It would be nicer if people could do something like:
# `isinstance(state.deferred[0], ops.StartEvent)`
# than comparing with the string names, but there's only one `_Event`
# class in Scenario, and it also needs to be created from the context,
# which is not available here. For the ops classes, it's complex to create
# them because they need a Handle.
@property
def name(self):
return self.handle_path.split("/")[-1].split("[")[0]


class _EventType(str, Enum):
class _EventType(str, Enum): #
framework = "framework"
builtin = "builtin"
relation = "relation"
Expand Down Expand Up @@ -1777,17 +1783,17 @@ def deferred(self, handler: Callable, event_id: int = 1) -> DeferredEvent:
owner_name, handler_name = match.groups()[0].split(".")[-2:]
handle_path = f"{owner_name}/on/{self.name}[{event_id}]"

# Many events have no snapshot data: install, start, stop, remove, config-changed,
# upgrade-charm, pre-series-upgrade, post-series-upgrade, leader-elected,
# leader-settings-changed, collect-metrics
snapshot_data = {}

# fixme: at this stage we can't determine if the event is a builtin one or not; if it is
# not, then the coming checks are meaningless: the custom event could be named like a
# relation event but not *be* one.
if self._is_workload_event:
# this is a WorkloadEvent. The snapshot:
container = cast(Container, self.container)
snapshot_data = {
"container_name": container.name,
}
assert self.container is not None
snapshot_data["container_name"] = self.container.name
if self.notice:
if hasattr(self.notice.type, "value"):
notice_type = cast(pebble.NoticeType, self.notice.type).value
Expand All @@ -1804,21 +1810,52 @@ def deferred(self, handler: Callable, event_id: int = 1) -> DeferredEvent:
snapshot_data["check_name"] = self.check_info.name

elif self._is_relation_event:
# this is a RelationEvent.
relation = cast("AnyRelation", self.relation)
assert self.relation is not None
relation = self.relation
if isinstance(relation, PeerRelation):
# FIXME: relation.unit for peers should point to <this unit>, but we
# don't have access to the local app name in this context.
remote_app = "local"
else:
remote_app = relation.remote_app_name

snapshot_data = {
"relation_name": relation.endpoint,
"relation_id": relation.id,
"app_name": remote_app,
"unit_name": f"{remote_app}/{self.relation_remote_unit_id}",
}
snapshot_data.update(
{
"relation_name": relation.endpoint,
"relation_id": relation.id,
"app_name": remote_app,
},
)
if not self.name.endswith(("_created", "_broken")):
snapshot_data[
"unit_name"
] = f"{remote_app}/{self.relation_remote_unit_id}"
if self.name.endswith("_departed"):
snapshot_data[
"departing_unit"
] = f"{remote_app}/{self.relation_departed_unit_id}"

elif self._is_storage_event:
assert self.storage is not None
snapshot_data.update(
{
"storage_name": self.storage.name,
"storage_index": self.storage.index,
# "storage_location": str(self.storage.get_filesystem(self._context)),
},
)

elif self._is_secret_event:
assert self.secret is not None
snapshot_data.update(
{"secret_id": self.secret.id, "secret_label": self.secret.label},
)
if self.name.endswith(("_remove", "_expired")):
snapshot_data["secret_revision"] = self.secret_revision

elif self._is_action_event:
assert self.action is not None
snapshot_data["id"] = self.action.id

return DeferredEvent(
handle_path,
Expand Down

0 comments on commit 7f9ae39

Please sign in to comment.