Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ops 2.10 relation broken behaviour fix #98

Merged
merged 3 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,9 @@ state_in = State(relations=[
PeerRelation(
endpoint="peers",
peers_data={1: {}, 2: {}, 42: {'foo': 'bar'}},
)],
unit_id=1)
)])

Context(...).run("start", state_in) # invalid: this unit's id cannot be the ID of a peer.
Context(..., unit_id=1).run("start", state_in) # invalid: this unit's id cannot be the ID of a peer.


```
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "ops-scenario"

version = "6.0"
version = "6.0.1"

authors = [
{ name = "Pietro Pasotti", email = "[email protected]" }
Expand Down
8 changes: 7 additions & 1 deletion scenario/ops_main_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ def setup_framework(
actions_metadata = None

meta = CharmMeta.from_yaml(metadata, actions_metadata)
model = ops.model.Model(meta, model_backend)

# If we are in a RelationBroken event, we want to know which relation is
# broken within the model, not only in the event's `.relation` attribute.
broken_relation_id = (
event.relation.relation_id if event.name.endswith("_relation_broken") else None # type: ignore
)
model = ops.model.Model(meta, model_backend, broken_relation_id=broken_relation_id)

charm_state_path = charm_dir / CHARM_STATE_FILE

Expand Down
32 changes: 29 additions & 3 deletions tests/test_e2e/test_relations.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
from typing import Type

import pytest
from ops.charm import CharmBase, CharmEvents, CollectStatusEvent, RelationDepartedEvent
from ops.charm import (
CharmBase,
CharmEvents,
CollectStatusEvent,
RelationDepartedEvent,
RelationEvent,
)
from ops.framework import EventBase, Framework

from scenario import Context
from scenario.state import (
PeerRelation,
Relation,
Expand Down Expand Up @@ -115,8 +122,15 @@ def test_relation_events(mycharm, evt_name, remote_app_name):
endpoint="foo", interface="foo", remote_app_name=remote_app_name
)

def callback(charm: CharmBase, _):
assert charm.model.get_relation("foo").app.name == remote_app_name
def callback(charm: CharmBase, e):
if not isinstance(e, RelationEvent):
return # filter out collect status events

if evt_name == "broken":
assert charm.model.get_relation("foo") is None
assert e.relation.app.name == remote_app_name
else:
assert charm.model.get_relation("foo").app.name == remote_app_name

mycharm._call = callback

Expand Down Expand Up @@ -357,3 +371,15 @@ def test_relation_ids():
for i in range(10):
rel = Relation("foo")
assert rel.relation_id == initial_id + i


def test_broken_relation_not_in_model_relations(mycharm):
rel = Relation("foo")

with Context(
mycharm, meta={"name": "local", "requires": {"foo": {"interface": "foo"}}}
).manager(rel.broken_event, state=State(relations=[rel])) as mgr:
charm = mgr.charm

assert charm.model.get_relation("foo") is None
assert charm.model.relations["foo"] == []
Loading