Moving back to using python-tuskarclient instead of mocking it

Change-Id: I06afd8c98e26b1fb0278622e54bf4ae03755ae9e
This commit is contained in:
Lennart Regebro 2014-08-25 12:00:32 +02:00
parent 4450b19acc
commit f4126ab431
12 changed files with 175 additions and 155 deletions

View File

@ -22,4 +22,5 @@ pytz>=2010h
lockfile>=0.8
python-ironicclient>=0.2.1
http://tarballs.openstack.org/python-tuskarclient/python-tuskarclient-master.tar.gz#egg=python-tuskarclient
#http://tarballs.openstack.org/python-tuskarclient/python-tuskarclient-master.tar.gz#egg=python-tuskarclient
-e git+http://git.openstack.org/cgit/openstack/python-tuskarclient/#egg=python-tuskarclient

View File

@ -16,18 +16,11 @@ import logging
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard.api import base
from openstack_dashboard.api import glance
from openstack_dashboard.test.test_data import utils
from tuskarclient.v1 import client as tuskar_client
from tuskarclient import client as tuskar_client
from tuskar_ui.api import flavor
from tuskar_ui.cached_property import cached_property # noqa
from tuskar_ui.handle_errors import handle_errors # noqa
from tuskar_ui.test.test_data import tuskar_data
from tuskar_ui.test.test_driver import tuskar_driver as mock_tuskar
TEST_DATA = utils.TestDataContainer()
tuskar_data.data(TEST_DATA)
LOG = logging.getLogger(__name__)
TUSKAR_ENDPOINT_URL = getattr(django.conf.settings, 'TUSKAR_ENDPOINT_URL')
@ -36,11 +29,12 @@ TUSKAR_ENDPOINT_URL = getattr(django.conf.settings, 'TUSKAR_ENDPOINT_URL')
# FIXME: request isn't used right in the tuskar client right now,
# but looking at other clients, it seems like it will be in the future
def tuskarclient(request):
c = tuskar_client.Client(TUSKAR_ENDPOINT_URL)
c = tuskar_client.get_client('2', tuskar_url=TUSKAR_ENDPOINT_URL,
os_auth_token=request.user.token.id)
return c
class OvercloudPlan(base.APIDictWrapper):
class OvercloudPlan(base.APIResourceWrapper):
_attrs = ('id', 'name', 'description', 'created_at', 'modified_at',
'roles', 'parameters', 'template')
@ -64,11 +58,12 @@ class OvercloudPlan(base.APIDictWrapper):
:return: the created OvercloudPlan object
:rtype: tuskar_ui.api.tuskar.OvercloudPlan
"""
plan = mock_tuskar.Plan.create(name, description)
plan = tuskarclient(request).plans.create(name=name,
description=description)
return cls(plan, request=request)
@classmethod
def update(cls, request, plan_id, name, description):
def patch(cls, request, plan_id, name, description):
"""Update an OvercloudPlan in Tuskar
:param request: request object
@ -86,7 +81,9 @@ class OvercloudPlan(base.APIDictWrapper):
:return: the updated OvercloudPlan object
:rtype: tuskar_ui.api.tuskar.OvercloudPlan
"""
plan = mock_tuskar.Plan.update(plan_id, name, description)
plan = tuskarclient(request).plans.patch(plan_uuid=plan_id,
name=name,
description=description)
return cls(plan, request=request)
@classmethod
@ -99,8 +96,7 @@ class OvercloudPlan(base.APIDictWrapper):
:return: list of OvercloudPlans, or an empty list if there are none
:rtype: list of tuskar_ui.api.tuskar.OvercloudPlan
"""
plans = mock_tuskar.Plan.list()
plans = tuskarclient(request).plans.list()
return [cls(plan, request=request) for plan in plans]
@classmethod
@ -118,7 +114,8 @@ class OvercloudPlan(base.APIDictWrapper):
the ID
:rtype: tuskar_ui.api.tuskar.OvercloudPlan
"""
return cls(mock_tuskar.Plan.get(plan_id), request=request)
plan = tuskarclient(request).plans.get(plan_uuid=plan_id)
return cls(plan, request=request)
# TODO(lsmola) before will will support multiple overclouds, we
# can work only with overcloud that is named overcloud. Delete
@ -147,11 +144,11 @@ class OvercloudPlan(base.APIDictWrapper):
:param plan_id: plan id
:type plan_id: int
"""
mock_tuskar.Plan.delete(plan_id)
tuskarclient(request).plans.delete(plan_uuid=plan_id)
@cached_property
def role_list(self):
return [OvercloudRole.get(self._request, role['id'])
return [OvercloudRole.get(self._request, role['uuid'])
for role in self.roles]
def parameter_list(self, include_key_parameters=True):
@ -177,8 +174,8 @@ class OvercloudPlan(base.APIDictWrapper):
return default
class OvercloudRole(base.APIDictWrapper):
_attrs = ('id', 'name', 'version', 'description', 'created')
class OvercloudRole(base.APIResourceWrapper):
_attrs = ('uuid', 'name', 'version', 'description', 'created')
def __init__(self, apiresource, request=None):
super(OvercloudRole, self).__init__(apiresource)
@ -196,7 +193,7 @@ class OvercloudRole(base.APIDictWrapper):
are none
:rtype: list of tuskar_ui.api.tuskar.OvercloudRole
"""
roles = TEST_DATA.tuskarclient_roles.list()
roles = tuskarclient(request).roles.list()
return [cls(role, request=request) for role in roles]
@classmethod
@ -215,7 +212,7 @@ class OvercloudRole(base.APIDictWrapper):
:rtype: tuskar_ui.api.tuskar.OvercloudRole
"""
for role in OvercloudRole.list(request):
if role.id == role_id:
if role.uuid == role_id:
return role
@classmethod
@ -276,3 +273,7 @@ class OvercloudRole(base.APIDictWrapper):
flavor_id = plan.parameter_value(self.flavor_id_parameter_name)
if flavor_id:
return flavor.Flavor.get(self._request, flavor_id)
@property
def id(self):
return self.uuid

View File

@ -67,13 +67,24 @@ def _prepare_create():
class FlavorsTest(test.BaseAdminViewTests):
def test_index(self):
plans = [api.tuskar.OvercloudPlan(plan, self.request)
for plan in TEST_DATA.tuskarclient_plans.list()]
roles = [api.tuskar.OvercloudRole(role)
for role in self.tuskarclient_roles.list()]
with contextlib.nested(
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=plans),
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=roles),
patch('openstack_dashboard.api.nova.flavor_list',
return_value=TEST_DATA.novaclient_flavors.list()),
patch('openstack_dashboard.api.nova.server_list',
return_value=([], False)),
) as (flavors_mock, servers_mock):
) as (plans_mock, roles_mock, flavors_mock, servers_mock):
res = self.client.get(INDEX_URL)
self.assertEqual(plans_mock.call_count, 1)
self.assertEqual(roles_mock.call_count, 4)
self.assertEqual(flavors_mock.call_count, 1)
self.assertEqual(servers_mock.call_count, 1)
@ -131,12 +142,14 @@ class FlavorsTest(test.BaseAdminViewTests):
return_value=([], False)),
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=[]),
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=[]),
patch('openstack_dashboard.api.glance.image_list_detailed',
return_value=([], False)),
patch('openstack_dashboard.api.nova.flavor_list',
return_value=TEST_DATA.novaclient_flavors.list())
) as (delete_mock, server_list_mock, _role_list_mock, _glance_mock,
_flavors_mock):
) as (delete_mock, server_list_mock, _role_list_mock, _plan_list_mock,
_glance_mock, _flavors_mock):
res = self.client.post(INDEX_URL, data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, INDEX_URL)
@ -159,12 +172,14 @@ class FlavorsTest(test.BaseAdminViewTests):
return_value=([server], False)),
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=[]),
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=[]),
patch('openstack_dashboard.api.glance.image_list_detailed',
return_value=([], False)),
patch('openstack_dashboard.api.nova.flavor_list',
return_value=TEST_DATA.novaclient_flavors.list())
) as (delete_mock, server_list_mock, _role_list_mock, _glance_mock,
_flavors_mock):
) as (delete_mock, server_list_mock, _role_list_mock, _plan_list_mock,
_glance_mock, _flavors_mock):
res = self.client.post(INDEX_URL, data)
self.assertMessageCount(error=1, warning=0)
self.assertNoFormErrors(res)

