17
17
18
18
from neutron .common .ovn import constants
19
19
from neutron .conf .plugins .ml2 .drivers .ovn import ovn_conf
20
+ from neutron .plugins .ml2 import db as ml2_db
20
21
from neutron .plugins .ml2 .drivers .ovn .mech_driver .ovsdb import ovn_client
21
22
from neutron .tests import base
22
23
from neutron .tests .unit import fake_resources as fakes
25
26
from neutron_lib .api .definitions import portbindings
26
27
from neutron_lib .services .logapi import constants as log_const
27
28
29
+ from tenacity import wait_none
30
+
28
31
29
32
class TestOVNClientBase (base .BaseTestCase ):
30
33
@@ -47,6 +50,9 @@ def setUp(self):
47
50
fakes .FakeChassis .create (
48
51
attrs = {'hostname' : self .fake_smartnic_hostname }))
49
52
53
+ # Disable tenacity wait for UT
54
+ self .ovn_client ._wait_for_port_bindings_host .retry .wait = wait_none ()
55
+
50
56
def test_vnic_normal_unbound_port (self ):
51
57
self .assertEqual (
52
58
'' ,
@@ -139,6 +145,45 @@ def test_update_lsp_host_info_up(self):
139
145
'Logical_Switch_Port' , port_id ,
140
146
('external_ids' , {constants .OVN_HOST_ID_EXT_ID_KEY : host_id }))
141
147
148
+ def test_update_lsp_host_info_up_retry (self ):
149
+ context = mock .MagicMock ()
150
+ host_id = 'fake-binding-host-id'
151
+ port_id = 'fake-port-id'
152
+ db_port_no_host = mock .Mock (
153
+ id = port_id , port_bindings = [mock .Mock (host = "" )])
154
+ db_port = mock .Mock (
155
+ id = port_id , port_bindings = [mock .Mock (host = host_id )])
156
+
157
+ with mock .patch .object (
158
+ self .ovn_client , '_wait_for_port_bindings_host' ) as mock_wait :
159
+ mock_wait .return_value = db_port
160
+ self .ovn_client .update_lsp_host_info (context , db_port_no_host )
161
+
162
+ # Assert _wait_for_port_bindings_host was called
163
+ mock_wait .assert_called_once_with (context , port_id )
164
+
165
+ # Assert host_id was set
166
+ self .nb_idl .db_set .assert_called_once_with (
167
+ 'Logical_Switch_Port' , port_id ,
168
+ ('external_ids' , {constants .OVN_HOST_ID_EXT_ID_KEY : host_id }))
169
+
170
+ def test_update_lsp_host_info_up_retry_fail (self ):
171
+ context = mock .MagicMock ()
172
+ port_id = 'fake-port-id'
173
+ db_port_no_host = mock .Mock (
174
+ id = port_id , port_bindings = [mock .Mock (host = "" )])
175
+
176
+ with mock .patch .object (
177
+ self .ovn_client , '_wait_for_port_bindings_host' ) as mock_wait :
178
+ mock_wait .side_effect = RuntimeError ("boom" )
179
+ self .ovn_client .update_lsp_host_info (context , db_port_no_host )
180
+
181
+ # Assert _wait_for_port_bindings_host was called
182
+ mock_wait .assert_called_once_with (context , port_id )
183
+
184
+ # Assert host_id was NOT set
185
+ self .assertFalse (self .nb_idl .db_set .called )
186
+
142
187
def test_update_lsp_host_info_down (self ):
143
188
context = mock .MagicMock ()
144
189
port_id = 'fake-port-id'
@@ -150,6 +195,47 @@ def test_update_lsp_host_info_down(self):
150
195
'Logical_Switch_Port' , port_id , 'external_ids' ,
151
196
constants .OVN_HOST_ID_EXT_ID_KEY , if_exists = True )
152
197
198
+ @mock .patch .object (ml2_db , 'get_port' )
199
+ def test__wait_for_port_bindings_host (self , mock_get_port ):
200
+ context = mock .MagicMock ()
201
+ host_id = 'fake-binding-host-id'
202
+ port_id = 'fake-port-id'
203
+ db_port_no_host = mock .Mock (
204
+ id = port_id , port_bindings = [mock .Mock (host = "" )])
205
+ db_port = mock .Mock (
206
+ id = port_id , port_bindings = [mock .Mock (host = host_id )])
207
+
208
+ mock_get_port .side_effect = (db_port_no_host , db_port )
209
+
210
+ ret = self .ovn_client ._wait_for_port_bindings_host (
211
+ context , port_id )
212
+
213
+ self .assertEqual (ret , db_port )
214
+
215
+ expected_calls = [mock .call (context , port_id ),
216
+ mock .call (context , port_id )]
217
+ mock_get_port .assert_has_calls (expected_calls )
218
+
219
+ @mock .patch .object (ml2_db , 'get_port' )
220
+ def test__wait_for_port_bindings_host_fail (self , mock_get_port ):
221
+ context = mock .MagicMock ()
222
+ port_id = 'fake-port-id'
223
+ db_port_no_pb = mock .Mock (id = port_id , port_bindings = [])
224
+ db_port_no_host = mock .Mock (
225
+ id = port_id , port_bindings = [mock .Mock (host = "" )])
226
+
227
+ mock_get_port .side_effect = (
228
+ db_port_no_pb , db_port_no_host , db_port_no_host )
229
+
230
+ self .assertRaises (
231
+ RuntimeError , self .ovn_client ._wait_for_port_bindings_host ,
232
+ context , port_id )
233
+
234
+ expected_calls = [mock .call (context , port_id ),
235
+ mock .call (context , port_id ),
236
+ mock .call (context , port_id )]
237
+ mock_get_port .assert_has_calls (expected_calls )
238
+
153
239
154
240
class TestOVNClientFairMeter (TestOVNClientBase ,
155
241
test_log_driver .TestOVNDriverBase ):
0 commit comments