diff --git a/tuskar_ui/api/tuskar.py b/tuskar_ui/api/tuskar.py index 0e1e10122..0c71fe980 100644 --- a/tuskar_ui/api/tuskar.py +++ b/tuskar_ui/api/tuskar.py @@ -21,6 +21,7 @@ from tuskarclient.v1 import client as tuskar_client 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() @@ -61,19 +62,18 @@ class OvercloudPlan(base.APIDictWrapper): :return: the created OvercloudPlan object :rtype: tuskar_ui.api.tuskar.OvercloudPlan """ - - return cls(TEST_DATA.tuskarclient_plans.first(), - request=request) + plan = mock_tuskar.Plan.create(name, description) + return cls(plan, request=request) @classmethod - def update(cls, request, overcloud_id, name, description): + def update(cls, request, plan_id, name, description): """Update an OvercloudPlan in Tuskar :param request: request object :type request: django.http.HttpRequest - :param overcloud_id: id of the overcloud we want to update - :type overcloud_id: string + :param plan_id: id of the plan we want to update + :type plan_id: string :param name: plan name :type name: string @@ -84,8 +84,8 @@ class OvercloudPlan(base.APIDictWrapper): :return: the updated OvercloudPlan object :rtype: tuskar_ui.api.tuskar.OvercloudPlan """ - return cls(TEST_DATA.tuskarclient_plans.first(), - request=request) + plan = mock_tuskar.Plan.update(plan_id, name, description) + return cls(plan, request=request) @classmethod def list(cls, request): @@ -97,7 +97,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 = TEST_DATA.tuskarclient_plans.list() + plans = mock_tuskar.Plan.list() return [cls(plan, request=request) for plan in plans] @@ -116,8 +116,7 @@ class OvercloudPlan(base.APIDictWrapper): the ID :rtype: tuskar_ui.api.tuskar.OvercloudPlan """ - # FIXME(lsmola) hack for Icehouse, only one Overcloud is allowed - return cls.get_the_plan(request) + return cls(mock_tuskar.Plan.get(plan_id)) # TODO(lsmola) before will will support multiple overclouds, we # can work only with overcloud that is named overcloud. Delete @@ -131,8 +130,7 @@ class OvercloudPlan(base.APIDictWrapper): def get_the_plan(cls, request): plan_list = cls.list(request) for plan in plan_list: - if plan.name == 'overcloud': - return plan + return plan @classmethod def delete(cls, request, plan_id): @@ -144,7 +142,7 @@ class OvercloudPlan(base.APIDictWrapper): :param plan_id: plan id :type plan_id: int """ - return + mock_tuskar.Plan.delete(plan_id) @cached_property def role_list(self): diff --git a/tuskar_ui/infrastructure/history/tests.py b/tuskar_ui/infrastructure/history/tests.py index 7d4568050..93232aa20 100644 --- a/tuskar_ui/infrastructure/history/tests.py +++ b/tuskar_ui/infrastructure/history/tests.py @@ -12,17 +12,22 @@ # 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 openstack_dashboard.test.test_data import utils +from tuskar_ui import api from tuskar_ui.test import helpers as test from tuskar_ui.test.test_data import heat_data +from tuskar_ui.test.test_data import tuskar_data TEST_DATA = utils.TestDataContainer() heat_data.data(TEST_DATA) +tuskar_data.data(TEST_DATA) INDEX_URL = urlresolvers.reverse( 'horizon:infrastructure:history:index') @@ -30,10 +35,20 @@ INDEX_URL = urlresolvers.reverse( class HistoryTest(test.BaseAdminViewTests): def test_index(self): + plan = api.tuskar.OvercloudPlan( + TEST_DATA.tuskarclient_plans.first()) + stack = api.heat.Stack( + TEST_DATA.heatclient_stacks.first()) events = TEST_DATA.heatclient_events.list() - with patch('tuskar_ui.api.heat.Stack.events', - return_value=events): + with contextlib.nested( + patch('tuskar_ui.api.tuskar.OvercloudPlan.get_the_plan', + return_value=plan), + patch('tuskar_ui.api.heat.Stack.get_by_plan', + return_value=stack), + patch('tuskar_ui.api.heat.Stack.events', + return_value=events) + ): res = self.client.get(INDEX_URL) self.assertTemplateUsed(res, 'infrastructure/history/index.html') diff --git a/tuskar_ui/infrastructure/parameters/tests.py b/tuskar_ui/infrastructure/parameters/tests.py index 530b88980..5550254b8 100644 --- a/tuskar_ui/infrastructure/parameters/tests.py +++ b/tuskar_ui/infrastructure/parameters/tests.py @@ -12,20 +12,32 @@ # 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 openstack_dashboard.test.test_data import utils +from tuskar_ui import api from tuskar_ui.test import helpers as test +from tuskar_ui.test.test_data import tuskar_data INDEX_URL = urlresolvers.reverse( 'horizon:infrastructure:parameters:index') +TEST_DATA = utils.TestDataContainer() +tuskar_data.data(TEST_DATA) + class ParametersTest(test.BaseAdminViewTests): def test_index(self): - res = self.client.get(INDEX_URL) + plan = api.tuskar.OvercloudPlan(TEST_DATA.tuskarclient_plans.first()) + with contextlib.nested( + patch('tuskar_ui.api.tuskar.OvercloudPlan.get_the_plan', + return_value=plan), + ): + res = self.client.get(INDEX_URL) self.assertTemplateUsed(res, 'infrastructure/parameters/index.html') diff --git a/tuskar_ui/infrastructure/plans/workflows/create.py b/tuskar_ui/infrastructure/plans/workflows/create.py index fe083544d..45cbae8a7 100644 --- a/tuskar_ui/infrastructure/plans/workflows/create.py +++ b/tuskar_ui/infrastructure/plans/workflows/create.py @@ -14,7 +14,6 @@ import logging import django.forms -from django.utils import translation from django.utils.translation import ugettext_lazy as _ import horizon.workflows @@ -26,32 +25,7 @@ from tuskar_ui.infrastructure.plans.workflows import create_overview LOG = logging.getLogger(__name__) -class DeploymentValidationMixin(object): - def validate(self, context): - requested = sum(context['role_counts'].values()) - # TODO(lsmola) change this when we support more overclouds. It - # will have to obtain actual free nodes and compare them to - # number of newly created. - free = len(api.node.Node.list(self.request)) - if requested > free: - m1 = translation.ungettext_lazy( - 'This configuration requires %(requested)d node, ', - 'This configuration requires %(requested)d nodes, ', - requested) - m1 %= {'requested': requested} - m2 = translation.ungettext_lazy( - 'but only %(free)d is available.', - 'but only %(free)d are available.', - free) - m2 %= {'free': free} - message = unicode(translation.string_concat(m1, m2)) - self.add_error_to_step(message, 'create_overview') - self.add_error_to_step(message, 'scale_node_counts') - return False - return super(DeploymentValidationMixin, self).validate(context) - - -class Workflow(DeploymentValidationMixin, horizon.workflows.Workflow): +class Workflow(horizon.workflows.Workflow): slug = 'create_plan' name = _("My OpenStack Deployment Plan") default_steps = ( diff --git a/tuskar_ui/infrastructure/plans/workflows/scale.py b/tuskar_ui/infrastructure/plans/workflows/scale.py index da91d9a6d..efa0a20ae 100644 --- a/tuskar_ui/infrastructure/plans/workflows/scale.py +++ b/tuskar_ui/infrastructure/plans/workflows/scale.py @@ -18,12 +18,10 @@ from horizon import exceptions import horizon.workflows from tuskar_ui import api -from tuskar_ui.infrastructure.plans.workflows import create from tuskar_ui.infrastructure.plans.workflows import scale_node_counts -class Workflow(create.DeploymentValidationMixin, - horizon.workflows.Workflow): +class Workflow(horizon.workflows.Workflow): slug = 'scale_overcloud' name = _("Scale Deployment") default_steps = ( diff --git a/tuskar_ui/test/api_tests/heat_tests.py b/tuskar_ui/test/api_tests/heat_tests.py index ba63cdb51..d3c78582a 100644 --- a/tuskar_ui/test/api_tests/heat_tests.py +++ b/tuskar_ui/test/api_tests/heat_tests.py @@ -37,7 +37,11 @@ class HeatAPITests(test.APITestCase): def test_stack_plan(self): stack = api.heat.Stack(self.heatclient_stacks.first()) - ret_val = stack.plan + plan = self.tuskarclient_plans.first() + + with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.get', + return_value=plan): + ret_val = stack.plan self.assertIsInstance(ret_val, api.tuskar.OvercloudPlan) def test_stack_events(self): @@ -100,6 +104,7 @@ class HeatAPITests(test.APITestCase): def test_stack_dashboard_url(self): stack = api.heat.Stack(self.heatclient_stacks.first()) + stack.plan = api.tuskar.OvercloudPlan(self.tuskarclient_plans.first()) mocked_service = mock.Mock(id='horizon_id') mocked_service.name = 'horizon' diff --git a/tuskar_ui/test/api_tests/tuskar_tests.py b/tuskar_ui/test/api_tests/tuskar_tests.py index 35f75077a..5e94f6501 100644 --- a/tuskar_ui/test/api_tests/tuskar_tests.py +++ b/tuskar_ui/test/api_tests/tuskar_tests.py @@ -21,18 +21,29 @@ from tuskar_ui.test import helpers as test class TuskarAPITests(test.APITestCase): def test_plan_create(self): - ret_val = api.tuskar.OvercloudPlan.create(self.request, {}, {}) + plan = self.tuskarclient_plans.first() + + with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.create', + return_value=plan): + ret_val = api.tuskar.OvercloudPlan.create(self.request, {}, {}) self.assertIsInstance(ret_val, api.tuskar.OvercloudPlan) def test_plan_list(self): - ret_val = api.tuskar.OvercloudPlan.list(self.request) + plans = self.tuskarclient_plans.list() + + with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.list', + return_value=plans): + ret_val = api.tuskar.OvercloudPlan.list(self.request) for plan in ret_val: self.assertIsInstance(plan, api.tuskar.OvercloudPlan) self.assertEqual(1, len(ret_val)) def test_plan_get(self): plan = self.tuskarclient_plans.first() - ret_val = api.tuskar.OvercloudPlan.get(self.request, plan['id']) + + with patch('tuskar_ui.test.test_driver.tuskar_driver.Plan.get', + return_value=plan): + ret_val = api.tuskar.OvercloudPlan.get(self.request, plan['id']) self.assertIsInstance(ret_val, api.tuskar.OvercloudPlan) diff --git a/tuskar_ui/test/test_driver/__init__.py b/tuskar_ui/test/test_driver/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tuskar_ui/test/test_driver/tuskar_driver.py b/tuskar_ui/test/test_driver/tuskar_driver.py new file mode 100644 index 000000000..5306c5e63 --- /dev/null +++ b/tuskar_ui/test/test_driver/tuskar_driver.py @@ -0,0 +1,47 @@ +# 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)