aboutsummaryrefslogtreecommitdiffstats
path: root/docker/tempest/Fixes-race-condition-in-test_add_remove_fixed_ip.patch
blob: a9f3c7e6d22d720789274709fdec139f137ef168 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
From 61a3c8efa4a5e41dc6b5fd2d7a28a25555ebb54b Mon Sep 17 00:00:00 2001
From: David Sedlák <dsedlak@redhat.com>
Date: Wed, 30 Oct 2019 15:38:21 +0100
Subject: [PATCH] Fixes race condition in test_add_remove_fixed_ip

Currently race condition can occure in
tempest.api.compute.servers.test_attach_interfaces.
AttachInterfacesUnderV243Test.test_add_remove_fixed_ip
when floating IP added during resource preparation doesn't appear in
the list of original IPs that is created at the beggining of the test,
which then confuses the test
and floating ip is later recognized as fixed IP added in the test.
more details including log:
https://bugzilla.redhat.com/show_bug.cgi?id=1752416

This change ensures possible floating IP added during server
creation is always present in the set of original IPs and also
during every comparasion of IPs.

Closes-Bug: #1866179

Change-Id: Ic3a3e0708714b6d6c9c226e641e1c520e5ebde9d
Signed-off-by: David Sedlák <dsedlak@redhat.com>
---

diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index df8da07..c1af6c7 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -86,12 +86,16 @@
         # apparently not enough? Add cleanup here.
         self.addCleanup(self.delete_server, server['id'])
         self._wait_for_validation(server, validation_resources)
+        try:
+            fip = set([validation_resources['floating_ip']['ip']])
+        except KeyError:
+            fip = ()
         ifs = (self.interfaces_client.list_interfaces(server['id'])
                ['interfaceAttachments'])
         body = waiters.wait_for_interface_status(
             self.interfaces_client, server['id'], ifs[0]['port_id'], 'ACTIVE')
         ifs[0]['port_state'] = body['port_state']
-        return server, ifs
+        return server, ifs, fip
 
 
 class AttachInterfacesTestJSON(AttachInterfacesTestBase):
@@ -226,7 +230,7 @@
     @decorators.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
     @utils.services('network')
     def test_create_list_show_delete_interfaces_by_network_port(self):
-        server, ifs = self._create_server_get_interfaces()
+        server, ifs, _ = self._create_server_get_interfaces()
         interface_count = len(ifs)
         self.assertGreater(interface_count, 0)
 
@@ -268,7 +272,7 @@
             raise self.skipException("Only owner network supports "
                                      "creating interface by fixed ip.")
 
-        server, ifs = self._create_server_get_interfaces()
+        server, ifs, _ = self._create_server_get_interfaces()
         interface_count = len(ifs)
         self.assertGreater(interface_count, 0)
 
@@ -354,9 +358,8 @@
                 not CONF.network.shared_physical_network):
             raise self.skipException("Only owner network supports "
                                      "creating interface by fixed ip.")
-
         # Add and Remove the fixed IP to server.
-        server, ifs = self._create_server_get_interfaces()
+        server, ifs, fip = self._create_server_get_interfaces()
         original_interface_count = len(ifs)  # This is the number of ports.
         self.assertGreater(original_interface_count, 0)
         # Get the starting list of IPs on the server.
@@ -369,6 +372,9 @@
         self.assertEqual(1, len(addresses), addresses)  # number of networks
         # Keep track of the original addresses so we can know which IP is new.
         original_ips = [addr['addr'] for addr in list(addresses.values())[0]]
+        # Make sure the floating IP possibly assigned during
+        # server creation is always present in the set of original ips.
+        original_ips = set(original_ips).union(fip)
         original_ip_count = len(original_ips)
         self.assertGreater(original_ip_count, 0, addresses)  # at least 1
         network_id = ifs[0]['net_id']
@@ -376,40 +382,22 @@
         # fixed IP on the same network (and same port since we only have one
         # port).
         self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
-        # Wait for the ips count to increase by one.
 
-        def _get_server_floating_ips():
-            _floating_ips = []
-            _server = self.os_primary.servers_client.show_server(
-                server['id'])['server']
-            for _ip_set in _server['addresses']:
-                for _ip in _server['addresses'][_ip_set]:
-                    if _ip['OS-EXT-IPS:type'] == 'floating':
-                        _floating_ips.append(_ip['addr'])
-            return _floating_ips
-
-        def _wait_for_ip_increase():
+        def _wait_for_ip_change(expected_count):
             _addresses = self.os_primary.servers_client.list_addresses(
                 server['id'])['addresses']
-            _ips = [addr['addr'] for addr in list(_addresses.values())[0]]
-            LOG.debug("Wait for IP increase. All IPs still associated to "
+            _ips = set([addr['addr'] for addr in list(_addresses.values())[0]])
+            # Make sure possible floating ip is always present in the set.
+            _ips = _ips.union(fip)
+            LOG.debug("Wait for change of IPs. All IPs still associated to "
                       "the server %(id)s: %(ips)s",
                       {'id': server['id'], 'ips': _ips})
-            if len(_ips) == original_ip_count + 1:
-                return True
-            elif len(_ips) == original_ip_count:
-                return False
-            # If not, lets remove any floating IP from the list and check again
-            _fips = _get_server_floating_ips()
-            _ips = [_ip for _ip in _ips if _ip not in _fips]
-            LOG.debug("Wait for IP increase. Fixed IPs still associated to "
-                      "the server %(id)s: %(ips)s",
-                      {'id': server['id'], 'ips': _ips})
-            return len(_ips) == original_ip_count + 1
+            return len(_ips) == expected_count
 
+        # Wait for the ips count to increase by one.
         if not test_utils.call_until_true(
-                _wait_for_ip_increase, CONF.compute.build_timeout,
-                CONF.compute.build_interval):
+                _wait_for_ip_change, CONF.compute.build_timeout,
+                CONF.compute.build_interval, original_ip_count + 1):
             raise lib_exc.TimeoutException(
                 'Timed out while waiting for IP count to increase.')
 
@@ -428,26 +416,8 @@
                 break
         self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
         # Wait for the interface count to decrease by one.
-
-        def _wait_for_ip_decrease():
-            _addresses = self.os_primary.servers_client.list_addresses(
-                server['id'])['addresses']
-            _ips = [addr['addr'] for addr in list(_addresses.values())[0]]
-            LOG.debug("Wait for IP decrease. All IPs still associated to "
-                      "the server %(id)s: %(ips)s",
-                      {'id': server['id'], 'ips': _ips})
-            if len(_ips) == original_ip_count:
-                return True
-            # If not, lets remove any floating IP from the list and check again
-            _fips = _get_server_floating_ips()
-            _ips = [_ip for _ip in _ips if _ip not in _fips]
-            LOG.debug("Wait for IP decrease. Fixed IPs still associated to "
-                      "the server %(id)s: %(ips)s",
-                      {'id': server['id'], 'ips': _ips})
-            return len(_ips) == original_ip_count
-
         if not test_utils.call_until_true(
-                _wait_for_ip_decrease, CONF.compute.build_timeout,
-                CONF.compute.build_interval):
+                _wait_for_ip_change, CONF.compute.build_timeout,
+                CONF.compute.build_interval, original_ip_count):
             raise lib_exc.TimeoutException(
                 'Timed out while waiting for IP count to decrease.')