- Covers most of what is demonstrated in the examples/ directory.
- The integration tests are not run by default (with the 'tox' command),
but they are run by TravisCI.
- Each integration test gets its own clean model in which to run, which
is destroyed at the end of the test. See tests.base.CleanModel.
- Includes charmstore and local bundle tests (local bundle has machine
and placement directives).
Fixes #27.
install: pip install tox-travis
before_script:
- sudo -E sudo -u $USER -E bash -c "juju bootstrap localhost test"
-script: tox
+script: tox -e py35,integration
after_script:
- sudo -E sudo -u $USER -E bash -c "juju destroy-controller --destroy-all-models -y test"
log = logging.getLogger(__name__)
-MB = 1024 * 1024
+MB = 1
+
async def run():
model = Model()
application_name='nrpe',
series='trusty',
channel='stable',
- num_units=1,
+ # subordinates must be deployed without units
+ num_units=0,
)
my_relation = await model.add_relation(
'ubuntu',
--- /dev/null
+series: xenial
+services:
+ wordpress:
+ charm: "cs:trusty/wordpress-2"
+ num_units: 1
+ annotations:
+ "gui-x": "339.5"
+ "gui-y": "-171"
+ to:
+ - "0"
+ mysql:
+ charm: "cs:trusty/mysql-26"
+ num_units: 1
+ annotations:
+ "gui-x": "79.5"
+ "gui-y": "-142"
+ to:
+ - "1"
+relations:
+ - - "wordpress:db"
+ - "mysql:db"
+machines:
+ "0":
+ series: trusty
+ constraints: "arch=amd64 cores=1 cpu-power=100 mem=1740 root-disk=8192"
+ "1":
+ series: trusty
+ constraints: "arch=amd64 cores=1 cpu-power=100 mem=1740 root-disk=8192"
+++ /dev/null
-import pytest
-
-from juju.client import client
-
-from .. import base
-
-
-@base.bootstrapped
-@pytest.mark.asyncio
-async def test_user_info(event_loop):
- async with base.CleanModel() as model:
- controller_conn = await model.connection.controller()
-
- um = client.UserManagerFacade()
- um.connect(controller_conn)
- result = await um.UserInfo(
- [client.Entity('user-admin')], True)
- await controller_conn.close()
-
- assert isinstance(result, client.UserInfoResults)
- for r in result.results:
- assert isinstance(r, client.UserInfoResult)
+++ /dev/null
-import pytest
-
-from juju.client.connection import Connection
-from .. import base
-
-
-@base.bootstrapped
-@pytest.mark.asyncio
-async def test_connect_current(event_loop):
- async with base.CleanModel():
- conn = await Connection.connect_current()
-
- assert isinstance(conn, Connection)
- await conn.close()
+++ /dev/null
-import pytest
-
-from .. import base
-
-MB = 1
-GB = 1024
-
-
-@base.bootstrapped
-@pytest.mark.asyncio
-async def test_add_machine(event_loop):
- from juju.machine import Machine
-
- async with base.CleanModel() as model:
- # add a new default machine
- machine1 = await model.add_machine()
-
- # add a machine with constraints, disks, and series
- machine2 = await model.add_machine(
- constraints={
- 'mem': 256 * MB,
- },
- disks=[{
- 'pool': 'rootfs',
- 'size': 10 * GB,
- 'count': 1,
- }],
- series='xenial',
- )
-
- # add a lxd container to machine2
- machine3 = await model.add_machine(
- 'lxd:{}'.format(machine2.id))
-
- for m in (machine1, machine2, machine3):
- assert isinstance(m, Machine)
-
- assert len(model.machines) == 3
-
- await machine3.destroy(force=True)
- await machine2.destroy(force=True)
- res = await machine1.destroy(force=True)
-
- assert res is None
- assert len(model.machines) == 0
--- /dev/null
+import pytest
+
+from .. import base
+
+MB = 1
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_action(event_loop):
+ async with base.CleanModel() as model:
+ ubuntu_app = await model.deploy(
+ 'mysql',
+ application_name='mysql',
+ series='trusty',
+ channel='stable',
+ config={
+ 'tuning-level': 'safest',
+ },
+ constraints={
+ 'mem': 256 * MB,
+ },
+ )
+
+ # update and check app config
+ await ubuntu_app.set_config({'tuning-level': 'fast'})
+ config = await ubuntu_app.get_config()
+ assert config['tuning-level']['value'] == 'fast'
+
+ # update and check app constraints
+ await ubuntu_app.set_constraints({'mem': 512 * MB})
+ constraints = await ubuntu_app.get_constraints()
+ assert constraints['mem'] == 512 * MB
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_add_units(event_loop):
+ from juju.unit import Unit
+
+ async with base.CleanModel() as model:
+ app = await model.deploy(
+ 'ubuntu-0',
+ application_name='ubuntu',
+ series='trusty',
+ channel='stable',
+ )
+ units = await app.add_units(count=2)
+
+ assert len(units) == 2
+ for unit in units:
+ assert isinstance(unit, Unit)
--- /dev/null
+import pytest
+
+from juju.client import client
+
+from .. import base
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_user_info(event_loop):
+ async with base.CleanModel() as model:
+ controller_conn = await model.connection.controller()
+
+ um = client.UserManagerFacade()
+ um.connect(controller_conn)
+ result = await um.UserInfo(
+ [client.Entity('user-admin')], True)
+ await controller_conn.close()
+
+ assert isinstance(result, client.UserInfoResults)
+ for r in result.results:
+ assert isinstance(r, client.UserInfoResult)
--- /dev/null
+import pytest
+
+from juju.client.connection import Connection
+from .. import base
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_connect_current(event_loop):
+ async with base.CleanModel():
+ conn = await Connection.connect_current()
+
+ assert isinstance(conn, Connection)
+ await conn.close()
--- /dev/null
+import pytest
+
+from .. import base
+
+MB = 1
+GB = 1024
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_deploy_local_bundle(event_loop):
+ from pathlib import Path
+ tests_dir = Path(__file__).absolute().parent.parent
+ bundle_path = tests_dir / 'bundle'
+
+ async with base.CleanModel() as model:
+ await model.deploy(str(bundle_path))
+
+ for app in ('wordpress', 'mysql'):
+ assert app in model.applications
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_deploy_bundle(event_loop):
+ async with base.CleanModel() as model:
+ await model.deploy('bundle/wiki-simple')
+
+ for app in ('wiki', 'mysql'):
+ assert app in model.applications
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_add_machine(event_loop):
+ from juju.machine import Machine
+
+ async with base.CleanModel() as model:
+ # add a new default machine
+ machine1 = await model.add_machine()
+
+ # add a machine with constraints, disks, and series
+ machine2 = await model.add_machine(
+ constraints={
+ 'mem': 256 * MB,
+ },
+ disks=[{
+ 'pool': 'rootfs',
+ 'size': 10 * GB,
+ 'count': 1,
+ }],
+ series='xenial',
+ )
+
+ # add a lxd container to machine2
+ machine3 = await model.add_machine(
+ 'lxd:{}'.format(machine2.id))
+
+ for m in (machine1, machine2, machine3):
+ assert isinstance(m, Machine)
+
+ assert len(model.machines) == 3
+
+ await machine3.destroy(force=True)
+ await machine2.destroy(force=True)
+ res = await machine1.destroy(force=True)
+
+ assert res is None
+ assert len(model.machines) == 0
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_relate(event_loop):
+ from juju.relation import Relation
+
+ async with base.CleanModel() as model:
+ await model.deploy(
+ 'ubuntu',
+ application_name='ubuntu',
+ series='trusty',
+ channel='stable',
+ )
+ await model.deploy(
+ 'nrpe',
+ application_name='nrpe',
+ series='trusty',
+ channel='stable',
+ # subordinates must be deployed without units
+ num_units=0,
+ )
+ my_relation = await model.add_relation(
+ 'ubuntu',
+ 'nrpe',
+ )
+
+ assert isinstance(my_relation, Relation)
--- /dev/null
+import pytest
+
+from .. import base
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_run(event_loop):
+ from juju.action import Action
+
+ async with base.CleanModel() as model:
+ app = await model.deploy(
+ 'ubuntu-0',
+ application_name='ubuntu',
+ series='trusty',
+ channel='stable',
+ )
+
+ for unit in app.units:
+ action = await unit.run('unit-get public-address')
+ assert isinstance(action, Action)
+ assert 'Stdout' in action.results
+ break
+
+
+@base.bootstrapped
+@pytest.mark.asyncio
+async def test_run_action(event_loop):
+ async def run_action(unit):
+ # unit.run() returns a juju.action.Action instance
+ action = await unit.run_action('add-repo', repo='myrepo')
+ # wait for the action to complete
+ return await action.wait()
+
+ async with base.CleanModel() as model:
+ app = await model.deploy(
+ 'git',
+ application_name='git',
+ series='trusty',
+ channel='stable',
+ )
+
+ for unit in app.units:
+ action = await run_action(unit)
+ assert action.results == {'dir': '/var/git/myrepo.git'}
+ break
usedevelop=True
passenv =
HOME
-commands = py.test -ra -s -x -n auto
deps =
pytest
pytest-asyncio
pytest-xdist
mock
+
+[testenv:py35]
+# default tox env excludes integration tests
+commands = py.test -ra -s -x -n auto -k 'not integration'
+
+[testenv:integration]
+commands = py.test -ra -s -x -n auto