Skip to content

Commit 76b9361

Browse files
authored
Merge branch 'master' into feat/remove_application_timeout
2 parents 5b87acb + 66e92a3 commit 76b9361

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,16 +1,18 @@
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
import asyncio
67

78
import pytest
8-
import logging
99

10-
from .. import base
11-
from juju import jasyncio, errors
12-
from juju.url import URL, Schema
10+
from juju import errors, jasyncio
11+
from juju.application import Application
1312
from juju.client import client
13+
from juju.url import URL, Schema
14+
15+
from .. import base
1416

1517
MB = 1
1618

@@ -342,3 +344,14 @@ async def test_app_charm_name():
342344
await model.wait_for_idle(status="active")
343345
assert 'ubuntu' in app.charm_url
344346
assert 'ubuntu' == app.charm_name
347+
348+
349+
@base.bootstrapped
350+
async def test_app_relation_destroy_block_until_done():
351+
async with base.CleanModel() as model:
352+
app: Application = await model.deploy('docker-registry')
353+
rsa: Application = await model.deploy("easyrsa")
354+
relation = await app.relate('cert-provider', rsa.name)
355+
await model.wait_for_idle(status="active")
356+
await app.destroy_relation('cert-provider', rsa.name, block_until_done=True)
357+
assert relation not in app.relations

0 commit comments

Comments
 (0)