Do not assume jsonutils.dumps ordering

This fixes the unit tests[1] that breaks with a randomized
PYTHONHASHSEED (see the bug report).

The test assumed that the oslo_serializarion.jsonutils.dumps performs
dictionary json dump in particular order. Found with PYTHONHASHSEED=1.

The fix refactors the test case by disabling json dumps and comparing
dictionnaries instead of their json dumps.

[1] neutron_fwaas.tests.unit.services.firewall.drivers.mcafee.\
    test_ngfw_fwaas:
  NGFWFwaasTestCase.test_create_firewall
  NGFWFwaasTestCase.test_update_firewall

Partial-bug: #1348818

Note: There are several other unrelated unit tests that also break with
a randomized PYTHONHASHSEED, but they are not addressed here. They will
be addressed in separate patches.

Change-Id: I67fe1ab69bcfd99c2e778963b97c0d6b4b039802
changes/30/187230/2
Cedric Brandily 7 years ago
parent b1373f8fb8
commit 0660c0518e
  1. 86
      neutron_fwaas/tests/unit/services/firewall/drivers/mcafee/test_ngfw_fwaas.py

@ -137,54 +137,64 @@ class NGFWFwaasTestCase(base.BaseTestCase):
ref_v4rule = self.tmp_ref + "/fw_ipv4_access_rule"
ref_upload = self.tmp_ref + "/upload"
with mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'login'), \
# NOTE(cbrandily): we replace jsonutils.dumps by identity in order
# to compare dictionaries instead of their json dumps and avoid to
# assume how jsonutils.dumps order dictionaries.
with mock.patch('oslo_serialization.jsonutils.dumps',
side_effect=lambda x: x), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'login'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'get'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'logout'), \
mock.patch.object(mcafee.smc_api.SMCAPIConnection, 'post',
return_value=self.post_return) as post:
expected = [mock.call(
'elements/fw_policy',
'{"name": "%s", "template": null}' % self.policy_name),
expected = [
mock.call(
'elements/fw_policy',
{"name": self.policy_name, "template": None}),
mock.call(
'elements/udp_service',
{"min_dst_port": 23, "max_dst_port": 23,
"name": "service-a2", "max_src_port": 23,
"min_src_port": 23}),
mock.call(
'elements/udp_service',
'{"min_dst_port": 23, "max_dst_port": 23, '
'"name": "service-a2", "max_src_port": 23, '
'"min_src_port": 23}'),
ref_v4rule,
{"action": {"action": "discard",
"connection_tracking_options": {}},
"services": {"service": [self.tmp_ref]},
"sources": {"src": ["None"]},
"name": "a2",
"destinations": {"dst": ["None"]}},
raw=True),
mock.call(
ref_v4rule,
'{"action": {"action": "discard", '
'"connection_tracking_options": {}}, '
'"services": {"service": ["%s"]}, "sources": '
'{"src": ["None"]}, "name": "a2", "destinations": '
'{"dst": ["None"]}}' % self.tmp_ref, raw=True),
'elements/network',
{"ipv4_network": "192.168.100.0/24",
"name": "network-192.168.100.0/24"}),
mock.call(
'elements/network',
'{"ipv4_network": "192.168.100.0/24", '
'"name": "network-192.168.100.0/24"}'),
'elements/icmp_service',
{"icmp_code": 0, "icmp_type": 0, "name": "service22"}),
mock.call(
'elements/icmp_service',
'{"icmp_code": 0, "icmp_type": 0, "name": "service22"}'),
mock.call(ref_v4rule,
'{"action": {"action": "discard", '
'"connection_tracking_options": {}}, '
'"services": {"service": ["%s"]}, '
'"sources": {"src": ["%s"]}, "name": "a3", '
'"destinations": {"dst": ["None"]}}' % (
self.tmp_ref, self.tmp_ref), raw=True),
ref_v4rule,
{"action": {"action": "discard",
"connection_tracking_options": {}},
"services": {"service": [self.tmp_ref]},
"sources": {"src": [self.tmp_ref]},
"name": "a3",
"destinations": {"dst": ["None"]}},
raw=True),
mock.call(
'elements/tcp_service',
'{"min_dst_port": 0, "max_dst_port": 65535, '
'"name": "service-a4", "max_src_port": 65535, '
'"min_src_port": 0}'),
'elements/tcp_service',
{"min_dst_port": 0, "max_dst_port": 65535,
"name": "service-a4", "max_src_port": 65535,
"min_src_port": 0}),
mock.call(
ref_v4rule,
'{"action": {"action": "allow", '
'"connection_tracking_options": {}}, '
'"services": {"service": ["%s"]}, '
'"sources": {"src": ["None"]}, "name": "a4", '
'"destinations": {"dst": ["None"]}}' %
self.tmp_ref, raw=True),
ref_v4rule,
{"action": {"action": "allow",
"connection_tracking_options": {}},
"services": {"service": [self.tmp_ref]},
"sources": {"src": ["None"]},
"name": "a4",
"destinations": {"dst": ["None"]}},
raw=True),
mock.call(ref_upload, '', raw=True)]
self.firewall.update_firewall('legacy', self.apply_list, firewall)

Loading…
Cancel
Save