View File

@ -12,13 +12,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import contextlib
from django.core import urlresolvers
from mock import patch, call # noqa
from tuskar_ui import api
from tuskar_ui.test import helpers as test
INDEX_URL = urlresolvers.reverse(
'horizon:infrastructure:images:index')
@ -26,8 +28,18 @@ INDEX_URL = urlresolvers.reverse(
class ImagesTest(test.BaseAdminViewTests):
def test_index(self):
with patch('openstack_dashboard.api.glance.image_list_detailed',
return_value=[self.images.list(), False, False]):
roles = [api.tuskar.OvercloudRole(role) for role in
self.tuskarclient_roles.list()]
plans = [api.tuskar.OvercloudPlan(plan) for plan in
self.tuskarclient_plans.list()]
with contextlib.nested(
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=roles),
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=plans),
patch('openstack_dashboard.api.glance.image_list_detailed',
return_value=[self.images.list(), False, False]),):
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, 'infrastructure/images/index.html')

View File

@ -33,10 +33,16 @@ tuskar_data.data(TEST_DATA)
class ParametersTest(test.BaseAdminViewTests):
def test_index(self):
plan = api.tuskar.OvercloudPlan(TEST_DATA.tuskarclient_plans.first())
plans = [api.tuskar.OvercloudPlan(plan)
for plan in self.tuskarclient_plans.list()]
roles = [api.tuskar.OvercloudRole(role)
for role in self.tuskarclient_roles.list()]
with contextlib.nested(
patch('tuskar_ui.api.tuskar.OvercloudPlan.get_the_plan',
return_value=plan),
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=plans),
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=roles),
):
res = self.client.get(INDEX_URL)

