Skip to content

Commit 66e92a3

Browse files
authored
Merge pull request #1017 from yanksyoon/feat/remove_application_block_until_done
#1017 #### Description *<Please add why this change is needed and what it does.>* Addresses #781 to add `block_until_done` to `remove_relation`. *<Fixes: >* #### QA Steps *<Commands / tests / steps to run to verify that the change works:>* ``` tox -e integration -- -k test_app_relation_destroy_block_until_done ``` All CI tests need to pass. *<Please note that most likely an additional test will be required by the reviewers for any change that's not a one liner to land.>* #### Notes & Discussion *<Additional notes for the reviewers if needed. Please delete section if not applicable.>*
2 parents 6692f3d + 27cae57 commit 66e92a3

2 files changed

Lines changed: 39 additions & 14 deletions

File tree

juju/application.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
import hashlib
55
import json
66
import logging
7+
import typing
78
from pathlib import Path
89

9-
from . import model, tag, utils, jasyncio
10-
from .url import URL
11-
from .status import derive_status
10+
from . import jasyncio, model, tag, utils
1211
from .annotationhelper import _get_annotations, _set_annotations
13-
from .client import client
14-
from .errors import JujuError, JujuApplicationConfigError
1512
from .bundle import get_charm_series, is_local_charm
16-
from .placement import parse as parse_placement
13+
from .client import client
14+
from .errors import JujuApplicationConfigError, JujuError
1715
from .origin import Channel, Source
16+
from .placement import parse as parse_placement
17+
from .relation import Relation
18+
from .status import derive_status
19+
from .url import URL
20+
from .utils import block_until
1821

1922
log = logging.getLogger(__name__)
2023

@@ -59,14 +62,14 @@ def subordinate_units(self):
5962
return [u for u in self.units if u.is_subordinate]
6063

6164
@property
62-
def relations(self):
65+
def relations(self) -> typing.List[Relation]:
6366
return [rel for rel in self.model.relations if rel.matches(self.name)]
6467

6568
def related_applications(self, endpoint_name=None):
6669
apps = {}
6770
for rel in self.relations:
6871
if rel.is_peer:
69-
local_ep, remote_ep = rel.endpoints[0]
72+
local_ep, remote_ep = rel.endpoints
7073
else:
7174
def is_us(ep):
7275
return ep.application.name == self.name
@@ -191,12 +194,13 @@ async def scale(self, scale=None, scale_change=None):
191194
scale_change=scale_change)
192195
])
193196

194-
async def destroy_relation(self, local_relation, remote_relation):
197+
async def destroy_relation(self, local_relation, remote_relation, block_until_done: bool = False):
195198
"""Remove a relation to another application.
196199
197200
:param str local_relation: Name of relation on this application
198201
:param str remote_relation: Name of relation on the other
199202
application in the form '<application>[:<relation_name>]'
203+
:param bool block_until_done: Wait until the relation is completely removed.
200204
201205
"""
202206
if ':' not in local_relation:
@@ -207,8 +211,16 @@ async def destroy_relation(self, local_relation, remote_relation):
207211
log.debug(
208212
'Destroying relation %s <-> %s', local_relation, remote_relation)
209213

210-
return await app_facade.DestroyRelation(endpoints=[
214+
await app_facade.DestroyRelation(endpoints=[
211215
local_relation, remote_relation])
216+
if block_until_done:
217+
await block_until(
218+
lambda: not any(
219+
relation.matches(local_relation, remote_relation)
220+
for relation in self.relations
221+
)
222+
)
223+
212224
remove_relation = destroy_relation
213225

214226
async def destroy_unit(self, *unit_names):

tests/integration/test_application.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
# Copyright 2023 Canonical Ltd.
22
# Licensed under the Apache V2, see LICENCE file for details.
33

4+
import logging
45
from pathlib import Path
56

67
import pytest
7-
import logging
88

9-
from .. import base
10-
from juju import jasyncio, errors
11-
from juju.url import URL, Schema
9+
from juju import errors, jasyncio
10+
from juju.application import Application
1211
from juju.client import client
12+
from juju.url import URL, Schema
13+
14+
from .. import base
1315

1416
MB = 1
1517

@@ -331,3 +333,14 @@ async def test_app_charm_name():
331333
await model.wait_for_idle(status="active")
332334
assert 'ubuntu' in app.charm_url
333335
assert 'ubuntu' == app.charm_name
336+
337+
338+
@base.bootstrapped
339+
async def test_app_relation_destroy_block_until_done():
340+
async with base.CleanModel() as model:
341+
app: Application = await model.deploy('docker-registry')
342+
rsa: Application = await model.deploy("easyrsa")
343+
relation = await app.relate('cert-provider', rsa.name)
344+
await model.wait_for_idle(status="active")
345+
await app.destroy_relation('cert-provider', rsa.name, block_until_done=True)
346+
assert relation not in app.relations

0 commit comments

Comments
 (0)