octavia 13.0.0__py3-none-any.whl → 13.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- octavia/amphorae/backends/agent/api_server/keepalivedlvs.py +9 -0
- octavia/amphorae/backends/agent/api_server/osutils.py +1 -2
- octavia/amphorae/backends/agent/api_server/util.py +35 -2
- octavia/amphorae/backends/utils/interface.py +4 -5
- octavia/amphorae/drivers/driver_base.py +16 -0
- octavia/amphorae/drivers/haproxy/rest_api_driver.py +13 -8
- octavia/amphorae/drivers/keepalived/jinja/jinja_cfg.py +0 -1
- octavia/amphorae/drivers/keepalived/jinja/templates/keepalived_base.template +0 -1
- octavia/amphorae/drivers/keepalived/vrrp_rest_driver.py +2 -1
- octavia/amphorae/drivers/noop_driver/driver.py +3 -0
- octavia/api/common/pagination.py +1 -1
- octavia/api/v2/controllers/health_monitor.py +3 -2
- octavia/api/v2/controllers/l7policy.py +0 -1
- octavia/api/v2/controllers/l7rule.py +0 -1
- octavia/api/v2/controllers/listener.py +0 -1
- octavia/api/v2/controllers/load_balancer.py +13 -7
- octavia/api/v2/controllers/member.py +18 -5
- octavia/api/v2/controllers/pool.py +6 -7
- octavia/api/v2/types/pool.py +1 -1
- octavia/certificates/common/pkcs12.py +9 -9
- octavia/certificates/manager/barbican.py +24 -16
- octavia/certificates/manager/castellan_mgr.py +12 -7
- octavia/certificates/manager/noop.py +106 -0
- octavia/common/clients.py +22 -4
- octavia/common/config.py +21 -5
- octavia/common/constants.py +4 -0
- octavia/common/exceptions.py +6 -0
- octavia/common/jinja/haproxy/combined_listeners/templates/macros.j2 +7 -5
- octavia/common/keystone.py +7 -7
- octavia/common/tls_utils/cert_parser.py +23 -9
- octavia/controller/worker/task_utils.py +28 -6
- octavia/controller/worker/v2/controller_worker.py +2 -2
- octavia/controller/worker/v2/flows/amphora_flows.py +41 -10
- octavia/controller/worker/v2/flows/flow_utils.py +6 -4
- octavia/controller/worker/v2/flows/load_balancer_flows.py +17 -3
- octavia/controller/worker/v2/tasks/amphora_driver_tasks.py +114 -23
- octavia/controller/worker/v2/tasks/database_tasks.py +36 -47
- octavia/controller/worker/v2/tasks/lifecycle_tasks.py +96 -40
- octavia/controller/worker/v2/tasks/network_tasks.py +12 -13
- octavia/db/base_models.py +16 -4
- octavia/db/repositories.py +34 -33
- octavia/network/drivers/neutron/allowed_address_pairs.py +10 -8
- octavia/network/drivers/noop_driver/driver.py +1 -2
- octavia/tests/common/sample_certs.py +115 -0
- octavia/tests/functional/api/v2/base.py +1 -1
- octavia/tests/functional/api/v2/test_health_monitor.py +18 -0
- octavia/tests/functional/api/v2/test_listener.py +45 -0
- octavia/tests/functional/api/v2/test_member.py +32 -0
- octavia/tests/functional/db/base.py +9 -0
- octavia/tests/functional/db/test_repositories.py +45 -98
- octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +89 -1
- octavia/tests/unit/amphorae/backends/utils/test_interface.py +3 -1
- octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver.py +3 -3
- octavia/tests/unit/amphorae/drivers/keepalived/jinja/test_jinja_cfg.py +0 -4
- octavia/tests/unit/amphorae/drivers/keepalived/test_vrrp_rest_driver.py +17 -0
- octavia/tests/unit/api/common/test_pagination.py +78 -1
- octavia/tests/unit/api/v2/types/test_pool.py +71 -0
- octavia/tests/unit/certificates/manager/test_barbican.py +3 -3
- octavia/tests/unit/certificates/manager/test_noop.py +53 -0
- octavia/tests/unit/cmd/test_prometheus_proxy.py +8 -1
- octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py +16 -17
- octavia/tests/unit/common/test_config.py +35 -0
- octavia/tests/unit/common/test_keystone.py +32 -0
- octavia/tests/unit/controller/worker/test_task_utils.py +58 -2
- octavia/tests/unit/controller/worker/v2/flows/test_amphora_flows.py +28 -5
- octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +10 -5
- octavia/tests/unit/controller/worker/v2/tasks/test_amphora_driver_tasks.py +234 -17
- octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks.py +28 -6
- octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks_quota.py +19 -19
- octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +57 -2
- octavia/tests/unit/controller/worker/v2/test_controller_worker.py +56 -1
- octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +24 -1
- {octavia-13.0.0.dist-info → octavia-13.0.1.dist-info}/AUTHORS +8 -0
- octavia-13.0.1.dist-info/METADATA +155 -0
- {octavia-13.0.0.dist-info → octavia-13.0.1.dist-info}/RECORD +90 -88
- {octavia-13.0.0.dist-info → octavia-13.0.1.dist-info}/WHEEL +1 -1
- {octavia-13.0.0.dist-info → octavia-13.0.1.dist-info}/entry_points.txt +1 -1
- octavia-13.0.1.dist-info/pbr.json +1 -0
- octavia-13.0.0.dist-info/METADATA +0 -158
- octavia-13.0.0.dist-info/pbr.json +0 -1
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/LICENSE +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/README.rst +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/README.rst +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/tox.ini +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/data/share/octavia/diskimage-create/version.txt +0 -0
- {octavia-13.0.0.data → octavia-13.0.1.data}/scripts/octavia-wsgi +0 -0
- {octavia-13.0.0.dist-info → octavia-13.0.1.dist-info}/LICENSE +0 -0
- {octavia-13.0.0.dist-info → octavia-13.0.1.dist-info}/top_level.txt +0 -0
@@ -14,6 +14,7 @@
|
|
14
14
|
from unittest import mock
|
15
15
|
|
16
16
|
from oslo_utils import uuidutils
|
17
|
+
import tenacity
|
17
18
|
|
18
19
|
from octavia.common import constants
|
19
20
|
from octavia.controller.worker import task_utils as task_utilities
|
@@ -183,7 +184,13 @@ class TestTaskUtils(base.TestCase):
|
|
183
184
|
|
184
185
|
@mock.patch('octavia.db.api.session')
|
185
186
|
@mock.patch('octavia.db.repositories.LoadBalancerRepository.update')
|
187
|
+
@mock.patch('tenacity.nap.time')
|
188
|
+
# mock LOG so we don't fill the console with log messages from
|
189
|
+
# tenacity.retry
|
190
|
+
@mock.patch('octavia.controller.worker.task_utils.LOG')
|
186
191
|
def test_mark_loadbalancer_prov_status_active(self,
|
192
|
+
mock_LOG,
|
193
|
+
mock_time,
|
187
194
|
mock_lb_repo_update,
|
188
195
|
mock_get_session):
|
189
196
|
|
@@ -202,14 +209,42 @@ class TestTaskUtils(base.TestCase):
|
|
202
209
|
mock_lb_repo_update.reset_mock()
|
203
210
|
mock_get_session.side_effect = Exception('fail')
|
204
211
|
|
205
|
-
self.
|
212
|
+
self.assertRaises(
|
213
|
+
tenacity.RetryError,
|
214
|
+
self.task_utils.mark_loadbalancer_prov_status_active,
|
206
215
|
self.LOADBALANCER_ID)
|
207
216
|
|
208
217
|
self.assertFalse(mock_lb_repo_update.called)
|
209
218
|
|
219
|
+
# Exceptions then happy path
|
220
|
+
mock_get_session.reset_mock(side_effect=True)
|
221
|
+
mock_lb_repo_update.reset_mock()
|
222
|
+
|
223
|
+
mock_session = mock_get_session()
|
224
|
+
mock_session_context = mock_session.begin().__enter__()
|
225
|
+
mock_get_session.side_effect = [
|
226
|
+
Exception('fail'),
|
227
|
+
Exception('fail'),
|
228
|
+
Exception('fail'),
|
229
|
+
mock_session]
|
230
|
+
|
231
|
+
self.task_utils.mark_loadbalancer_prov_status_active(
|
232
|
+
self.LOADBALANCER_ID)
|
233
|
+
|
234
|
+
mock_lb_repo_update.assert_called_once_with(
|
235
|
+
mock_session_context,
|
236
|
+
id=self.LOADBALANCER_ID,
|
237
|
+
provisioning_status=constants.ACTIVE)
|
238
|
+
|
210
239
|
@mock.patch('octavia.db.api.session')
|
211
240
|
@mock.patch('octavia.db.repositories.LoadBalancerRepository.update')
|
241
|
+
@mock.patch('tenacity.nap.time')
|
242
|
+
# mock LOG so we don't fill the console with log messages from
|
243
|
+
# tenacity.retry
|
244
|
+
@mock.patch('octavia.controller.worker.task_utils.LOG')
|
212
245
|
def test_mark_loadbalancer_prov_status_error(self,
|
246
|
+
mock_LOG,
|
247
|
+
mock_time,
|
213
248
|
mock_lb_repo_update,
|
214
249
|
mock_get_session):
|
215
250
|
|
@@ -228,10 +263,31 @@ class TestTaskUtils(base.TestCase):
|
|
228
263
|
mock_lb_repo_update.reset_mock()
|
229
264
|
mock_get_session.side_effect = Exception('fail')
|
230
265
|
|
266
|
+
self.assertRaises(tenacity.RetryError,
|
267
|
+
self.task_utils.mark_loadbalancer_prov_status_error,
|
268
|
+
self.LOADBALANCER_ID)
|
269
|
+
|
270
|
+
self.assertFalse(mock_lb_repo_update.called)
|
271
|
+
|
272
|
+
# Exceptions then happy path
|
273
|
+
mock_get_session.reset_mock(side_effect=True)
|
274
|
+
mock_lb_repo_update.reset_mock()
|
275
|
+
|
276
|
+
mock_session = mock_get_session()
|
277
|
+
mock_session_context = mock_session.begin().__enter__()
|
278
|
+
mock_get_session.side_effect = [
|
279
|
+
Exception('fail'),
|
280
|
+
Exception('fail'),
|
281
|
+
Exception('fail'),
|
282
|
+
mock_session]
|
283
|
+
|
231
284
|
self.task_utils.mark_loadbalancer_prov_status_error(
|
232
285
|
self.LOADBALANCER_ID)
|
233
286
|
|
234
|
-
|
287
|
+
mock_lb_repo_update.assert_called_once_with(
|
288
|
+
mock_session_context,
|
289
|
+
id=self.LOADBALANCER_ID,
|
290
|
+
provisioning_status=constants.ERROR)
|
235
291
|
|
236
292
|
@mock.patch('octavia.db.api.session')
|
237
293
|
@mock.patch('octavia.db.repositories.MemberRepository.update')
|
@@ -286,6 +286,7 @@ class TestAmphoraFlows(base.TestCase):
|
|
286
286
|
self.assertIn(constants.AMPHORA, amp_flow.provides)
|
287
287
|
self.assertIn(constants.AMPHORA_ID, amp_flow.provides)
|
288
288
|
self.assertIn(constants.AMPHORAE, amp_flow.provides)
|
289
|
+
self.assertIn(constants.AMPHORAE_STATUS, amp_flow.provides)
|
289
290
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, amp_flow.provides)
|
290
291
|
self.assertIn(constants.BASE_PORT, amp_flow.provides)
|
291
292
|
self.assertIn(constants.COMPUTE_ID, amp_flow.provides)
|
@@ -296,7 +297,7 @@ class TestAmphoraFlows(base.TestCase):
|
|
296
297
|
self.assertIn(constants.VIP_SG_ID, amp_flow.provides)
|
297
298
|
|
298
299
|
self.assertEqual(8, len(amp_flow.requires))
|
299
|
-
self.assertEqual(
|
300
|
+
self.assertEqual(14, len(amp_flow.provides))
|
300
301
|
|
301
302
|
def test_get_failover_flow_standalone(self, mock_get_net_driver):
|
302
303
|
failed_amphora = data_models.Amphora(
|
@@ -320,6 +321,7 @@ class TestAmphoraFlows(base.TestCase):
|
|
320
321
|
self.assertIn(constants.AMPHORA, amp_flow.provides)
|
321
322
|
self.assertIn(constants.AMPHORA_ID, amp_flow.provides)
|
322
323
|
self.assertIn(constants.AMPHORAE, amp_flow.provides)
|
324
|
+
self.assertIn(constants.AMPHORAE_STATUS, amp_flow.provides)
|
323
325
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, amp_flow.provides)
|
324
326
|
self.assertIn(constants.BASE_PORT, amp_flow.provides)
|
325
327
|
self.assertIn(constants.COMPUTE_ID, amp_flow.provides)
|
@@ -330,7 +332,7 @@ class TestAmphoraFlows(base.TestCase):
|
|
330
332
|
self.assertIn(constants.VIP_SG_ID, amp_flow.provides)
|
331
333
|
|
332
334
|
self.assertEqual(8, len(amp_flow.requires))
|
333
|
-
self.assertEqual(
|
335
|
+
self.assertEqual(13, len(amp_flow.provides))
|
334
336
|
|
335
337
|
def test_get_failover_flow_bogus_role(self, mock_get_net_driver):
|
336
338
|
failed_amphora = data_models.Amphora(id=uuidutils.generate_uuid(),
|
@@ -366,14 +368,33 @@ class TestAmphoraFlows(base.TestCase):
|
|
366
368
|
|
367
369
|
self.assertIsInstance(vrrp_subflow, flow.Flow)
|
368
370
|
|
371
|
+
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, vrrp_subflow.provides)
|
372
|
+
self.assertIn(constants.AMP_VRRP_INT, vrrp_subflow.provides)
|
373
|
+
self.assertIn(constants.AMPHORAE_STATUS, vrrp_subflow.provides)
|
374
|
+
|
375
|
+
self.assertIn(constants.LOADBALANCER_ID, vrrp_subflow.requires)
|
376
|
+
self.assertIn(constants.AMPHORAE, vrrp_subflow.requires)
|
377
|
+
self.assertIn(constants.AMPHORA_ID, vrrp_subflow.requires)
|
378
|
+
|
379
|
+
self.assertEqual(3, len(vrrp_subflow.provides))
|
380
|
+
self.assertEqual(3, len(vrrp_subflow.requires))
|
381
|
+
|
382
|
+
def test_get_vrrp_subflow_dont_get_status(self, mock_get_net_driver):
|
383
|
+
vrrp_subflow = self.AmpFlow.get_vrrp_subflow('123',
|
384
|
+
get_amphorae_status=False)
|
385
|
+
|
386
|
+
self.assertIsInstance(vrrp_subflow, flow.Flow)
|
387
|
+
|
369
388
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, vrrp_subflow.provides)
|
370
389
|
self.assertIn(constants.AMP_VRRP_INT, vrrp_subflow.provides)
|
371
390
|
|
372
391
|
self.assertIn(constants.LOADBALANCER_ID, vrrp_subflow.requires)
|
373
392
|
self.assertIn(constants.AMPHORAE, vrrp_subflow.requires)
|
393
|
+
self.assertIn(constants.AMPHORA_ID, vrrp_subflow.requires)
|
394
|
+
self.assertIn(constants.AMPHORAE_STATUS, vrrp_subflow.requires)
|
374
395
|
|
375
396
|
self.assertEqual(2, len(vrrp_subflow.provides))
|
376
|
-
self.assertEqual(
|
397
|
+
self.assertEqual(4, len(vrrp_subflow.requires))
|
377
398
|
|
378
399
|
def test_get_vrrp_subflow_dont_create_vrrp_group(
|
379
400
|
self, mock_get_net_driver):
|
@@ -384,12 +405,14 @@ class TestAmphoraFlows(base.TestCase):
|
|
384
405
|
|
385
406
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, vrrp_subflow.provides)
|
386
407
|
self.assertIn(constants.AMP_VRRP_INT, vrrp_subflow.provides)
|
408
|
+
self.assertIn(constants.AMPHORAE_STATUS, vrrp_subflow.provides)
|
387
409
|
|
388
410
|
self.assertIn(constants.LOADBALANCER_ID, vrrp_subflow.requires)
|
389
411
|
self.assertIn(constants.AMPHORAE, vrrp_subflow.requires)
|
412
|
+
self.assertIn(constants.AMPHORA_ID, vrrp_subflow.requires)
|
390
413
|
|
391
|
-
self.assertEqual(
|
392
|
-
self.assertEqual(
|
414
|
+
self.assertEqual(3, len(vrrp_subflow.provides))
|
415
|
+
self.assertEqual(3, len(vrrp_subflow.requires))
|
393
416
|
|
394
417
|
def test_update_amphora_config_flow(self, mock_get_net_driver):
|
395
418
|
|
@@ -199,14 +199,16 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
199
199
|
|
200
200
|
self.assertIn(constants.LOADBALANCER_ID, amp_flow.requires)
|
201
201
|
self.assertIn(constants.UPDATE_DICT, amp_flow.requires)
|
202
|
+
self.assertIn(constants.AMPHORA_ID, amp_flow.requires)
|
202
203
|
|
203
204
|
self.assertIn(constants.AMPHORAE, amp_flow.provides)
|
205
|
+
self.assertIn(constants.AMPHORAE_STATUS, amp_flow.provides)
|
204
206
|
self.assertIn(constants.AMP_VRRP_INT, amp_flow.provides)
|
205
207
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, amp_flow.provides)
|
206
208
|
self.assertIn(constants.LOADBALANCER, amp_flow.provides)
|
207
209
|
|
208
|
-
self.assertEqual(
|
209
|
-
self.assertEqual(
|
210
|
+
self.assertEqual(3, len(amp_flow.requires), amp_flow.requires)
|
211
|
+
self.assertEqual(5, len(amp_flow.provides), amp_flow.provides)
|
210
212
|
|
211
213
|
amp_flow = self.LBFlow.get_post_lb_amp_association_flow(
|
212
214
|
'123', constants.TOPOLOGY_ACTIVE_STANDBY)
|
@@ -215,14 +217,16 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
215
217
|
|
216
218
|
self.assertIn(constants.LOADBALANCER_ID, amp_flow.requires)
|
217
219
|
self.assertIn(constants.UPDATE_DICT, amp_flow.requires)
|
220
|
+
self.assertIn(constants.AMPHORA_ID, amp_flow.requires)
|
218
221
|
|
219
222
|
self.assertIn(constants.AMPHORAE, amp_flow.provides)
|
223
|
+
self.assertIn(constants.AMPHORAE_STATUS, amp_flow.provides)
|
220
224
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, amp_flow.provides)
|
221
225
|
self.assertIn(constants.AMP_VRRP_INT, amp_flow.provides)
|
222
226
|
self.assertIn(constants.LOADBALANCER, amp_flow.provides)
|
223
227
|
|
224
|
-
self.assertEqual(
|
225
|
-
self.assertEqual(
|
228
|
+
self.assertEqual(3, len(amp_flow.requires), amp_flow.requires)
|
229
|
+
self.assertEqual(5, len(amp_flow.provides), amp_flow.provides)
|
226
230
|
|
227
231
|
@mock.patch('octavia.common.rpc.NOTIFIER',
|
228
232
|
new_callable=MockNOTIFIER)
|
@@ -285,6 +289,7 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
285
289
|
self.assertIn(constants.AMPHORA_ID, create_flow.provides)
|
286
290
|
self.assertIn(constants.AMPHORA_NETWORK_CONFIG, create_flow.provides)
|
287
291
|
self.assertIn(constants.AMPHORAE_NETWORK_CONFIG, create_flow.provides)
|
292
|
+
self.assertIn(constants.AMPHORAE_STATUS, create_flow.provides)
|
288
293
|
self.assertIn(constants.COMPUTE_ID, create_flow.provides)
|
289
294
|
self.assertIn(constants.COMPUTE_OBJ, create_flow.provides)
|
290
295
|
self.assertIn(constants.DELTAS, create_flow.provides)
|
@@ -296,7 +301,7 @@ class TestLoadBalancerFlows(base.TestCase):
|
|
296
301
|
self.assertIn(constants.ADDITIONAL_VIPS, create_flow.provides)
|
297
302
|
|
298
303
|
self.assertEqual(6, len(create_flow.requires), create_flow.requires)
|
299
|
-
self.assertEqual(
|
304
|
+
self.assertEqual(18, len(create_flow.provides),
|
300
305
|
create_flow.provides)
|
301
306
|
|
302
307
|
def _test_get_failover_LB_flow_single(self, amphorae):
|
@@ -132,21 +132,54 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
132
132
|
|
133
133
|
mock_amphora_repo_get.return_value = _db_amphora_mock
|
134
134
|
mock_lb_get.return_value = _db_load_balancer_mock
|
135
|
+
amphorae_status = {
|
136
|
+
_amphora_mock[constants.ID]: {
|
137
|
+
constants.UNREACHABLE: False
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
135
141
|
amp_list_update_obj = amphora_driver_tasks.AmphoraIndexListenerUpdate()
|
136
142
|
amp_list_update_obj.execute(_LB_mock, 0, [_amphora_mock],
|
143
|
+
amphorae_status,
|
144
|
+
_amphora_mock[constants.ID],
|
137
145
|
self.timeout_dict)
|
138
146
|
|
139
147
|
mock_driver.update_amphora_listeners.assert_called_once_with(
|
140
148
|
_db_load_balancer_mock, _db_amphora_mock, self.timeout_dict)
|
141
149
|
|
150
|
+
# Unreachable amp
|
151
|
+
mock_driver.reset_mock()
|
152
|
+
amphorae_status = {
|
153
|
+
_amphora_mock[constants.ID]: {
|
154
|
+
constants.UNREACHABLE: True
|
155
|
+
}
|
156
|
+
}
|
157
|
+
amp_list_update_obj.execute(_LB_mock, 0, [_amphora_mock],
|
158
|
+
amphorae_status,
|
159
|
+
_amphora_mock[constants.ID],
|
160
|
+
self.timeout_dict)
|
161
|
+
mock_driver.update_amphora_listeners.assert_not_called()
|
162
|
+
|
163
|
+
# Test exception
|
142
164
|
mock_driver.update_amphora_listeners.side_effect = Exception('boom')
|
143
165
|
|
144
|
-
amp_list_update_obj.execute(_LB_mock, 0,
|
145
|
-
[
|
166
|
+
amp_list_update_obj.execute(_LB_mock, 0, [_amphora_mock], {},
|
167
|
+
_amphora_mock[constants.ID],
|
168
|
+
self.timeout_dict)
|
146
169
|
|
147
170
|
mock_amphora_repo_update.assert_called_once_with(
|
148
171
|
_session_mock, AMP_ID, status=constants.ERROR)
|
149
172
|
|
173
|
+
# Test exception, secondary amp
|
174
|
+
mock_amphora_repo_update.reset_mock()
|
175
|
+
mock_driver.update_amphora_listeners.side_effect = Exception('boom')
|
176
|
+
|
177
|
+
amp_list_update_obj.execute(_LB_mock, 0, [_amphora_mock], {},
|
178
|
+
'1234',
|
179
|
+
self.timeout_dict)
|
180
|
+
|
181
|
+
mock_amphora_repo_update.assert_not_called()
|
182
|
+
|
150
183
|
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
151
184
|
@mock.patch('octavia.db.api.session')
|
152
185
|
def test_listeners_update(self,
|
@@ -198,39 +231,70 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
198
231
|
mock_driver, mock_generate_uuid, mock_log, mock_get_session,
|
199
232
|
mock_listener_repo_get, mock_listener_repo_update,
|
200
233
|
mock_amphora_repo_get, mock_amphora_repo_update):
|
201
|
-
amphora_mock = mock.MagicMock()
|
202
234
|
listeners_reload_obj = (
|
203
235
|
amphora_driver_tasks.AmphoraIndexListenersReload())
|
204
236
|
mock_lb = mock.MagicMock()
|
205
237
|
mock_listener = mock.MagicMock()
|
206
238
|
mock_listener.id = '12345'
|
207
|
-
mock_amphora_repo_get.return_value =
|
239
|
+
mock_amphora_repo_get.return_value = _amphora_mock
|
208
240
|
mock_lb_repo_get.return_value = mock_lb
|
209
241
|
mock_driver.reload.side_effect = [mock.DEFAULT, Exception('boom')]
|
210
242
|
|
211
243
|
# Test no listeners
|
212
244
|
mock_lb.listeners = None
|
213
|
-
listeners_reload_obj.execute(mock_lb, 0, None
|
245
|
+
listeners_reload_obj.execute(mock_lb, 0, None, {},
|
246
|
+
_amphora_mock[constants.ID])
|
214
247
|
mock_driver.reload.assert_not_called()
|
215
248
|
|
216
249
|
# Test with listeners
|
217
|
-
|
250
|
+
amphorae_status = {
|
251
|
+
_amphora_mock[constants.ID]: {
|
252
|
+
constants.UNREACHABLE: False
|
253
|
+
}
|
254
|
+
}
|
255
|
+
mock_driver.reload.reset_mock()
|
218
256
|
mock_lb.listeners = [mock_listener]
|
219
|
-
listeners_reload_obj.execute(mock_lb, 0, [
|
257
|
+
listeners_reload_obj.execute(mock_lb, 0, [_amphora_mock],
|
258
|
+
amphorae_status,
|
259
|
+
_amphora_mock[constants.ID],
|
220
260
|
timeout_dict=self.timeout_dict)
|
221
|
-
mock_driver.reload.assert_called_once_with(mock_lb,
|
261
|
+
mock_driver.reload.assert_called_once_with(mock_lb, _amphora_mock,
|
222
262
|
self.timeout_dict)
|
223
263
|
|
264
|
+
# Unreachable amp
|
265
|
+
amphorae_status = {
|
266
|
+
_amphora_mock[constants.ID]: {
|
267
|
+
constants.UNREACHABLE: True
|
268
|
+
}
|
269
|
+
}
|
270
|
+
mock_driver.reload.reset_mock()
|
271
|
+
listeners_reload_obj.execute(mock_lb, 0, [_amphora_mock],
|
272
|
+
amphorae_status,
|
273
|
+
_amphora_mock[constants.ID],
|
274
|
+
timeout_dict=self.timeout_dict)
|
275
|
+
mock_driver.reload.assert_not_called()
|
276
|
+
|
224
277
|
# Test with reload exception
|
225
278
|
mock_driver.reload.reset_mock()
|
226
|
-
listeners_reload_obj.execute(mock_lb, 0, [
|
279
|
+
listeners_reload_obj.execute(mock_lb, 0, [_amphora_mock], {},
|
280
|
+
_amphora_mock[constants.ID],
|
227
281
|
timeout_dict=self.timeout_dict)
|
228
|
-
mock_driver.reload.assert_called_once_with(mock_lb,
|
282
|
+
mock_driver.reload.assert_called_once_with(mock_lb, _amphora_mock,
|
229
283
|
self.timeout_dict)
|
230
284
|
mock_amphora_repo_update.assert_called_once_with(
|
231
|
-
_session_mock,
|
285
|
+
_session_mock, _amphora_mock[constants.ID],
|
232
286
|
status=constants.ERROR)
|
233
287
|
|
288
|
+
# Test with reload exception, secondary amp
|
289
|
+
mock_driver.reload.reset_mock()
|
290
|
+
mock_amphora_repo_update.reset_mock()
|
291
|
+
listeners_reload_obj.execute(mock_lb, 0, [_amphora_mock], {},
|
292
|
+
'1234',
|
293
|
+
timeout_dict=self.timeout_dict)
|
294
|
+
mock_driver.reload.assert_called_once_with(mock_lb, _amphora_mock,
|
295
|
+
self.timeout_dict)
|
296
|
+
mock_amphora_repo_update.assert_not_called()
|
297
|
+
|
234
298
|
@mock.patch('octavia.controller.worker.task_utils.TaskUtils.'
|
235
299
|
'mark_listener_prov_status_error')
|
236
300
|
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
@@ -827,6 +891,11 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
827
891
|
FAKE_INTERFACE = 'fake0'
|
828
892
|
mock_driver.get_interface_from_ip.side_effect = [FAKE_INTERFACE,
|
829
893
|
Exception('boom')]
|
894
|
+
amphorae_status = {
|
895
|
+
_amphora_mock[constants.ID]: {
|
896
|
+
constants.UNREACHABLE: False
|
897
|
+
}
|
898
|
+
}
|
830
899
|
|
831
900
|
timeout_dict = {constants.CONN_MAX_RETRIES: CONN_MAX_RETRIES,
|
832
901
|
constants.CONN_RETRY_INTERVAL: CONN_RETRY_INTERVAL}
|
@@ -834,20 +903,39 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
834
903
|
amphora_update_vrrp_interface_obj = (
|
835
904
|
amphora_driver_tasks.AmphoraIndexUpdateVRRPInterface())
|
836
905
|
amphora_update_vrrp_interface_obj.execute(
|
837
|
-
0, [_amphora_mock],
|
906
|
+
0, [_amphora_mock], amphorae_status, _amphora_mock[constants.ID],
|
907
|
+
timeout_dict)
|
838
908
|
mock_driver.get_interface_from_ip.assert_called_once_with(
|
839
909
|
_db_amphora_mock, _db_amphora_mock.vrrp_ip,
|
840
910
|
timeout_dict=timeout_dict)
|
841
911
|
mock_amphora_repo_update.assert_called_once_with(
|
842
912
|
_session_mock, _db_amphora_mock.id, vrrp_interface=FAKE_INTERFACE)
|
843
913
|
|
914
|
+
# Unreachable amp
|
915
|
+
mock_driver.reset_mock()
|
916
|
+
amphorae_status = {
|
917
|
+
_amphora_mock[constants.ID]: {
|
918
|
+
constants.UNREACHABLE: True
|
919
|
+
}
|
920
|
+
}
|
921
|
+
amphora_update_vrrp_interface_obj.execute(
|
922
|
+
0, [_amphora_mock], amphorae_status, _amphora_mock[constants.ID],
|
923
|
+
timeout_dict)
|
924
|
+
mock_driver.get_interface_from_ip.assert_not_called()
|
925
|
+
|
844
926
|
# Test with an exception
|
845
927
|
mock_amphora_repo_update.reset_mock()
|
846
928
|
amphora_update_vrrp_interface_obj.execute(
|
847
|
-
0, [_amphora_mock], timeout_dict)
|
929
|
+
0, [_amphora_mock], {}, _amphora_mock[constants.ID], timeout_dict)
|
848
930
|
mock_amphora_repo_update.assert_called_once_with(
|
849
931
|
_session_mock, _db_amphora_mock.id, status=constants.ERROR)
|
850
932
|
|
933
|
+
# Test with an exception, secondary amp
|
934
|
+
mock_amphora_repo_update.reset_mock()
|
935
|
+
amphora_update_vrrp_interface_obj.execute(
|
936
|
+
0, [_amphora_mock], {}, '1234', timeout_dict)
|
937
|
+
mock_amphora_repo_update.assert_not_called()
|
938
|
+
|
851
939
|
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
|
852
940
|
def test_amphora_vrrp_update(self,
|
853
941
|
mock_lb_get,
|
@@ -895,23 +983,52 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
895
983
|
Exception('boom')]
|
896
984
|
mock_lb_get.return_value = _db_load_balancer_mock
|
897
985
|
mock_amphora_repo_get.return_value = _db_amphora_mock
|
986
|
+
amphorae_status = {
|
987
|
+
_amphora_mock[constants.ID]: {
|
988
|
+
constants.UNREACHABLE: False
|
989
|
+
}
|
990
|
+
}
|
991
|
+
|
898
992
|
amphora_vrrp_update_obj = (
|
899
993
|
amphora_driver_tasks.AmphoraIndexVRRPUpdate())
|
900
994
|
|
901
995
|
amphora_vrrp_update_obj.execute(LB_ID, amphorae_network_config,
|
902
|
-
0, [_amphora_mock],
|
996
|
+
0, [_amphora_mock], amphorae_status,
|
997
|
+
'fakeint0',
|
998
|
+
_amphora_mock[constants.ID],
|
903
999
|
timeout_dict=self.timeout_dict)
|
904
1000
|
mock_driver.update_vrrp_conf.assert_called_once_with(
|
905
1001
|
_db_load_balancer_mock, amphorae_network_config, _db_amphora_mock,
|
906
1002
|
self.timeout_dict)
|
907
1003
|
|
1004
|
+
# Unreachable amp
|
1005
|
+
amphorae_status = {
|
1006
|
+
_amphora_mock[constants.ID]: {
|
1007
|
+
constants.UNREACHABLE: True
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
mock_amphora_repo_update.reset_mock()
|
1011
|
+
mock_driver.update_vrrp_conf.reset_mock()
|
1012
|
+
amphora_vrrp_update_obj.execute(LB_ID, amphorae_network_config,
|
1013
|
+
0, [_amphora_mock], amphorae_status,
|
1014
|
+
None, _amphora_mock[constants.ID])
|
1015
|
+
mock_driver.update_vrrp_conf.assert_not_called()
|
1016
|
+
|
908
1017
|
# Test with an exception
|
909
1018
|
mock_amphora_repo_update.reset_mock()
|
910
1019
|
amphora_vrrp_update_obj.execute(LB_ID, amphorae_network_config,
|
911
|
-
0, [_amphora_mock], 'fakeint0'
|
1020
|
+
0, [_amphora_mock], {}, 'fakeint0',
|
1021
|
+
_amphora_mock[constants.ID])
|
912
1022
|
mock_amphora_repo_update.assert_called_once_with(
|
913
1023
|
_session_mock, _db_amphora_mock.id, status=constants.ERROR)
|
914
1024
|
|
1025
|
+
# Test with an exception, secondary amp
|
1026
|
+
mock_amphora_repo_update.reset_mock()
|
1027
|
+
amphora_vrrp_update_obj.execute(LB_ID, amphorae_network_config,
|
1028
|
+
0, [_amphora_mock], {}, 'fakeint0',
|
1029
|
+
'1234')
|
1030
|
+
mock_amphora_repo_update.assert_not_called()
|
1031
|
+
|
915
1032
|
def test_amphora_vrrp_start(self,
|
916
1033
|
mock_driver,
|
917
1034
|
mock_generate_uuid,
|
@@ -939,25 +1056,54 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
939
1056
|
mock_amphora_repo_get,
|
940
1057
|
mock_amphora_repo_update):
|
941
1058
|
mock_amphora_repo_get.return_value = _db_amphora_mock
|
1059
|
+
amphorae_status = {
|
1060
|
+
_amphora_mock[constants.ID]: {
|
1061
|
+
constants.UNREACHABLE: False
|
1062
|
+
}
|
1063
|
+
}
|
1064
|
+
|
942
1065
|
amphora_vrrp_start_obj = (
|
943
1066
|
amphora_driver_tasks.AmphoraIndexVRRPStart())
|
944
1067
|
mock_driver.start_vrrp_service.side_effect = [mock.DEFAULT,
|
945
1068
|
Exception('boom')]
|
946
1069
|
|
947
|
-
amphora_vrrp_start_obj.execute(0, [_amphora_mock],
|
1070
|
+
amphora_vrrp_start_obj.execute(0, [_amphora_mock], amphorae_status,
|
1071
|
+
_amphora_mock[constants.ID],
|
948
1072
|
timeout_dict=self.timeout_dict)
|
949
1073
|
mock_driver.start_vrrp_service.assert_called_once_with(
|
950
1074
|
_db_amphora_mock, self.timeout_dict)
|
951
1075
|
|
1076
|
+
# Unreachable amp
|
1077
|
+
mock_driver.start_vrrp_service.reset_mock()
|
1078
|
+
amphorae_status = {
|
1079
|
+
_amphora_mock[constants.ID]: {
|
1080
|
+
constants.UNREACHABLE: True
|
1081
|
+
}
|
1082
|
+
}
|
1083
|
+
amphora_vrrp_start_obj.execute(0, [_amphora_mock], amphorae_status,
|
1084
|
+
_amphora_mock[constants.ID],
|
1085
|
+
timeout_dict=self.timeout_dict)
|
1086
|
+
mock_driver.start_vrrp_service.assert_not_called()
|
1087
|
+
|
952
1088
|
# Test with a start exception
|
953
1089
|
mock_driver.start_vrrp_service.reset_mock()
|
954
|
-
amphora_vrrp_start_obj.execute(0, [_amphora_mock],
|
1090
|
+
amphora_vrrp_start_obj.execute(0, [_amphora_mock], {},
|
1091
|
+
_amphora_mock[constants.ID],
|
955
1092
|
timeout_dict=self.timeout_dict)
|
956
1093
|
mock_driver.start_vrrp_service.assert_called_once_with(
|
957
1094
|
_db_amphora_mock, self.timeout_dict)
|
958
1095
|
mock_amphora_repo_update.assert_called_once_with(
|
959
1096
|
_session_mock, _db_amphora_mock.id, status=constants.ERROR)
|
960
1097
|
|
1098
|
+
# Test with a start exception, secondary amp
|
1099
|
+
mock_driver.start_vrrp_service.reset_mock()
|
1100
|
+
mock_amphora_repo_update.reset_mock()
|
1101
|
+
amphora_vrrp_start_obj.execute(0, [_amphora_mock], {}, '1234',
|
1102
|
+
timeout_dict=self.timeout_dict)
|
1103
|
+
mock_driver.start_vrrp_service.assert_called_once_with(
|
1104
|
+
_db_amphora_mock, self.timeout_dict)
|
1105
|
+
mock_amphora_repo_update.assert_not_called()
|
1106
|
+
|
961
1107
|
def test_amphora_compute_connectivity_wait(self,
|
962
1108
|
mock_driver,
|
963
1109
|
mock_generate_uuid,
|
@@ -1029,3 +1175,74 @@ class TestAmphoraDriverTasks(base.TestCase):
|
|
1029
1175
|
self.assertRaises(driver_except.TimeOutException,
|
1030
1176
|
amp_config_update_obj.execute,
|
1031
1177
|
_amphora_mock, flavor)
|
1178
|
+
|
1179
|
+
def test_amphorae_get_connectivity_status(self,
|
1180
|
+
mock_driver,
|
1181
|
+
mock_generate_uuid,
|
1182
|
+
mock_log,
|
1183
|
+
mock_get_session,
|
1184
|
+
mock_listener_repo_get,
|
1185
|
+
mock_listener_repo_update,
|
1186
|
+
mock_amphora_repo_get,
|
1187
|
+
mock_amphora_repo_update):
|
1188
|
+
amphora1_mock = mock.MagicMock()
|
1189
|
+
amphora1_mock[constants.ID] = 'id1'
|
1190
|
+
amphora2_mock = mock.MagicMock()
|
1191
|
+
amphora2_mock[constants.ID] = 'id2'
|
1192
|
+
db_amphora1_mock = mock.Mock()
|
1193
|
+
db_amphora2_mock = mock.Mock()
|
1194
|
+
|
1195
|
+
amp_get_connectivity_status = (
|
1196
|
+
amphora_driver_tasks.AmphoraeGetConnectivityStatus())
|
1197
|
+
|
1198
|
+
# All amphorae reachable
|
1199
|
+
mock_amphora_repo_get.side_effect = [
|
1200
|
+
db_amphora1_mock,
|
1201
|
+
db_amphora2_mock]
|
1202
|
+
mock_driver.check.return_value = None
|
1203
|
+
|
1204
|
+
ret = amp_get_connectivity_status.execute(
|
1205
|
+
[amphora1_mock, amphora2_mock],
|
1206
|
+
amphora1_mock[constants.ID],
|
1207
|
+
timeout_dict=self.timeout_dict)
|
1208
|
+
mock_driver.check.assert_has_calls(
|
1209
|
+
[mock.call(db_amphora1_mock, timeout_dict=self.timeout_dict),
|
1210
|
+
mock.call(db_amphora2_mock, timeout_dict=self.timeout_dict)])
|
1211
|
+
self.assertFalse(
|
1212
|
+
ret[amphora1_mock[constants.ID]][constants.UNREACHABLE])
|
1213
|
+
self.assertFalse(
|
1214
|
+
ret[amphora2_mock[constants.ID]][constants.UNREACHABLE])
|
1215
|
+
|
1216
|
+
# amphora1 unreachable
|
1217
|
+
mock_driver.check.reset_mock()
|
1218
|
+
mock_amphora_repo_get.side_effect = [
|
1219
|
+
db_amphora1_mock,
|
1220
|
+
db_amphora2_mock]
|
1221
|
+
mock_driver.check.side_effect = [
|
1222
|
+
driver_except.TimeOutException, None]
|
1223
|
+
self.assertRaises(driver_except.TimeOutException,
|
1224
|
+
amp_get_connectivity_status.execute,
|
1225
|
+
[amphora1_mock, amphora2_mock],
|
1226
|
+
amphora1_mock[constants.ID],
|
1227
|
+
timeout_dict=self.timeout_dict)
|
1228
|
+
mock_driver.check.assert_called_with(
|
1229
|
+
db_amphora1_mock, timeout_dict=self.timeout_dict)
|
1230
|
+
|
1231
|
+
# amphora2 unreachable
|
1232
|
+
mock_driver.check.reset_mock()
|
1233
|
+
mock_amphora_repo_get.side_effect = [
|
1234
|
+
db_amphora1_mock,
|
1235
|
+
db_amphora2_mock]
|
1236
|
+
mock_driver.check.side_effect = [
|
1237
|
+
None, driver_except.TimeOutException]
|
1238
|
+
ret = amp_get_connectivity_status.execute(
|
1239
|
+
[amphora1_mock, amphora2_mock],
|
1240
|
+
amphora1_mock[constants.ID],
|
1241
|
+
timeout_dict=self.timeout_dict)
|
1242
|
+
mock_driver.check.assert_has_calls(
|
1243
|
+
[mock.call(db_amphora1_mock, timeout_dict=self.timeout_dict),
|
1244
|
+
mock.call(db_amphora2_mock, timeout_dict=self.timeout_dict)])
|
1245
|
+
self.assertFalse(
|
1246
|
+
ret[amphora1_mock[constants.ID]][constants.UNREACHABLE])
|
1247
|
+
self.assertTrue(
|
1248
|
+
ret[amphora2_mock[constants.ID]][constants.UNREACHABLE])
|
@@ -181,7 +181,9 @@ class TestDatabaseTasks(base.TestCase):
|
|
181
181
|
|
182
182
|
@mock.patch('octavia.db.repositories.AmphoraRepository.create',
|
183
183
|
return_value=_db_amphora_mock)
|
184
|
+
@mock.patch('octavia.db.repositories.AmphoraHealthRepository.delete')
|
184
185
|
def test_create_amphora_in_db(self,
|
186
|
+
mock_amphora_health_repo_delete,
|
185
187
|
mock_create,
|
186
188
|
mock_generate_uuid,
|
187
189
|
mock_LOG,
|
@@ -207,23 +209,43 @@ class TestDatabaseTasks(base.TestCase):
|
|
207
209
|
|
208
210
|
# Test the revert
|
209
211
|
create_amp_in_db.revert(_tf_failure_mock)
|
210
|
-
|
212
|
+
mock_amphora_repo_delete.assert_not_called()
|
213
|
+
mock_amphora_health_repo_delete.assert_not_called()
|
211
214
|
|
215
|
+
amp_id = 'AMP'
|
212
216
|
mock_amphora_repo_delete.reset_mock()
|
213
|
-
|
217
|
+
mock_amphora_health_repo_delete.reset_mock()
|
218
|
+
create_amp_in_db.revert(result=amp_id)
|
214
219
|
self.assertTrue(mock_amphora_repo_delete.called)
|
220
|
+
self.assertTrue(mock_amphora_health_repo_delete.called)
|
215
221
|
mock_amphora_repo_delete.assert_called_once_with(
|
216
222
|
mock_session,
|
217
|
-
id=
|
223
|
+
id=amp_id)
|
224
|
+
mock_amphora_health_repo_delete.assert_called_once_with(
|
225
|
+
mock_session,
|
226
|
+
amphora_id=amp_id)
|
227
|
+
mock_LOG.error.assert_not_called()
|
228
|
+
mock_LOG.debug.assert_not_called()
|
218
229
|
|
219
230
|
# Test revert with exception
|
220
231
|
mock_amphora_repo_delete.reset_mock()
|
221
|
-
|
222
|
-
|
232
|
+
mock_amphora_health_repo_delete.reset_mock()
|
233
|
+
err1_msg, err2_msg = ('fail', 'fail2')
|
234
|
+
mock_amphora_repo_delete.side_effect = Exception(err1_msg)
|
235
|
+
mock_amphora_health_repo_delete.side_effect = Exception(err2_msg)
|
236
|
+
create_amp_in_db.revert(result=amp_id)
|
223
237
|
self.assertTrue(mock_amphora_repo_delete.called)
|
238
|
+
self.assertTrue(mock_amphora_health_repo_delete.called)
|
224
239
|
mock_amphora_repo_delete.assert_called_once_with(
|
225
240
|
mock_session,
|
226
|
-
id=
|
241
|
+
id=amp_id)
|
242
|
+
mock_amphora_health_repo_delete.assert_called_once_with(
|
243
|
+
mock_session,
|
244
|
+
amphora_id=amp_id)
|
245
|
+
mock_LOG.error.assert_called_once_with(
|
246
|
+
"Failed to delete amphora %(amp)s "
|
247
|
+
"in the database due to: "
|
248
|
+
"%(except)s", {'amp': amp_id, 'except': err1_msg})
|
227
249
|
|
228
250
|
@mock.patch('octavia.db.repositories.ListenerRepository.delete')
|
229
251
|
def test_delete_listener_in_db(self,
|