Skip to content

Commit

Permalink
Merge pull request #573 from cderici/reliable-unit-public-address
Browse files Browse the repository at this point in the history
#573

### Description

Assigning a unit's public address may take a little time, which makes the result of `unit.public_address` depend on when it's called, thereby creating inconsistency. This PR adds a method, namely `get_public_address`, that waits (with a timeout) until the unit is assigned an address and returns the address when it's assigned.

Fixes #551

Jira card [#141](https://warthogs.atlassian.net/browse/JUJU-141)

### QA Steps

```sh
tox -e integration -- tests/integration/test_unit.py::test_unit_public_address
```

### Notes & Discussion

**A minor design decision:** is that in the case of a timeout, `get_public_address` returns a `None`, rather than a `TimeoutError`.
  • Loading branch information
jujubot authored Nov 8, 2021
2 parents 7b5145c + c1d2fae commit d6bb918
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
24 changes: 23 additions & 1 deletion juju/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pyrfc3339

from . import model, tag
from . import model, tag, jasyncio
from .annotationhelper import _get_annotations, _set_annotations
from .client import client

Expand Down Expand Up @@ -102,6 +102,28 @@ async def destroy(self):
return await app_facade.DestroyUnits(unit_names=[self.name])
remove = destroy

async def get_public_address(self, timeout=60):
"""Return the public address of this unit. Waits until the unit is
assigned a public address.
In case of a timeout, a None is returned (instead of a
TimeoutError)
:param int timeout (60): Maximum seconds to wait for unit to
be assigned an address.
:return int public-address
"""
try:
if self.public_address is None:
await self.model.block_until(
lambda: self.public_address,
timeout=timeout)
except jasyncio.TimeoutError:
return None
return self.public_address

def get_resources(self, details=False):
"""Return resources for this unit.
Expand Down
23 changes: 23 additions & 0 deletions tests/integration/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@
from .. import base


@base.bootstrapped
@pytest.mark.asyncio
async def test_unit_public_address(event_loop):
async with base.CleanModel() as model:
app = await model.deploy(
'ch:ubuntu',
application_name='ubuntu',
series='bionic',
channel='stable',
num_units=2,
)

# wait for the units to come up
await model.block_until(lambda: app.units, timeout=480)

# make sure we have some units to test with
assert len(app.units) >= 1

for unit in app.units:
addr = await unit.get_public_address(timeout=480)
assert addr, 'unit public address not set'


@base.bootstrapped
@pytest.mark.asyncio
async def test_run(event_loop):
Expand Down

0 comments on commit d6bb918

Please sign in to comment.