X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=modules%2Flibjuju%2Ftests%2Fintegration%2Ftest_controller.py;h=6423a98892c6b43b39322a84a65bfe8b3949e830;hp=d5593134b35cae20dd2209f892bc6c402ac33607;hb=e2051cca7dac12aa09f6ed33555dcc4548c4b52b;hpb=1a15d1c84fc826fa7996c1c9d221a324edd33432 diff --git a/modules/libjuju/tests/integration/test_controller.py b/modules/libjuju/tests/integration/test_controller.py index d559313..6423a98 100644 --- a/modules/libjuju/tests/integration/test_controller.py +++ b/modules/libjuju/tests/integration/test_controller.py @@ -1,11 +1,16 @@ import asyncio -import pytest +import subprocess import uuid -from .. import base +from juju.client.connection import Connection +from juju.client.jujudata import FileJujuData from juju.controller import Controller from juju.errors import JujuAPIError +import pytest + +from .. import base + @base.bootstrapped @pytest.mark.asyncio @@ -16,6 +21,7 @@ async def test_add_remove_user(event_loop): assert user is None user = await controller.add_user(username) assert user is not None + assert user.secret_key is not None assert user.username == username users = await controller.get_users() assert any(u.username == username for u in users) @@ -57,14 +63,45 @@ async def test_change_user_password(event_loop): username = 'test-password{}'.format(uuid.uuid4()) user = await controller.add_user(username) await user.set_password('password') + # Check that we can connect with the new password. + new_connection = None try: - new_controller = Controller() - await new_controller.connect( - controller.connection.endpoint, username, 'password') + kwargs = controller.connection().connect_params() + kwargs['username'] = username + kwargs['password'] = 'password' + new_connection = await Connection.connect(**kwargs) except JujuAPIError: raise AssertionError('Unable to connect with new password') finally: - await new_controller.disconnect() + if new_connection: + await new_connection.close() + + +@base.bootstrapped +@pytest.mark.asyncio +async def test_reset_user_password(event_loop): + async with base.CleanController() as controller: + username = 'test{}'.format(uuid.uuid4()) + user = await controller.add_user(username) + origin_secret_key = user.secret_key + await user.set_password('password') + await controller.reset_user_password(username) + user = await controller.get_user(username) + new_secret_key = user.secret_key + # Check secret key is different after the reset. + assert origin_secret_key != new_secret_key + # Check that we can't connect with the old password. + new_connection = None + try: + kwargs = controller.connection().connect_params() + kwargs['username'] = username + kwargs['password'] = 'password' + new_connection = await Connection.connect(**kwargs) + except JujuAPIError: + pass + finally: + # No connection with old password + assert new_connection is None @base.bootstrapped @@ -77,14 +114,14 @@ async def test_grant_revoke(event_loop): assert user.access == 'superuser' fresh = await controller.get_user(username) # fetch fresh copy assert fresh.access == 'superuser' - await user.grant('login') - assert user.access == 'login' + await user.grant('login') # already has 'superuser', so no-op + assert user.access == 'superuser' fresh = await controller.get_user(username) # fetch fresh copy - assert fresh.access == 'login' + assert fresh.access == 'superuser' await user.revoke() - assert user.access is '' + assert user.access == '' fresh = await controller.get_user(username) # fetch fresh copy - assert fresh.access is '' + assert fresh.access == '' @base.bootstrapped @@ -120,6 +157,11 @@ async def test_get_model(event_loop): await controller.destroy_model(model_name) +async def _wait_for_model(controller, model_name): + while model_name not in await controller.list_models(): + await asyncio.sleep(0.5, loop=controller.loop) + + async def _wait_for_model_gone(controller, model_name): while model_name in await controller.list_models(): await asyncio.sleep(0.5, loop=controller.loop) @@ -132,6 +174,9 @@ async def test_destroy_model_by_name(event_loop): model_name = 'test-{}'.format(uuid.uuid4()) model = await controller.add_model(model_name) await model.disconnect() + await asyncio.wait_for(_wait_for_model(controller, + model_name), + timeout=60) await controller.destroy_model(model_name) await asyncio.wait_for(_wait_for_model_gone(controller, model_name), @@ -146,7 +191,38 @@ async def test_add_destroy_model_by_uuid(event_loop): model = await controller.add_model(model_name) model_uuid = model.info.uuid await model.disconnect() + await asyncio.wait_for(_wait_for_model(controller, + model_name), + timeout=60) await controller.destroy_model(model_uuid) await asyncio.wait_for(_wait_for_model_gone(controller, model_name), timeout=60) + + +# this test must be run serially because it modifies the login password +@pytest.mark.serial +@base.bootstrapped +@pytest.mark.asyncio +async def test_macaroon_auth(event_loop): + jujudata = FileJujuData() + account = jujudata.accounts()[jujudata.current_controller()] + with base.patch_file('~/.local/share/juju/accounts.yaml'): + if 'password' in account: + # force macaroon auth by "changing" password to current password + result = subprocess.run( + ['juju', 'change-user-password'], + input='{0}\n{0}\n'.format(account['password']), + universal_newlines=True, + stderr=subprocess.PIPE) + assert result.returncode == 0, ('Failed to change password: ' + '{}'.format(result.stderr)) + controller = Controller() + try: + await controller.connect() + assert controller.is_connected() + finally: + if controller.is_connected(): + await controller.disconnect() + async with base.CleanModel(): + pass # create and login to model works