From 7559cc66c7adffaf27bcfa500375abddd958a786 Mon Sep 17 00:00:00 2001 From: Maxim Kulkin Date: Fri, 10 Aug 2012 19:03:41 +0400 Subject: [PATCH] [test] Added some tests for Keystone resources --- cooks | 2 +- test/cookbooks/__init__.py | 12 +++ test/cookbooks/openstack_common.py | 9 +- test/cookbooks/test_keystone.py | 142 +++++++++++++++++++++++++++-- 4 files changed, 155 insertions(+), 10 deletions(-) diff --git a/cooks b/cooks index 9f734d65a..a96a1fddd 160000 --- a/cooks +++ b/cooks @@ -1 +1 @@ -Subproject commit 9f734d65ab6b0a0471b9cc32696e50bbd5785d76 +Subproject commit a96a1fdddbed149086e25771b550b0eacc5d5bb5 diff --git a/test/cookbooks/__init__.py b/test/cookbooks/__init__.py index b199a3fd5..b1f6babe3 100644 --- a/test/cookbooks/__init__.py +++ b/test/cookbooks/__init__.py @@ -268,6 +268,18 @@ cookbook_path "/opt/os-cookbooks" return result + @classmethod + def chef_run_recipe(klass, recipe): + klass.remote.mkdir('/opt/os-cookbooks/test') + klass.remote.mkdir('/opt/os-cookbooks/test/recipes') + + default_rb = klass.remote.open('/opt/os-cookbooks/test/recipes/default.rb', 'w') + default_rb.write(recipe) + default_rb.close() + + klass.chef_solo({'recipes': ['test']}) + def setUp(self): self.node.restore_snapshot(self.__class__.__name__) self.remote.reconnect() + diff --git a/test/cookbooks/openstack_common.py b/test/cookbooks/openstack_common.py index cae0de6c0..d860314c7 100644 --- a/test/cookbooks/openstack_common.py +++ b/test/cookbooks/openstack_common.py @@ -22,6 +22,7 @@ class OpenstackCommon(object): klass.remote.reconnect() + keystone_admin_token = 'secret' keystone_admin_port = 37376 keystone_public_port = 5000 @@ -39,21 +40,23 @@ class OpenstackCommon(object): 'host': str(klass.ip), 'port': klass.mysql_port, 'username': 'db_maker', - 'password': 'test' + 'password': 'secret' } }, 'keystone': { 'db': { 'password': 'secret' }, - 'admin_token': 'secret', + 'admin_port': klass.keystone_admin_port, + 'public_port': klass.keystone_public_port, + 'admin_token': klass.keystone_admin_token, 'service_tenant': 'service', 'admin_tenant': 'admin', 'admin_user': 'admin', 'admin_password': 'admin', 'admin_role': 'admin', 'admin_url': 'http://%s:%s/' % (klass.ip, - klass.keystone_public_port), + klass.keystone_admin_port), 'public_url': 'http://%s:%s/' % (klass.ip, klass.keystone_public_port), 'internal_url': 'http://%s:%s/' % (klass.ip, diff --git a/test/cookbooks/test_keystone.py b/test/cookbooks/test_keystone.py index bcdc6fdd8..68c6d58bc 100644 --- a/test/cookbooks/test_keystone.py +++ b/test/cookbooks/test_keystone.py @@ -2,7 +2,7 @@ from . import CookbookTestCase from openstack_common import OpenstackCommon from devops.helpers import tcp_ping -from integration.helpers import HTTPClient +import httplib import os import simplejson as json @@ -22,18 +22,148 @@ class TestKeystone(CookbookTestCase, OpenstackCommon): klass.setUpMysql() klass.setUpKeystone(reuse_cached=False) + def keystone_data(self, url): + conn = httplib.HTTPConnection(str(self.ip), self.keystone_admin_port) + conn.request('GET', url, None, {'X-Auth-Token': self.keystone_admin_token}) + res = conn.getresponse() + data = res.read() + + assert res.status in [200], \ + "Keystone request was expected to return code 200, but was %d (%s)\n%s" % (res.status, res.reason, data) + + return json.loads(data) + + def test_admin_port_open(self): + assert tcp_ping(self.ip, self.keystone_admin_port) + def test_public_port_open(self): assert tcp_ping(self.ip, self.keystone_public_port) def test_keystone_identity_service_registered(self): - keystone_url = "http://%s:%d" % (self.ip, self.keystone_admin_port) - - http = HTTPClient() - services = json.loads(http.get(keystone_url + "/v2.0/OS-KSADM/services"))['OS-KSADM:services'] - + services = self.keystone_data('/v2.0/OS-KSADM/services')['OS-KSADM:services'] keystone_service = find(lambda service: service['name'] == 'keystone', services) assert keystone_service, "Keystone service is not registered" assert keystone_service['type'] == 'identity', \ "Keystone service has incorrect type ('%s' instead of 'identity')" % keystone_service['type'] + + def _create_tenant(self, name, description=''): + self.chef_run_recipe(""" + keystone_tenant '%(name)s' do + connection :url => 'http://localhost:%(port)d', + :token => '%(token)s' + description '%(description)s' + end + """ % { + 'name': name, + 'description': description, + 'port': self.keystone_admin_port, + 'token': self.keystone_admin_token + }) + + def _delete_tenant(self, name): + self.chef_run_recipe(""" + keystone_tenant '%(name)s' do + connection :url => 'http://localhost:%(port)d', + :token => '%(token)s' + action :delete + end + """ % { + 'name': name, + 'port': self.keystone_admin_port, + 'token': self.keystone_admin_token + }) + + def test_tenant_creation(self): + self._create_tenant('foo', 'Test tenant') + + tenants = self.keystone_data('/v2.0/tenants')['tenants'] + tenant = find(lambda tenant: tenant['name'] == 'foo', tenants) + + assert tenant, "Tenant wasn't created" + self.assertEqual('Test tenant', tenant['description']) + self.assertEqual(True, tenant['enabled']) + + def test_tenant_creation_doesnt_fail_if_tenant_already_do_exist(self): + self._create_tenant('foo', 'Test tenant') + self._create_tenant('foo', 'Test tenant') + + tenants = self.keystone_data('/v2.0/tenants')['tenants'] + tenant = find(lambda tenant: tenant['name'] == 'foo', tenants) + + assert tenant, "Tenant wasn't created" + + def test_tenant_deletion(self): + self._create_tenant('foo') + self._delete_tenant('foo') + + tenants = self.keystone_data('/v2.0/tenants')['tenants'] + tenant = find(lambda tenant: tenant['name'] == 'foo', tenants) + + assert tenant == None, "Tenant wasn't deleted" + + + def test_tenant_deletion_doesnt_fail_if_tenant_do_not_exist(self): + self._create_tenant('foo') + self._delete_tenant('foo') + self._delete_tenant('foo') + + + def _create_role(self, name): + self.chef_run_recipe(""" + keystone_role '%(name)s' do + connection :url => 'http://localhost:%(port)d', + :token => '%(token)s' + end + """ % { + 'name': name, + 'port': self.keystone_admin_port, + 'token': self.keystone_admin_token + }) + + def _delete_role(self, name): + self.chef_run_recipe(""" + keystone_role '%(name)s' do + connection :url => 'http://localhost:%(port)d', + :token => '%(token)s' + action :delete + end + """ % { + 'name': name, + 'port': self.keystone_admin_port, + 'token': self.keystone_admin_token + }) + + def test_role_creation(self): + self._create_role('foo') + + roles = self.keystone_data('/v2.0/OS-KSADM/roles')['roles'] + role = find(lambda role: role['name'] == 'foo', roles) + + assert role, "Role wasn't created" + + def test_role_creation_doesnt_fail_if_role_do_exist(self): + self._create_role('foo') + self._create_role('foo') + + def test_role_deletion(self): + self._create_role('foo') + + self._delete_role('foo') + + roles = self.keystone_data('/v2.0/OS-KSADM/roles')['roles'] + role = find(lambda role: role['name'] == 'foo', roles) + + assert role == None, "Role wasn't deleted" + + def test_role_deletion(self): + self._create_role('foo') + + self._delete_role('foo') + + roles = self.keystone_data('/v2.0/OS-KSADM/roles')['roles'] + role = find(lambda role: role['name'] == 'foo', roles) + + assert role == None, "Role wasn't deleted" +