Improve unit tests to succeed without hash tweak
PYTHONHASHSEED was set to 0 to disable hash randomization, because some tests assertions were order sensitive. This commit is to improve the assertions, so the PYTHONHASHSEED hack in tox.ini is not needed. Change-Id: I4ff09d202af818d27321e8e83718e82d0c48e3d2 Closes-Bug: 1348818
This commit is contained in:
parent
87e625e20c
commit
b070ed0286
@ -17,6 +17,7 @@ import json
|
||||
import uuid
|
||||
|
||||
import mock
|
||||
import mox
|
||||
import six
|
||||
|
||||
from heat.common import exception
|
||||
@ -1229,11 +1230,11 @@ class LoadBalancerTest(common.HeatTestCase):
|
||||
template['Resources'][lb_name]['Properties']['metadata'] = {
|
||||
'a': 1, 'b': 2}
|
||||
expected_body = copy.deepcopy(self.expected_body)
|
||||
expected_body['metadata'] = [{'key': 'a', 'value': 1},
|
||||
{'key': 'b', 'value': 2}]
|
||||
rsrc, fake_loadbalancer = self._mock_loadbalancer(template,
|
||||
self.lb_name,
|
||||
expected_body)
|
||||
expected_body['metadata'] = mox.SameElementsAs(
|
||||
[{'key': 'a', 'value': 1},
|
||||
{'key': 'b', 'value': 2}])
|
||||
rsrc, fake_loadbalancer = self._mock_loadbalancer(
|
||||
template, self.lb_name, expected_body)
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
|
@ -24,12 +24,13 @@ from heat.api.aws import ec2token
|
||||
from heat.api.aws import exception
|
||||
from heat.common import wsgi
|
||||
from heat.tests import common
|
||||
from heat.tests import utils
|
||||
|
||||
|
||||
class Ec2TokenTest(common.HeatTestCase):
|
||||
'''
|
||||
"""
|
||||
Tests the Ec2Token middleware
|
||||
'''
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(Ec2TokenTest, self).setUp()
|
||||
@ -253,8 +254,9 @@ class Ec2TokenTest(common.HeatTestCase):
|
||||
"path": "/v1",
|
||||
"body_hash": body_hash}})
|
||||
req_headers = {'Content-Type': 'application/json'}
|
||||
requests.post(req_url, data=req_creds, verify=verify, cert=cert,
|
||||
headers=req_headers).AndReturn(DummyHTTPResponse())
|
||||
requests.post(
|
||||
req_url, data=utils.JsonEquals(req_creds), verify=verify,
|
||||
cert=cert, headers=req_headers).AndReturn(DummyHTTPResponse())
|
||||
|
||||
def test_call_ok(self):
|
||||
dummy_conf = {'auth_uri': 'http://123:5000/v2.0'}
|
||||
|
@ -33,10 +33,10 @@ policy_path = os.path.dirname(os.path.realpath(__file__)) + "/../../policy/"
|
||||
|
||||
|
||||
class CfnStackControllerTest(common.HeatTestCase):
|
||||
'''
|
||||
"""
|
||||
Tests the API class which acts as the WSGI controller,
|
||||
the endpoint processing API requests after they are routed
|
||||
'''
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(CfnStackControllerTest, self).setUp()
|
||||
@ -333,7 +333,8 @@ class CfnStackControllerTest(common.HeatTestCase):
|
||||
'DisableRollback': 'true',
|
||||
'LastUpdatedTime': u'2012-07-09T09:13:11Z'}]}}}
|
||||
|
||||
self.assertEqual(expected, response)
|
||||
self.assertEqual(utils.recursive_sort(expected),
|
||||
utils.recursive_sort(response))
|
||||
|
||||
def test_describe_arn(self):
|
||||
# Format a dummy GET request to pass into the WSGI handler
|
||||
@ -417,7 +418,8 @@ class CfnStackControllerTest(common.HeatTestCase):
|
||||
'DisableRollback': 'true',
|
||||
'LastUpdatedTime': u'2012-07-09T09:13:11Z'}]}}}
|
||||
|
||||
self.assertEqual(expected, response)
|
||||
self.assertEqual(utils.recursive_sort(expected),
|
||||
utils.recursive_sort(response))
|
||||
|
||||
def test_describe_arn_invalidtenant(self):
|
||||
# Format a dummy GET request to pass into the WSGI handler
|
||||
@ -481,7 +483,7 @@ class CfnStackControllerTest(common.HeatTestCase):
|
||||
self.assertIsInstance(result, exception.HeatInvalidParameterValueError)
|
||||
|
||||
def test_get_template_int_body(self):
|
||||
'''Test the internal _get_template function.'''
|
||||
"""Test the internal _get_template function."""
|
||||
params = {'TemplateBody': "abcdef"}
|
||||
dummy_req = self._dummy_GET_request(params)
|
||||
result = self.controller._get_template(dummy_req)
|
||||
|
@ -73,11 +73,13 @@ class WatchControllerTest(common.HeatTestCase):
|
||||
|
||||
dims = [{'StackId': u'21617058-781e-4262-97ab-5f9df371ee52',
|
||||
'Foo': 'bar'}]
|
||||
self.assertEqual([{'Name': 'StackId',
|
||||
'Value': u'21617058-781e-4262-97ab-5f9df371ee52'},
|
||||
{'Name': 'Foo', 'Value': 'bar'}],
|
||||
self.controller._reformat_dimensions(dims)
|
||||
)
|
||||
self.assertEqual(
|
||||
utils.recursive_sort(
|
||||
[{'Name': 'StackId',
|
||||
'Value': u'21617058-781e-4262-97ab-5f9df371ee52'},
|
||||
{'Name': 'Foo',
|
||||
'Value': 'bar'}]),
|
||||
utils.recursive_sort(self.controller._reformat_dimensions(dims)))
|
||||
|
||||
def test_enforce_default(self):
|
||||
self.m.ReplayAll()
|
||||
@ -301,7 +303,9 @@ class WatchControllerTest(common.HeatTestCase):
|
||||
'MetricName': u'ServiceFailure3'}]}}}
|
||||
|
||||
# First pass no query paramters filtering, should get all three
|
||||
self.assertEqual(expected, self.controller.list_metrics(dummy_req))
|
||||
self.assertEqual(
|
||||
utils.recursive_sort(expected),
|
||||
utils.recursive_sort(self.controller.list_metrics(dummy_req)))
|
||||
|
||||
def test_list_metrics_filter_name(self):
|
||||
|
||||
@ -358,7 +362,9 @@ class WatchControllerTest(common.HeatTestCase):
|
||||
'Value': 1}],
|
||||
'MetricName': u'ServiceFailure'}]}}}
|
||||
# First pass no query paramters filtering, should get all three
|
||||
self.assertEqual(expected, self.controller.list_metrics(dummy_req))
|
||||
self.assertEqual(
|
||||
utils.recursive_sort(expected),
|
||||
utils.recursive_sort(self.controller.list_metrics(dummy_req)))
|
||||
|
||||
def test_list_metrics_filter_namespace(self):
|
||||
|
||||
@ -426,7 +432,9 @@ class WatchControllerTest(common.HeatTestCase):
|
||||
{'Name': u'Value',
|
||||
'Value': 1}],
|
||||
'MetricName': u'ServiceFailure2'}]}}}
|
||||
self.assertEqual(expected, self.controller.list_metrics(dummy_req))
|
||||
self.assertEqual(
|
||||
utils.recursive_sort(expected),
|
||||
utils.recursive_sort(self.controller.list_metrics(dummy_req)))
|
||||
|
||||
def test_put_metric_alarm(self):
|
||||
# Not yet implemented, should raise HeatAPINotImplementedError
|
||||
|
@ -38,10 +38,12 @@ class TestViewsCommon(common.HeatTestCase):
|
||||
self.setUpGetCollectionLinks()
|
||||
links = views_common.get_collection_links(self.request, self.items)
|
||||
|
||||
expected = 'http://example.com/fake/path?marker=id2&limit=2'
|
||||
expected_params = {'marker': ['id2'], 'limit': ['2']}
|
||||
next_link = filter(lambda link: link['rel'] == 'next', links).pop()
|
||||
self.assertEqual('next', next_link['rel'])
|
||||
self.assertEqual(expected, next_link['href'])
|
||||
url_path, url_params = next_link['href'].split('?', 1)
|
||||
self.assertEqual(url_path, self.request.path_url)
|
||||
self.assertEqual(expected_params, urlparse.parse_qs(url_params))
|
||||
|
||||
def test_get_collection_links_doesnt_create_next_if_no_limit(self):
|
||||
self.setUpGetCollectionLinks()
|
||||
@ -62,9 +64,12 @@ class TestViewsCommon(common.HeatTestCase):
|
||||
self.request.params = {'limit': '2', 'marker': 'some_marker'}
|
||||
links = views_common.get_collection_links(self.request, self.items)
|
||||
|
||||
expected = 'http://example.com/fake/path?marker=id2&limit=2'
|
||||
expected_params = {'marker': ['id2'], 'limit': ['2']}
|
||||
next_link = filter(lambda link: link['rel'] == 'next', links).pop()
|
||||
self.assertEqual(expected, next_link['href'])
|
||||
self.assertEqual('next', next_link['rel'])
|
||||
url_path, url_params = next_link['href'].split('?', 1)
|
||||
self.assertEqual(url_path, self.request.path_url)
|
||||
self.assertEqual(expected_params, urlparse.parse_qs(url_params))
|
||||
|
||||
def test_get_collection_links_does_not_overwrite_other_params(self):
|
||||
self.setUpGetCollectionLinks()
|
||||
|
@ -88,7 +88,8 @@ class LoadBalancerTest(common.HeatTestCase):
|
||||
lb_defn = s.t.resource_definitions(s)[resource_name]
|
||||
rsrc = lb.LoadBalancer(resource_name, lb_defn, s)
|
||||
|
||||
nova.NovaClientPlugin._create = mock.Mock(return_value=self.fc)
|
||||
self.patchobject(nova.NovaClientPlugin, '_create',
|
||||
return_value=self.fc)
|
||||
|
||||
initial_md = {'AWS::CloudFormation::Init':
|
||||
{'config':
|
||||
|
@ -198,7 +198,7 @@ class CeilometerAlarmTest(common.HeatTestCase):
|
||||
if 'matching_metadata' in al:
|
||||
del al['matching_metadata']
|
||||
if query:
|
||||
rule['query'] = query
|
||||
rule['query'] = mox.SameElementsAs(query)
|
||||
al['threshold_rule'] = rule
|
||||
al['type'] = 'threshold'
|
||||
self.m.StubOutWithMock(self.fa.alarms, 'create')
|
||||
@ -396,8 +396,9 @@ class CeilometerAlarmTest(common.HeatTestCase):
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_mem_alarm_high_not_correct_string_parameters(self):
|
||||
snippet = template_format.parse(not_string_alarm_template)
|
||||
orig_snippet = template_format.parse(not_string_alarm_template)
|
||||
for p in ('period', 'evaluation_periods'):
|
||||
snippet = copy.deepcopy(orig_snippet)
|
||||
snippet['Resources']['MEMAlarmHigh']['Properties'][p] = '60a'
|
||||
stack = utils.parse_stack(snippet)
|
||||
|
||||
@ -411,8 +412,9 @@ class CeilometerAlarmTest(common.HeatTestCase):
|
||||
"Value '60a' is not an integer" % p, six.text_type(error))
|
||||
|
||||
def test_mem_alarm_high_not_integer_parameters(self):
|
||||
snippet = template_format.parse(not_string_alarm_template)
|
||||
orig_snippet = template_format.parse(not_string_alarm_template)
|
||||
for p in ('period', 'evaluation_periods'):
|
||||
snippet = copy.deepcopy(orig_snippet)
|
||||
snippet['Resources']['MEMAlarmHigh']['Properties'][p] = [60]
|
||||
stack = utils.parse_stack(snippet)
|
||||
|
||||
|
@ -374,7 +374,12 @@ class NovaClientPluginMetadataTests(NovaClientPluginTestCase):
|
||||
self.assertEqual(expected, self.nova_plugin.meta_serialize(original))
|
||||
|
||||
def test_serialize_dict(self):
|
||||
original = {'test_key': {'a': 'b', 'c': 'd'}}
|
||||
original = collections.OrderedDict([
|
||||
('test_key', collections.OrderedDict([
|
||||
('a', 'b'),
|
||||
('c', 'd'),
|
||||
]))
|
||||
])
|
||||
expected = {'test_key': '{"a": "b", "c": "d"}'}
|
||||
actual = self.nova_plugin.meta_serialize(original)
|
||||
self.assertEqual(json.loads(expected['test_key']),
|
||||
|
@ -85,6 +85,11 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
|
||||
return self.engine.create_software_config(
|
||||
self.ctx, group, name, config, inputs, outputs, options)
|
||||
|
||||
def assert_status_reason(self, expected, actual):
|
||||
expected_dict = dict((i.split(' : ') for i in expected.split(', ')))
|
||||
actual_dict = dict((i.split(' : ') for i in actual.split(', ')))
|
||||
self.assertEqual(expected_dict, actual_dict)
|
||||
|
||||
def test_list_software_configs(self):
|
||||
config = self._create_software_config()
|
||||
config_id = config['id']
|
||||
@ -362,7 +367,7 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
|
||||
sd = software_deployment_object.SoftwareDeployment.get_by_id(
|
||||
self.ctx, deployment_id)
|
||||
self.assertEqual('FAILED', sd.status)
|
||||
self.assertEqual(
|
||||
self.assert_status_reason(
|
||||
('deploy_status_code : Deployment exited with non-zero '
|
||||
'status code: -1'),
|
||||
sd.status_reason)
|
||||
@ -394,7 +399,7 @@ class SoftwareConfigServiceTest(common.HeatTestCase):
|
||||
sd = software_deployment_object.SoftwareDeployment.get_by_id(
|
||||
self.ctx, deployment_id)
|
||||
self.assertEqual('FAILED', sd.status)
|
||||
self.assertEqual(
|
||||
self.assert_status_reason(
|
||||
('foo : bar, deploy_status_code : Deployment exited with '
|
||||
'non-zero status code: -1'),
|
||||
sd.status_reason)
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
@ -31,8 +32,9 @@ class GenericResource(resource.Resource):
|
||||
Dummy resource for use in tests
|
||||
'''
|
||||
properties_schema = {}
|
||||
attributes_schema = {'foo': attributes.Schema('A generic attribute'),
|
||||
'Foo': attributes.Schema('Another generic attribute')}
|
||||
attributes_schema = collections.OrderedDict([
|
||||
('foo', attributes.Schema('A generic attribute')),
|
||||
('Foo', attributes.Schema('Another generic attribute'))])
|
||||
|
||||
@classmethod
|
||||
def is_service_available(cls, context):
|
||||
|
@ -214,7 +214,8 @@ class HeatWaitConditionTest(common.HeatTestCase):
|
||||
'status': 'SUCCESS', 'id': '456'}
|
||||
ret = handle.handle_signal(details=test_metadata)
|
||||
wc_att = rsrc.FnGetAtt('data')
|
||||
self.assertEqual(u'{"123": "foo", "456": "dog"}', wc_att)
|
||||
self.assertEqual(json.loads(u'{"123": "foo", "456": "dog"}'),
|
||||
json.loads(wc_att))
|
||||
self.assertEqual('status:SUCCESS reason:cat', ret)
|
||||
self.m.VerifyAll()
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import datetime
|
||||
|
||||
import webob
|
||||
@ -37,13 +38,21 @@ class JSONResponseSerializerTest(common.HeatTestCase):
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_to_json_with_more_deep_format(self):
|
||||
fixture = {"is_public": True, "name": [{"name1": "test"}]}
|
||||
fixture = collections.OrderedDict([
|
||||
('is_public', True),
|
||||
('name', [collections.OrderedDict([
|
||||
('name1', 'test'),
|
||||
])])
|
||||
])
|
||||
expected = '{"is_public": true, "name": [{"name1": "test"}]}'
|
||||
actual = serializers.JSONResponseSerializer().to_json(fixture)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_to_json_with_objects(self):
|
||||
fixture = {"is_public": True, "value": complex(1, 2)}
|
||||
fixture = collections.OrderedDict([
|
||||
('is_public', True),
|
||||
('value', complex(1, 2)),
|
||||
])
|
||||
expected = '{"is_public": true, "value": "(1+2j)"}'
|
||||
actual = serializers.JSONResponseSerializer().to_json(fixture)
|
||||
self.assertEqual(expected, actual)
|
||||
@ -83,8 +92,14 @@ class XMLResponseSerializerTest(common.HeatTestCase):
|
||||
def test_to_xml_with_more_deep_format(self):
|
||||
# Note we expect tree traversal from one root key, which is compatible
|
||||
# with the AWS format responses we need to serialize
|
||||
fixture = {"aresponse":
|
||||
{"is_public": True, "name": [{"name1": "test"}]}}
|
||||
fixture = collections.OrderedDict([
|
||||
('aresponse', collections.OrderedDict([
|
||||
('is_public', True),
|
||||
('name', [collections.OrderedDict([
|
||||
('name1', 'test'),
|
||||
])])
|
||||
]))
|
||||
])
|
||||
expected = ('<aresponse><is_public>True</is_public>'
|
||||
'<name><member><name1>test</name1></member></name>'
|
||||
'</aresponse>')
|
||||
@ -94,10 +109,13 @@ class XMLResponseSerializerTest(common.HeatTestCase):
|
||||
def test_to_xml_with_json_only_keys(self):
|
||||
# Certain keys are excluded from serialization because CFN
|
||||
# format demands a json blob in the XML body
|
||||
fixture = {"aresponse":
|
||||
{"is_public": True,
|
||||
"TemplateBody": {"name1": "test"},
|
||||
"Metadata": {"name2": "test2"}}}
|
||||
fixture = collections.OrderedDict([
|
||||
('aresponse', collections.OrderedDict([
|
||||
('is_public', True),
|
||||
('TemplateBody', {"name1": "test"}),
|
||||
('Metadata', {"name2": "test2"}),
|
||||
]))
|
||||
])
|
||||
expected = ('<aresponse><is_public>True</is_public>'
|
||||
'<TemplateBody>{"name1": "test"}</TemplateBody>'
|
||||
'<Metadata>{"name2": "test2"}</Metadata></aresponse>')
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
import mock
|
||||
import mox
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from heat.common import identifier
|
||||
from heat.common import template_format
|
||||
@ -286,12 +287,13 @@ class WaitCondMetadataUpdateTest(common.HeatTestCase):
|
||||
|
||||
update_metadata('456', 'blarg', 'wibble')
|
||||
|
||||
self.assertEqual('{"123": "foo", "456": "blarg"}',
|
||||
watch.FnGetAtt('Data'))
|
||||
self.assertEqual({'123': 'foo', '456': 'blarg'},
|
||||
jsonutils.loads(watch.FnGetAtt('Data')))
|
||||
self.assertEqual('{"123": "foo"}',
|
||||
inst.metadata_get()['test'])
|
||||
self.assertEqual('{"123": "foo", "456": "blarg"}',
|
||||
inst.metadata_get(refresh=True)['test'])
|
||||
self.assertEqual(
|
||||
{'123': 'foo', '456': 'blarg'},
|
||||
jsonutils.loads(inst.metadata_get(refresh=True)['test']))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
|
@ -75,7 +75,10 @@ class ParameterTestCommon(common.HeatTestCase):
|
||||
|
||||
def test_param_to_str(self):
|
||||
p = new_parameter('p', {'Type': self.p_type}, self.value)
|
||||
self.assertEqual(self.expected, str(p))
|
||||
if self.p_type == 'Json':
|
||||
self.assertEqual(json.loads(self.expected), json.loads(str(p)))
|
||||
else:
|
||||
self.assertEqual(self.expected, str(p))
|
||||
|
||||
def test_default_no_override(self):
|
||||
p = new_parameter('defaulted', {'Type': self.p_type,
|
||||
@ -137,7 +140,10 @@ class ParameterTestCommon(common.HeatTestCase):
|
||||
'NoEcho': 'false'},
|
||||
self.value)
|
||||
self.assertFalse(p.hidden())
|
||||
self.assertEqual(self.expected, str(p))
|
||||
if self.p_type == 'Json':
|
||||
self.assertEqual(json.loads(self.expected), json.loads(str(p)))
|
||||
else:
|
||||
self.assertEqual(self.expected, str(p))
|
||||
|
||||
def test_default_empty(self):
|
||||
p = new_parameter('defaulted', {'Type': self.p_type,
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import json
|
||||
import os
|
||||
import uuid
|
||||
@ -140,8 +141,13 @@ class ProviderTemplateTest(common.HeatTestCase):
|
||||
prop_vals = {
|
||||
"Foo": "Bar",
|
||||
"AList": ["one", "two", "three"],
|
||||
"MemList": [{"key": "name", "value": "three"},
|
||||
{"key": "name", "value": "four"}],
|
||||
"MemList": [collections.OrderedDict([
|
||||
('key', 'name'),
|
||||
('value', 'three'),
|
||||
]), collections.OrderedDict([
|
||||
('key', 'name'),
|
||||
('value', 'four'),
|
||||
])],
|
||||
"ListEmpty": [],
|
||||
"ANum": 5,
|
||||
"AMap": map_prop_val,
|
||||
@ -165,7 +171,8 @@ class ProviderTemplateTest(common.HeatTestCase):
|
||||
'.member.0.value=three,'
|
||||
'.member.1.key=name,'
|
||||
'.member.1.value=four')
|
||||
self.assertEqual(mem_exp, converted_params.get("MemList"))
|
||||
self.assertEqual(sorted(mem_exp.split(',')),
|
||||
sorted(converted_params.get("MemList").split(',')))
|
||||
# verify Number conversion
|
||||
self.assertEqual(5, converted_params.get("ANum"))
|
||||
# verify Map conversion
|
||||
|
@ -17,6 +17,7 @@ import uuid
|
||||
from keystoneclient import exceptions as kc_exceptions
|
||||
import mox
|
||||
import six
|
||||
from six.moves.urllib import parse as urlparse
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
@ -176,19 +177,25 @@ class SignalTest(common.HeatTestCase):
|
||||
rsrc.created_time = created_time
|
||||
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
expected_url = "".join([
|
||||
# url parameters come in unexpected order, so the conversion has to be
|
||||
# done for comparison
|
||||
expected_url_path = "".join([
|
||||
'http://server.test:8000/v1/signal/',
|
||||
'arn%3Aopenstack%3Aheat%3A%3Atest_tenant%3Astacks%2F',
|
||||
'test_stack%2FSTACKABCD1234%2Fresources%2F',
|
||||
'signal_handler?',
|
||||
'Timestamp=2012-11-29T13%3A49%3A37Z&',
|
||||
'SignatureMethod=HmacSHA256&',
|
||||
'AWSAccessKeyId=4567&',
|
||||
'SignatureVersion=2&',
|
||||
'Signature=',
|
||||
'VW4NyvRO4WhQdsQ4rxl5JMUr0AlefHN6OLsRz9oZyls%3D'])
|
||||
'signal_handler'])
|
||||
expected_url_params = {
|
||||
'Timestamp': ['2012-11-29T13:49:37Z'],
|
||||
'SignatureMethod': ['HmacSHA256'],
|
||||
'AWSAccessKeyId': ['4567'],
|
||||
'SignatureVersion': ['2'],
|
||||
'Signature': ['VW4NyvRO4WhQdsQ4rxl5JMUr0AlefHN6OLsRz9oZyls=']}
|
||||
|
||||
self.assertEqual(expected_url, rsrc.FnGetAtt('AlarmUrl'))
|
||||
url = rsrc.FnGetAtt('AlarmUrl')
|
||||
url_path, url_params = url.split('?', 1)
|
||||
url_params = urlparse.parse_qs(url_params)
|
||||
self.assertEqual(expected_url_path, url_path)
|
||||
self.assertEqual(expected_url_params, url_params)
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_FnGetAtt_Alarm_Url_is_cached(self):
|
||||
|
@ -17,6 +17,7 @@ import uuid
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_messaging import exceptions as msg_exceptions
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
import testtools
|
||||
|
||||
@ -156,11 +157,24 @@ class StackResourceBaseTest(common.HeatTestCase):
|
||||
|
||||
|
||||
class StackResourceTest(StackResourceBaseTest):
|
||||
|
||||
def setUp(self):
|
||||
super(StackResourceTest, self).setUp()
|
||||
self.templ = template_format.parse(param_template)
|
||||
self.simple_template = template_format.parse(simple_template)
|
||||
|
||||
# to get same json string from a dict for comparison,
|
||||
# make sort_keys True
|
||||
orig_dumps = jsonutils.dumps
|
||||
|
||||
def sorted_dumps(*args, **kwargs):
|
||||
kwargs.setdefault('sort_keys', True)
|
||||
return orig_dumps(*args, **kwargs)
|
||||
patched_dumps = mock.patch(
|
||||
'oslo_serialization.jsonutils.dumps', sorted_dumps)
|
||||
patched_dumps.start()
|
||||
self.addCleanup(lambda: patched_dumps.stop())
|
||||
|
||||
def test_child_template_defaults_to_not_implemented(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.parent_resource.child_template)
|
||||
@ -188,8 +202,8 @@ class StackResourceTest(StackResourceBaseTest):
|
||||
sig1, sig2 = self.parent_resource.implementation_signature()
|
||||
self.assertEqual('7b0eaabb5b82b9e90804d42e0bb739035588cb797'
|
||||
'82427770646686ca2235028', sig1)
|
||||
self.assertEqual('5a58b34cc3dd7f4e11fa35b63daad7b6b3aaa1744'
|
||||
'19eb1c42b75d102bdda5fc9', sig2)
|
||||
self.assertEqual('8fa647d036b8f36909386e1e1004539dfae7a8e88'
|
||||
'c24aac0d85399e881421301', sig2)
|
||||
self.parent_stack.t.files["foo"] = "bar"
|
||||
sig1a, sig2a = self.parent_resource.implementation_signature()
|
||||
self.assertEqual(sig1, sig1a)
|
||||
|
@ -15,8 +15,10 @@ import random
|
||||
import string
|
||||
import uuid
|
||||
|
||||
import mox
|
||||
from oslo_config import cfg
|
||||
from oslo_db import options
|
||||
from oslo_serialization import jsonutils
|
||||
import sqlalchemy
|
||||
|
||||
from heat.common import context
|
||||
@ -143,3 +145,32 @@ class PhysName(object):
|
||||
|
||||
def __repr__(self):
|
||||
return self._physname
|
||||
|
||||
|
||||
def recursive_sort(obj):
|
||||
"""Recursively sort list in iterables for comparison."""
|
||||
if isinstance(obj, dict):
|
||||
for v in obj.values():
|
||||
recursive_sort(v)
|
||||
elif isinstance(obj, list):
|
||||
obj.sort()
|
||||
for i in obj:
|
||||
recursive_sort(i)
|
||||
return obj
|
||||
|
||||
|
||||
class JsonEquals(mox.Comparator):
|
||||
"""Comparison class used to check if two json strings equal.
|
||||
|
||||
If a dict is dumped to json, the order is undecided, so load the string
|
||||
back to an object for comparison
|
||||
"""
|
||||
|
||||
def __init__(self, other_json):
|
||||
self.other_json = other_json
|
||||
|
||||
def equals(self, rhs):
|
||||
return jsonutils.loads(self.other_json) == jsonutils.loads(rhs)
|
||||
|
||||
def __repr__(self):
|
||||
return "<equals to json '%s'>" % self.other_json
|
||||
|
3
tox.ini
3
tox.ini
@ -4,10 +4,7 @@ minversion = 1.6
|
||||
skipsdist = True
|
||||
|
||||
[testenv]
|
||||
# Note the hash seed is set to 0 until heat can be tested with a
|
||||
# random hash seed successfully.
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
PYTHONHASHSEED=0
|
||||
usedevelop = True
|
||||
install_command = pip install {opts} {packages}
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
|
Loading…
x
Reference in New Issue
Block a user