diff --git a/.gitignore b/.gitignore index ff125954..c306f56f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ pip-log.txt # pbr output AUTHORS ChangeLog + +test.conf diff --git a/akanda/rug/test/functional/__init__.py b/akanda/rug/test/functional/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/akanda/rug/test/functional/base.py b/akanda/rug/test/functional/base.py new file mode 100644 index 00000000..b047e2d6 --- /dev/null +++ b/akanda/rug/test/functional/base.py @@ -0,0 +1,80 @@ + +import ConfigParser +import mock +import os +import testtools + +from akanda.rug.api import akanda_client + +from novaclient.v1_1 import client as _novaclient +from neutronclient.v2_0 import client as _neutronclient + +DEFAULT_CONFIG = os.path.join(os.path.dirname(__file__), 'test.conf') + + +class AkandaFunctionalBase(testtools.TestCase): + def setUp(self): + super(AkandaFunctionalBase, self).setUp() + self.config = self._get_config() + + self.ak_cfg = mock.patch.object(akanda_client.cfg, 'CONF').start() + self.ak_cfg.alive_timeout = 10 + self.ak_client = akanda_client + + self.novaclient = _novaclient.Client( + self.config['os_username'], + self.config['os_password'], + self.config['os_tenant_name'], + auth_url=self.config['os_auth_url'], + auth_system='keystone', + ) + + self.neutronclient = _neutronclient.Client( + username=self.config['os_username'], + password=self.config['os_password'], + tenant_name=self.config['os_tenant_name'], + auth_url=self.config['os_auth_url'], + auth_strategy='keystone', + ) + self._management_address = None + + def get_config(self): + config_file = os.environ.get('AKANDA_TEST_CONFIG', + DEFAULT_CONFIG) + config = ConfigParser.SafeConfigParser() + if not config.read(config_file): + self.skipTest('Skipping, no test config found @ %s' % + config_file) + + conf_settings = ['os_auth_url', 'os_username', 'os_password', + 'os_tenant_name', 'service_tenant_name', + 'service_tenant_id', 'appliance_api_port'] + out = {} + for c in conf_settings: + try: + out[c] = config.get('functional', c) + except ConfigParser.NoOptionError: + out[c] = None + missing = [k for k, v in out.items() if not v] + if missing: + self.fail('Missing required setting in test.conf (%s)' + (config_file, ','.join(missing))) + return out + + @property + def management_address(self): + if self._management_address: + return self._management_address['addr'] + + # TODO(adam_g): Deal with multiple service VMs + service_vm = [vm for vm in self.novaclient.servers.list(search_opts={ + 'all_tenants': 1, + 'tenant_id': self.config['service_tenant_id'], + }) if vm.name.startswith('ak-')][0] + + try: + self._management_address = service_vm.addresses['mgt'][0] + except KeyError: + self.fail('"mgt" port not found on service vm %s (%s)' % + (service_vm.id, service_vm.name)) + return self._management_address['addr'] diff --git a/akanda/rug/test/functional/test.conf b/akanda/rug/test/functional/test.conf new file mode 100644 index 00000000..d5bd11ea --- /dev/null +++ b/akanda/rug/test/functional/test.conf @@ -0,0 +1,8 @@ +[functional] +os_auth_url=http://127.0.0.1:5000/v2.0 +os_username=admin +os_password=secret +os_tenant_name=admin +service_tenant_name=service +service_tenant_id=5d58fe467c73483c8d68b8610c38554b +appliance_api_port=5000 diff --git a/akanda/rug/test/functional/test_service_vm.py b/akanda/rug/test/functional/test_service_vm.py new file mode 100644 index 00000000..7ae08267 --- /dev/null +++ b/akanda/rug/test/functional/test_service_vm.py @@ -0,0 +1,15 @@ + +from akanda.rug.test.functional import base + + +class AkandaApplianceVMTest(base.AkandaFunctionalBase): + """Basic tests to ensure a service VM and its associated router is alive + and well. + """ + def test_appliance_is_alive(self): + self.assertTrue( + self.ak_client.is_alive( + host=self.management_address, + port=self.config['appliance_api_port'], + ), + ) diff --git a/tools/run_functional.sh b/tools/run_functional.sh index 9a2659e6..c360af96 100755 --- a/tools/run_functional.sh +++ b/tools/run_functional.sh @@ -1,7 +1,23 @@ -#!/bin/bash -# -# This is a temporary place holder for an entry point that devstack-gate -# can use to run functional akanda tests against a devstack deployed -# cloud. +#!/bin/bash -xe -exit 0 +FUNC_TEST_DIR=$(dirname $0)/../akanda/rug/test/functional/ +CONFIG_FILE=$FUNC_TEST_DIR/test.conf + +APPLIANCE_API_PORT=${APPLIANCE_API_PORT:-5000} +SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service} +if [ -z "$SERVICE_TENANT_ID" ]; then + SERVICE_TENANT_ID="$(keystone tenant-list | grep $SERVICE_TENANT_NAME | awk '{ print $2 }')" +fi + +cat <$CONFIG_FILE +[functional] +os_auth_url=$OS_AUTH_URL +os_username=$OS_USERNAME +os_password=$OS_PASSWORD +os_tenant_name=$OS_TENANT_NAME +service_tenant_name=$SERVICE_TENANT_NAME +service_tenant_id=$SERVICE_TENANT_ID +appliance_api_port=$APPLIANCE_API_PORT +END + +sudo -E tox -e functional diff --git a/tox.ini b/tox.ini index 66d12bf4..70f7bf12 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ envlist = py27,pep8 distribute = False setenv = VIRTUAL_ENV={envdir} deps = -r{toxinidir}/test-requirements.txt -commands = nosetests --with-coverage --cover-package=akanda.rug {posargs} +commands = nosetests --with-coverage --cover-package=akanda.rug akanda/rug/test/unit/ {posargs} sitepackages = False [tox:jenkins] @@ -29,5 +29,8 @@ setenv = NOSE_WITH_COVERAGE=1 [testenv:venv] commands = {posargs} +[testenv:functional] +commands = nosetests -v ./akanda/rug/test/functional/ + [flake8] ignore = E123,E133,E226,E241,E242,E731