Skip to content

Commit

Permalink
Merge branch 'main' into add-storage-clearer-use-1127
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyandrewmeyer authored Mar 18, 2024
2 parents c83d77f + 5804652 commit 77f280c
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
17 changes: 17 additions & 0 deletions ops/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,9 @@ def add_relation(self, relation_name: str, remote_app: str, *,
This function creates a relation with an application and triggers a
:class:`RelationCreatedEvent <ops.RelationCreatedEvent>`.
To match Juju's behaviour, it also creates a default network binding on this endpoint.
If you want to associate a custom network to this binding (or a global default network),
provide one using :meth:`add_network` before calling this function.
If `app_data` or `unit_data` are provided, also add a new unit
(``<remote_app>/0``) to the relation and trigger
Expand Down Expand Up @@ -836,6 +839,11 @@ def add_relation(self, relation_name: str, remote_app: str, *,
Return:
The ID of the relation created.
"""
if not (relation_name in self._meta.provides
or relation_name in self._meta.requires
or relation_name in self._meta.peers):
raise RelationNotFoundError(f'relation {relation_name!r} not declared in metadata')

relation_id = self._next_relation_id()
self._backend._relation_ids_map.setdefault(
relation_name, []).append(relation_id)
Expand Down Expand Up @@ -863,6 +871,15 @@ def add_relation(self, relation_name: str, remote_app: str, *,
if unit_data is not None:
self.update_relation_data(relation_id, remote_unit, unit_data)

# If we have a default network binding configured, respect it.
if not self._backend._networks.get((None, None)):
# If we don't already have a network binding for this relation id, create one.
if not self._backend._networks.get((relation_name, relation_id)):
self.add_network("10.0.0.10", endpoint=relation_name, relation_id=relation_id)
# If we don't already have a default network binding for this endpoint, create one.
if not self._backend._networks.get((relation_name, None)):
self.add_network("192.0.2.0", endpoint=relation_name)

return relation_id

def remove_relation(self, relation_id: int) -> None:
Expand Down
47 changes: 38 additions & 9 deletions test/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ def on_storage_changed(self, event: ops.EventBase):


class TestHarness(unittest.TestCase):
def test_add_relation_no_meta_fails(self):
harness = ops.testing.Harness(ops.CharmBase, meta="name: mycharm")
self.addCleanup(harness.cleanup)
with self.assertRaises(ops.RelationNotFoundError):
harness.add_relation('db', 'postgresql')

def test_add_relation(self):
harness = ops.testing.Harness(ops.CharmBase, meta='''
Expand Down Expand Up @@ -3048,6 +3053,12 @@ def test_network_get_relation_not_found(self):
assert binding is not None
binding.network

def test_add_relation_network_get(self):
self.harness.add_relation('db', 'remote')
binding = self.harness.model.get_binding('db')
assert binding is not None
assert binding.network

def test_add_network_endpoint_not_in_meta(self):
with self.assertRaises(ops.ModelError):
self.harness.add_network('35.0.0.1', endpoint='xyz')
Expand Down Expand Up @@ -4831,7 +4842,9 @@ def test_storage_multiple_storage_instances(self):

class TestSecrets(unittest.TestCase):
def test_add_model_secret_by_app_name_str(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand All @@ -4843,7 +4856,9 @@ def test_add_model_secret_by_app_name_str(self):
self.assertEqual(secret.get_content(), {'password': 'hunter2'})

def test_add_model_secret_by_app_instance(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand All @@ -4856,7 +4871,9 @@ def test_add_model_secret_by_app_instance(self):
self.assertEqual(secret.get_content(), {'password': 'hunter3'})

def test_add_model_secret_by_unit_instance(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand All @@ -4869,7 +4886,9 @@ def test_add_model_secret_by_unit_instance(self):
self.assertEqual(secret.get_content(), {'password': 'hunter4'})

def test_get_secret_as_owner(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
harness.begin()
# App secret.
Expand Down Expand Up @@ -4929,7 +4948,9 @@ def test_add_model_secret_invalid_content(self):
harness.add_model_secret('database', {'x': 'y'}) # key too short

def test_set_secret_content(self):
harness = ops.testing.Harness(EventRecorder, meta='name: webapp')
harness = ops.testing.Harness(EventRecorder, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand Down Expand Up @@ -4975,7 +4996,9 @@ def test_set_secret_content_invalid_content(self):
harness.set_secret_content(secret_id, {'x': 'y'})

def test_grant_secret_and_revoke_secret(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand All @@ -4991,7 +5014,9 @@ def test_grant_secret_and_revoke_secret(self):
harness.model.get_secret(id=secret_id)

def test_grant_secret_wrong_app(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand All @@ -5002,7 +5027,9 @@ def test_grant_secret_wrong_app(self):
harness.model.get_secret(id=secret_id)

def test_grant_secret_wrong_unit(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: webapp')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'webapp', 'requires': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)
relation_id = harness.add_relation('db', 'database')
harness.add_relation_unit(relation_id, 'database/0')
Expand All @@ -5021,7 +5048,9 @@ def test_grant_secret_no_relation(self):
harness.grant_secret(secret_id, 'webapp')

def test_get_secret_grants(self):
harness = ops.testing.Harness(ops.CharmBase, meta='name: database')
harness = ops.testing.Harness(ops.CharmBase, meta=yaml.safe_dump(
{'name': 'database', 'provides': {'db': {'interface': 'pgsql'}}}
))
self.addCleanup(harness.cleanup)

relation_id = harness.add_relation('db', 'webapp')
Expand Down

0 comments on commit 77f280c

Please sign in to comment.