3d2b7facda
It is a convention to have assertEqual() assertions invoked with 'expected value' before 'actual value', or else the debug output may become very confusing. This patch fixes about 100 violations in current test cases where about 3580 assertEqual calls are made. Closes-Bug: 1259292 Change-Id: I2e0474d9821716baf35a3bbb2952c63a84749dd3
259 lines
9.1 KiB
Python
259 lines
9.1 KiB
Python
#
|
|
# 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.
|
|
|
|
import mock
|
|
|
|
from heat.common import lifecycle_plugin_utils
|
|
from heat.engine import lifecycle_plugin
|
|
from heat.engine import resources
|
|
from heat.tests import common
|
|
|
|
|
|
empty_template = '''
|
|
heat_template_version: '2013-05-23'
|
|
description: Empty stack
|
|
resources:
|
|
'''
|
|
|
|
|
|
class LifecyclePluginUtilsTests(common.HeatTestCase):
|
|
"""
|
|
Basic tests for the helper methods in
|
|
:module:'heat.common.lifecycle_plugin_utils'.
|
|
"""
|
|
|
|
def setUp(self):
|
|
super(LifecyclePluginUtilsTests, self).setUp()
|
|
|
|
def tearDown(self):
|
|
super(LifecyclePluginUtilsTests, self).tearDown()
|
|
lifecycle_plugin_utils.pp_class_instances = None
|
|
|
|
def mock_lcp_class_map(self, lcp_mappings):
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(resources.global_env(),
|
|
'get_stack_lifecycle_plugins')
|
|
resources.global_env().get_stack_lifecycle_plugins().\
|
|
MultipleTimes().AndReturn(lcp_mappings)
|
|
self.m.ReplayAll()
|
|
# reset cache
|
|
lifecycle_plugin_utils.pp_class_instances = None
|
|
|
|
def test_get_plug_point_class_instances(self):
|
|
"""Tests the get_plug_point_class_instances function."""
|
|
lcp_mappings = [('A::B::C1', TestLifecycleCallout1)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
|
|
pp_cinstances = lifecycle_plugin_utils.get_plug_point_class_instances()
|
|
self.assertIsNotNone(pp_cinstances)
|
|
self.assertTrue(self.is_iterable(pp_cinstances),
|
|
"not iterable: %s" % pp_cinstances)
|
|
self.assertTrue(len(pp_cinstances) == 1)
|
|
self.assertEqual(TestLifecycleCallout1, pp_cinstances[0].__class__)
|
|
|
|
def test_do_pre_and_post_callouts(self):
|
|
lcp_mappings = [('A::B::C1', TestLifecycleCallout1)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
mc = mock.Mock()
|
|
mc.__setattr__("pre_counter_for_unit_test", 0)
|
|
mc.__setattr__("post_counter_for_unit_test", 0)
|
|
ms = mock.Mock()
|
|
ms.__setattr__("action", 'A')
|
|
lifecycle_plugin_utils.do_pre_ops(mc, ms, None, None)
|
|
self.assertEqual(1, mc.pre_counter_for_unit_test)
|
|
lifecycle_plugin_utils.do_post_ops(mc, ms, None, None)
|
|
self.assertEqual(1, mc.post_counter_for_unit_test)
|
|
|
|
return
|
|
|
|
def test_class_instantiation_and_sorting(self):
|
|
lcp_mappings = []
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
pp_cis = lifecycle_plugin_utils.get_plug_point_class_instances()
|
|
self.assertEqual(0, len(pp_cis))
|
|
|
|
# order should change with sort
|
|
lcp_mappings = [('A::B::C2', TestLifecycleCallout2),
|
|
('A::B::C1', TestLifecycleCallout1)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
pp_cis = lifecycle_plugin_utils.get_plug_point_class_instances()
|
|
self.assertEqual(2, len(pp_cis))
|
|
self.assertEqual(100, pp_cis[0].get_ordinal())
|
|
self.assertEqual(101, pp_cis[1].get_ordinal())
|
|
self.assertEqual(TestLifecycleCallout1, pp_cis[0].__class__)
|
|
self.assertEqual(TestLifecycleCallout2, pp_cis[1].__class__)
|
|
|
|
# order should NOT change with sort
|
|
lcp_mappings = [('A::B::C1', TestLifecycleCallout1),
|
|
('A::B::C2', TestLifecycleCallout2)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
pp_cis = lifecycle_plugin_utils.get_plug_point_class_instances()
|
|
self.assertEqual(2, len(pp_cis))
|
|
self.assertEqual(100, pp_cis[0].get_ordinal())
|
|
self.assertEqual(101, pp_cis[1].get_ordinal())
|
|
self.assertEqual(TestLifecycleCallout1, pp_cis[0].__class__)
|
|
self.assertEqual(TestLifecycleCallout2, pp_cis[1].__class__)
|
|
|
|
# sort failure due to exception in thrown by ordinal
|
|
lcp_mappings = [('A::B::C2', TestLifecycleCallout2),
|
|
('A::B::C3', TestLifecycleCallout3),
|
|
('A::B::C1', TestLifecycleCallout1)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
pp_cis = lifecycle_plugin_utils.get_plug_point_class_instances()
|
|
self.assertEqual(3, len(pp_cis))
|
|
self.assertEqual(100, pp_cis[2].get_ordinal())
|
|
self.assertEqual(101, pp_cis[0].get_ordinal())
|
|
# (can sort fail partially? If so then this test may break)
|
|
self.assertEqual(TestLifecycleCallout2, pp_cis[0].__class__)
|
|
self.assertEqual(TestLifecycleCallout3, pp_cis[1].__class__)
|
|
self.assertEqual(TestLifecycleCallout1, pp_cis[2].__class__)
|
|
|
|
return
|
|
|
|
def test_do_pre_op_failure(self):
|
|
lcp_mappings = [('A::B::C5', TestLifecycleCallout1),
|
|
('A::B::C4', TestLifecycleCallout4)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
mc = mock.Mock()
|
|
mc.__setattr__("pre_counter_for_unit_test", 0)
|
|
mc.__setattr__("post_counter_for_unit_test", 0)
|
|
ms = mock.Mock()
|
|
ms.__setattr__("action", 'A')
|
|
failed = False
|
|
try:
|
|
lifecycle_plugin_utils.do_pre_ops(mc, ms, None, None)
|
|
except Exception:
|
|
failed = True
|
|
self.assertTrue(failed)
|
|
self.assertEqual(1, mc.pre_counter_for_unit_test)
|
|
self.assertEqual(1, mc.post_counter_for_unit_test)
|
|
|
|
return
|
|
|
|
def test_do_post_op_failure(self):
|
|
lcp_mappings = [('A::B::C1', TestLifecycleCallout1),
|
|
('A::B::C5', TestLifecycleCallout5)]
|
|
self.mock_lcp_class_map(lcp_mappings)
|
|
mc = mock.Mock()
|
|
mc.__setattr__("pre_counter_for_unit_test", 0)
|
|
mc.__setattr__("post_counter_for_unit_test", 0)
|
|
ms = mock.Mock()
|
|
ms.__setattr__("action", 'A')
|
|
lifecycle_plugin_utils.do_post_ops(mc, ms, None, None)
|
|
self.assertEqual(1, mc.post_counter_for_unit_test)
|
|
|
|
return
|
|
|
|
def test_exercise_base_lifecycle_plugin_class(self):
|
|
lcp = lifecycle_plugin.LifecyclePlugin()
|
|
ordinal = lcp.get_ordinal()
|
|
lcp.do_pre_op(None, None, None)
|
|
lcp.do_post_op(None, None, None)
|
|
self.assertEqual(100, ordinal)
|
|
|
|
return
|
|
|
|
def is_iterable(self, obj):
|
|
#special case string
|
|
if not object:
|
|
return False
|
|
if isinstance(obj, str):
|
|
return False
|
|
|
|
#Test for iterabilityy
|
|
try:
|
|
for m in obj:
|
|
break
|
|
except TypeError:
|
|
return False
|
|
return True
|
|
|
|
|
|
class TestLifecycleCallout1(lifecycle_plugin.LifecyclePlugin):
|
|
'''
|
|
Sample test class for testing pre-op and post-op work on a stack
|
|
'''
|
|
def do_pre_op(self, cnxt, stack, current_stack=None, action=None):
|
|
cnxt.pre_counter_for_unit_test += 1
|
|
|
|
def do_post_op(self, cnxt, stack, current_stack=None, action=None,
|
|
is_stack_failure=False):
|
|
cnxt.post_counter_for_unit_test += 1
|
|
|
|
def get_ordinal(self):
|
|
return 100
|
|
|
|
|
|
class TestLifecycleCallout2(lifecycle_plugin.LifecyclePlugin):
|
|
'''
|
|
Sample test class for testing pre-op and post-op work on a stack,
|
|
different ordinal, and increment counters by 2
|
|
'''
|
|
def do_pre_op(self, cnxt, stack, current_stack=None, action=None):
|
|
cnxt.pre_counter_for_unit_test += 2
|
|
|
|
def do_post_op(self, cnxt, stack, current_stack=None, action=None,
|
|
is_stack_failure=False):
|
|
cnxt.post_counter_for_unit_test += 2
|
|
|
|
def get_ordinal(self):
|
|
return 101
|
|
|
|
|
|
class TestLifecycleCallout3(lifecycle_plugin.LifecyclePlugin):
|
|
'''
|
|
Sample test class for testing pre-op and post-op work on a stack,
|
|
methods raise exceptions
|
|
'''
|
|
def do_pre_op(self, cnxt, stack, current_stack=None, action=None):
|
|
raise Exception()
|
|
|
|
def do_post_op(self, cnxt, stack, current_stack=None, action=None,
|
|
is_stack_failure=False):
|
|
raise Exception()
|
|
|
|
def get_ordinal(self):
|
|
raise Exception()
|
|
|
|
|
|
class TestLifecycleCallout4(lifecycle_plugin.LifecyclePlugin):
|
|
'''
|
|
Sample test class for testing pre-op and post-op work on a stack;
|
|
do_pre_op, do_post_op both throw exception
|
|
'''
|
|
def do_pre_op(self, cnxt, stack, current_stack=None, action=None):
|
|
raise Exception()
|
|
|
|
def do_post_op(self, cnxt, stack, current_stack=None, action=None,
|
|
is_stack_failure=False):
|
|
raise Exception()
|
|
|
|
def get_ordinal(self):
|
|
return 103
|
|
|
|
|
|
class TestLifecycleCallout5(lifecycle_plugin.LifecyclePlugin):
|
|
'''
|
|
Sample test class for testing pre-op and post-op work on a stack;
|
|
do_post_op throws exception
|
|
'''
|
|
def do_pre_op(self, cnxt, stack, current_stack=None, action=None):
|
|
cnxt.pre_counter_for_unit_test += 1
|
|
|
|
def do_post_op(self, cnxt, stack, current_stack=None, action=None,
|
|
is_stack_failure=False):
|
|
raise Exception()
|
|
|
|
def get_ordinal(self):
|
|
return 100
|