aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Buil <mbuil@suse.com>2018-11-05 20:46:46 +0100
committerManuel Buil <mbuil@suse.com>2018-11-06 10:29:19 +0100
commit52e86db6e0a3343852c9aabba49dffe3d699d1a0 (patch)
tree0045cf59a98c3671ed4d250cf2819d23ae6777e7
parent6c11ccaa5e9f036a1b56926d80aaccb3dc5e3d78 (diff)
Avoid race conditions
Sometimes the port pair group gets created before port pair was committed in openstack. Before creating the port pair group, we check that the port pair is already listed by openstack Change-Id: Icfd23521859fc5d4e6bb6745be80f79bf9e31a0c Signed-off-by: Manuel Buil <mbuil@suse.com>
-rw-r--r--sfc/lib/openstack_utils.py17
-rw-r--r--sfc/unit_tests/unit/lib/test_openstack_utils.py34
2 files changed, 51 insertions, 0 deletions
diff --git a/sfc/lib/openstack_utils.py b/sfc/lib/openstack_utils.py
index 7915e77d..38ca61bb 100644
--- a/sfc/lib/openstack_utils.py
+++ b/sfc/lib/openstack_utils.py
@@ -316,6 +316,23 @@ class OpenStackSFC:
{'vnf': vm_instance.name})
return None
+ # Avoid race conditions by checking the port pair is already committed
+ iterations = 5
+ found_it = False
+ for i in range(iterations):
+ pp_list = self.neutron.list_sfc_port_pairs()['port_pairs']
+ for pp in pp_list:
+ if pp['id'] == port_pair_info['port_pair']['id']:
+ found_it = True
+ break
+ if found_it:
+ break
+ else:
+ time.sleep(3)
+
+ if not found_it:
+ raise Exception("Port pair was not committed in openstack")
+
logger.info("Creating the port pair groups for %s" % vm_instance.name)
port_pair_group = {}
port_pair_group['name'] = vm_instance.name + '-port-pair-group'
diff --git a/sfc/unit_tests/unit/lib/test_openstack_utils.py b/sfc/unit_tests/unit/lib/test_openstack_utils.py
index eca9316d..3397c55a 100644
--- a/sfc/unit_tests/unit/lib/test_openstack_utils.py
+++ b/sfc/unit_tests/unit/lib/test_openstack_utils.py
@@ -715,6 +715,36 @@ class SfcOpenStackUtilsTesting(unittest.TestCase):
@patch('snaps.domain.network.Port', autospec=True)
@patch('snaps.domain.vm_inst.VmInst', autospec=True)
@patch('sfc.lib.openstack_utils.logger', autospec=True)
+ def test_create_port_groups_exception_nopp(self, mock_log, mock_osvm,
+ mock_port):
+ """
+ Checks the create_port_groups when openstack does not commit the pp
+ """
+
+ log_calls_info = [call('Creating the port pairs for vm')]
+ mock_port_ins = mock_port.return_value
+ mock_port_ins.id = '123abc'
+ mock_vm_ins = mock_osvm.return_value
+ mock_vm_ins.name = 'vm'
+ exception_message = "Port pair was not committed in openstack"
+ expected_port_pair = {'name': 'vm-connection-points',
+ 'description': 'port pair for vm',
+ 'ingress': '123abc',
+ 'egress': '123abc'}
+ self.neutron.create_sfc_port_pair.return_value = \
+ {'port_pair': {'id': 'pp_id'}}
+ self.neutron.list_sfc_port_pairs.return_value = \
+ {'port_pairs': [{'id': 'xxxx'}]}
+ with self.assertRaises(Exception) as cm:
+ self.os_sfc.create_port_groups([mock_port_ins], mock_vm_ins)
+ self.assertEqual(exception_message, cm.exception.message)
+ self.neutron.create_sfc_port_pair.assert_has_calls(
+ [call({'port_pair': expected_port_pair})])
+ mock_log.info.assert_has_calls(log_calls_info)
+
+ @patch('snaps.domain.network.Port', autospec=True)
+ @patch('snaps.domain.vm_inst.VmInst', autospec=True)
+ @patch('sfc.lib.openstack_utils.logger', autospec=True)
def test_create_port_groups_returns_none_from_ppg(self, mock_log,
mock_vm,
mock_port):
@@ -732,6 +762,8 @@ class SfcOpenStackUtilsTesting(unittest.TestCase):
mock_port_ins.id = '123abc'
self.neutron.create_sfc_port_pair.return_value = \
{'port_pair': {'id': 'pp_id'}}
+ self.neutron.list_sfc_port_pairs.return_value = \
+ {'port_pairs': [{'id': 'pp_id'}]}
self.neutron.create_sfc_port_pair_group.return_value = None
result = self.os_sfc.create_port_groups([mock_port_ins], mock_vm_ins)
self.assertIsNone(result)
@@ -759,6 +791,8 @@ class SfcOpenStackUtilsTesting(unittest.TestCase):
'egress': '123abc'}
self.neutron.create_sfc_port_pair.return_value = \
{'port_pair': {'id': 'pp_id'}}
+ self.neutron.list_sfc_port_pairs.return_value = \
+ {'port_pairs': [{'id': 'pp_id'}]}
self.neutron.create_sfc_port_pair_group.return_value = \
{'port_pair_group': {'id': 'pp_id'}}
expected_port_pair_gr = {'name': 'vm-port-pair-group',