View File

@ -29,6 +29,9 @@ class RolesTable(tables.DataTable):
image = tables.Column('image',
verbose_name=_("Image"))
def get_object_id(self, datum):
return datum.uuid
class Meta:
name = "roles"
verbose_name = _("Deployment Roles")

View File

@ -13,7 +13,6 @@
# under the License.
import contextlib
from django.core import urlresolvers
from mock import patch, call # noqa
@ -44,35 +43,40 @@ class RolesTest(test.BaseAdminViewTests):
def test_index_get(self):
roles = [api.tuskar.OvercloudRole(role)
for role in TEST_DATA.tuskarclient_roles.list()]
flavor = TEST_DATA.novaclient_flavors.first()
for role in self.tuskarclient_roles.list()]
plans = [api.tuskar.OvercloudPlan(plan)
for plan in self.tuskarclient_plans.list()]
flavor = self.novaclient_flavors.first()
with contextlib.nested(
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=roles),
patch('openstack_dashboard.api.nova.flavor_get',
return_value=flavor),
):
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=plans),
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=roles),
patch('openstack_dashboard.api.glance.image_get',
return_value=None),
patch('tuskar_ui.api.flavor.Flavor.get',
return_value=flavor)):
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, 'infrastructure/roles/index.html')
def test_detail_get(self):
roles = [api.tuskar.OvercloudRole(role)
for role in TEST_DATA.tuskarclient_roles.list()]
flavor = TEST_DATA.novaclient_flavors.first()
for role in self.tuskarclient_roles.list()]
plans = [api.tuskar.OvercloudPlan(plan)
for plan in self.tuskarclient_plans.list()]
flavor = self.novaclient_flavors.first()
with contextlib.nested(
patch('tuskar_ui.api.tuskar.OvercloudRole', **{
'spec_set': ['list', 'get'],
'list.return_value': roles,
'get.return_value': roles[0],
}),
patch('tuskar_ui.api.tuskar.OvercloudRole.list',
return_value=roles),
patch('tuskar_ui.api.heat.Stack.events',
return_value=[]),
patch('openstack_dashboard.api.nova.flavor_get',
return_value=flavor),
):
patch('tuskar_ui.api.tuskar.OvercloudPlan.list',
return_value=plans),
patch('tuskar_ui.api.flavor.Flavor.get',
return_value=flavor)):
res = self.client.get(DETAIL_URL)
self.assertTemplateUsed(

View File

@ -55,9 +55,7 @@ class IndexView(horizon_tables.DataTableView):
plan = api.tuskar.OvercloudPlan.get_the_plan(self.request)
for role in roles:
role_flavor = role.flavor(plan)
# TODO(tzumainn): we don't mock images, so calling role.image(plan)
# won't work right now
role_image = None
role_image = role.image(plan)
if role_flavor:
role.flavor = role_flavor.name
else:

View File

@ -40,10 +40,11 @@ class HeatAPITests(test.APITestCase):
self.assertIsInstance(ret_val, api.heat.Stack)
def test_stack_plan(self):
stack = api.heat.Stack(self.heatclient_stacks.first())
stack = api.heat.Stack(self.heatclient_stacks.first(),
self.request)
plan = self.tuskarclient_plans.first()
with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.get',
with patch('tuskarclient.v2.plans.PlanManager.get',
return_value=plan):
ret_val = stack.plan
self.assertIsInstance(ret_val, api.tuskar.OvercloudPlan)
@ -146,8 +147,14 @@ class HeatAPITests(test.APITestCase):
self.assertIsInstance(ret_val, api.heat.Resource)
def test_resource_role(self):
resource = api.heat.Resource(self.heatclient_resources.first())
ret_val = resource.role
# The api needs to get the role, and getting the role means listing
# all roles, so we mock that.
roles = self.tuskarclient_roles.list()
with patch('tuskarclient.v2.roles.RoleManager.list',
return_value=roles):
resource = api.heat.Resource(self.heatclient_resources.first(),
self.request)
ret_val = resource.role
self.assertIsInstance(ret_val, api.tuskar.OvercloudRole)
self.assertEqual('Compute', ret_val.name)

View File

@ -23,7 +23,7 @@ class TuskarAPITests(test.APITestCase):
def test_plan_create(self):
plan = self.tuskarclient_plans.first()
with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.create',
with patch('tuskarclient.v2.plans.PlanManager.create',
return_value=plan):
ret_val = api.tuskar.OvercloudPlan.create(self.request, {}, {})
self.assertIsInstance(ret_val, api.tuskar.OvercloudPlan)
@ -31,7 +31,7 @@ class TuskarAPITests(test.APITestCase):
def test_plan_list(self):
plans = self.tuskarclient_plans.list()
with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.list',
with patch('tuskarclient.v2.plans.PlanManager.list',
return_value=plans):
ret_val = api.tuskar.OvercloudPlan.list(self.request)
for plan in ret_val:
@ -41,18 +41,18 @@ class TuskarAPITests(test.APITestCase):
def test_plan_get(self):
plan = self.tuskarclient_plans.first()
with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.get',
with patch('tuskarclient.v2.plans.PlanManager.get',
return_value=plan):
ret_val = api.tuskar.OvercloudPlan.get(self.request, plan['id'])
ret_val = api.tuskar.OvercloudPlan.get(self.request, plan.id)
self.assertIsInstance(ret_val, api.tuskar.OvercloudPlan)
def test_plan_get_the_plan(self):
plan = self.tuskarclient_plans.first()
with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.list',
return_value=[]):
with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.create',
with patch('tuskarclient.v2.plans.PlanManager.list',
return_value=[plan]):
with patch('tuskarclient.v2.plans.PlanManager.create',
return_value=plan):
ret_val = api.tuskar.OvercloudPlan.get_the_plan(self.request)
@ -60,36 +60,50 @@ class TuskarAPITests(test.APITestCase):
def test_plan_delete(self):
plan = self.tuskarclient_plans.first()
api.tuskar.OvercloudPlan.delete(self.request, plan['id'])
with patch('tuskarclient.v2.plans.PlanManager.delete',
return_value=None):
api.tuskar.OvercloudPlan.delete(self.request, plan.id)
def test_plan_role_list(self):
plan = api.tuskar.OvercloudPlan(self.tuskarclient_plans.first())
with patch('tuskarclient.v2.plans.PlanManager.get',
return_value=[]):
plan = api.tuskar.OvercloudPlan(self.tuskarclient_plans.first(),
self.request)
ret_val = plan.role_list
with patch('tuskarclient.v2.roles.RoleManager.list',
return_value=self.tuskarclient_roles.list()):
ret_val = plan.role_list
self.assertEqual(4, len(ret_val))
for r in ret_val:
self.assertIsInstance(r, api.tuskar.OvercloudRole)
def test_role_list(self):
ret_val = api.tuskar.OvercloudRole.list(self.request)
roles = self.tuskarclient_roles.list()
with patch('tuskarclient.v2.roles.RoleManager.list',
return_value=roles):
ret_val = api.tuskar.OvercloudRole.list(self.request)
for r in ret_val:
self.assertIsInstance(r, api.tuskar.OvercloudRole)
self.assertEqual(4, len(ret_val))
def test_role_get(self):
role = self.tuskarclient_roles.first()
ret_val = api.tuskar.OvercloudRole.get(self.request, role['id'])
roles = self.tuskarclient_roles.list()
with patch('tuskarclient.v2.roles.RoleManager.list',
return_value=roles):
ret_val = api.tuskar.OvercloudRole.get(self.request,
roles[0].uuid)
self.assertIsInstance(ret_val, api.tuskar.OvercloudRole)
def test_role_get_by_image(self):
plan = api.tuskar.OvercloudPlan(self.tuskarclient_plans.first())
image = self.glanceclient_images.first()
roles = [api.tuskar.OvercloudRole(role) for role in
self.tuskarclient_roles.list()]
roles = self.tuskarclient_roles.list()
with patch('tuskar_ui.api.tuskar.OvercloudRole.list',
with patch('tuskarclient.v2.roles.RoleManager.list',
return_value=roles):
ret_val = api.tuskar.OvercloudRole.get_by_image(
self.request, plan, image)

View File

@ -11,36 +11,42 @@
# under the License.
from openstack_dashboard.test.test_data import utils as test_data_utils
from tuskarclient.v2 import plans
from tuskarclient.v2 import roles
planmanager = plans.PlanManager(None)
rolemanager = roles.RoleManager(None)
def data(TEST):
# OvercloudPlan
# Plan
TEST.tuskarclient_plans = test_data_utils.TestDataContainer()
plan_1 = {
plan_1 = plans.Plan(planmanager, {
'id': 'plan-1',
'name': 'overcloud',
'description': 'this is an overcloud deployment plan',
'template': '',
'created_at': '2014-05-27T21:11:09Z',
'modified_at': '2014-05-30T21:11:09Z',
'roles': [{
'id': 'role-1',
'name': 'Controller',
'version': 1,
}, {
'id': 'role-2',
'name': 'Compute',
'version': 1,
}, {
'id': 'role-3',
'name': 'Object Storage',
'version': 1,
}, {
'id': 'role-4',
'name': 'Block Storage',
'version': 1,
}],
'roles': [
{
'uuid': 'role-1',
'name': 'Controller',
'version': 1,
}, {
'uuid': 'role-2',
'name': 'Compute',
'version': 1,
}, {
'uuid': 'role-3',
'name': 'Object Storage',
'version': 1,
}, {
'uuid': 'role-4',
'name': 'Block Storage',
'version': 1,
}],
'parameters': [{
'name': 'ControllerNodeCount',
'label': 'Controller Node Count',
@ -137,37 +143,37 @@ def data(TEST):
'hidden': 'false',
'value': 'unset',
}],
}
})
TEST.tuskarclient_plans.add(plan_1)
# OvercloudRole
# Role
TEST.tuskarclient_roles = test_data_utils.TestDataContainer()
r_1 = {
'id': 'role-1',
r_1 = roles.Role(rolemanager, {
'uuid': 'role-1',
'name': 'Controller',
'version': 1,
'description': 'controller role',
'created_at': '2014-05-27T21:11:09Z'
}
r_2 = {
'id': 'role-2',
})
r_2 = roles.Role(rolemanager, {
'uuid': 'role-2',
'name': 'Compute',
'version': 1,
'description': 'compute role',
'created_at': '2014-05-27T21:11:09Z'
}
r_3 = {
'id': 'role-3',
})
r_3 = roles.Role(rolemanager, {
'uuid': 'role-3',
'name': 'Object Storage',
'version': 1,
'description': 'object storage role',
'created_at': '2014-05-27T21:11:09Z'
}
r_4 = {
'id': 'role-4',
})
r_4 = roles.Role(rolemanager, {
'uuid': 'role-4',
'name': 'Block Storage',
'version': 1,
'description': 'block storage role',
'created_at': '2014-05-27T21:11:09Z'
}
})
TEST.tuskarclient_roles.add(r_1, r_2, r_3, r_4)

View File

@ -1,47 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack_dashboard.test.test_data import utils
from tuskar_ui.test.test_data import tuskar_data
TEST_DATA = utils.TestDataContainer()
tuskar_data.data(TEST_DATA)
class Plan:
_plans = {}
@classmethod
def create(cls, name, description):
plan = TEST_DATA.tuskarclient_plans.first()
cls._plans[plan['id']] = plan
return plan
@classmethod
def update(cls, plan_id, name, description):
plan = cls.get(plan_id)
# no updates for now
return plan
@classmethod
def list(cls):
return cls._plans.values()
@classmethod
def get(cls, plan_id):
return cls._plans.get(plan_id, None)
@classmethod
def delete(cls, plan_id):
cls._plans.pop(plan_id, None)