@@ -5212,7 +5212,8 @@ def test_get_preexisting_port_ids(self, mock_get_nw_info):
5212
5212
self .assertEqual (['2' , '3' ], result , "Invalid preexisting ports" )
5213
5213
5214
5214
@mock .patch ('nova.network.neutron.API._show_port' )
5215
- def _test_unbind_ports_get_client (self , mock_neutron , mock_show ):
5215
+ @mock .patch ('nova.network.neutron.get_client' )
5216
+ def test_unbind_ports_get_client (self , mock_neutron , mock_show ):
5216
5217
mock_ctx = mock .Mock (is_admin = False )
5217
5218
ports = ["1" , "2" , "3" ]
5218
5219
@@ -5228,23 +5229,16 @@ def _test_unbind_ports_get_client(self, mock_neutron, mock_show):
5228
5229
self .assertEqual (1 , mock_neutron .call_count )
5229
5230
mock_neutron .assert_has_calls (get_client_calls , True )
5230
5231
5231
- @mock .patch ('nova.network.neutron.get_client' )
5232
- def test_unbind_ports_get_client_binding_extension (self ,
5233
- mock_neutron ):
5234
- self ._test_unbind_ports_get_client (mock_neutron )
5235
-
5236
- @mock .patch ('nova.network.neutron.get_client' )
5237
- def test_unbind_ports_get_client (self , mock_neutron ):
5238
- self ._test_unbind_ports_get_client (mock_neutron )
5239
-
5240
5232
@mock .patch ('nova.network.neutron.API._show_port' )
5241
- def _test_unbind_ports (self , mock_neutron , mock_show ):
5233
+ @mock .patch ('nova.network.neutron.get_client' )
5234
+ def test_unbind_ports (self , mock_neutron , mock_show ):
5242
5235
mock_client = mock .Mock ()
5243
5236
mock_update_port = mock .Mock ()
5244
5237
mock_client .update_port = mock_update_port
5245
5238
mock_ctx = mock .Mock (is_admin = False )
5246
5239
ports = ["1" , "2" , "3" ]
5247
5240
mock_show .side_effect = [{"id" : "1" }, {"id" : "2" }, {"id" : "3" }]
5241
+
5248
5242
api = neutronapi .API ()
5249
5243
api ._unbind_ports (mock_ctx , ports , mock_neutron , mock_client )
5250
5244
@@ -5258,14 +5252,6 @@ def _test_unbind_ports(self, mock_neutron, mock_show):
5258
5252
self .assertEqual (3 , mock_update_port .call_count )
5259
5253
mock_update_port .assert_has_calls (update_port_calls )
5260
5254
5261
- @mock .patch ('nova.network.neutron.get_client' )
5262
- def test_unbind_ports_binding_ext (self , mock_neutron ):
5263
- self ._test_unbind_ports (mock_neutron )
5264
-
5265
- @mock .patch ('nova.network.neutron.get_client' )
5266
- def test_unbind_ports (self , mock_neutron ):
5267
- self ._test_unbind_ports (mock_neutron )
5268
-
5269
5255
def test_unbind_ports_no_port_ids (self ):
5270
5256
# Tests that None entries in the ports list are filtered out.
5271
5257
mock_client = mock .Mock ()
@@ -6014,7 +6000,6 @@ def test_get_instance_id_by_floating_address_port_not_found(self,
6014
6000
def test_unbind_ports_port_show_portnotfound (self , mock_log , mock_show ):
6015
6001
api = neutronapi .API ()
6016
6002
neutron_client = mock .Mock ()
6017
- mock_show .return_value = {'id' : uuids .port }
6018
6003
api ._unbind_ports (self .context , [uuids .port_id ],
6019
6004
neutron_client , neutron_client )
6020
6005
mock_show .assert_called_once_with (
@@ -6023,6 +6008,59 @@ def test_unbind_ports_port_show_portnotfound(self, mock_log, mock_show):
6023
6008
neutron_client = mock .ANY )
6024
6009
mock_log .assert_not_called ()
6025
6010
6011
+ @mock .patch ('nova.network.neutron.API._show_port' )
6012
+ @mock .patch .object (neutronapi , 'LOG' )
6013
+ def test_unbind_ports_port_show_portnotfound_multiple_ports (
6014
+ self , mock_log , mock_show ,
6015
+ ):
6016
+ """Ensure we continue unbinding ports even when one isn't found."""
6017
+ mock_show .side_effect = [
6018
+ exception .PortNotFound (port_id = uuids .port_a ),
6019
+ {'id' : uuids .port_b },
6020
+ ]
6021
+ api = neutronapi .API ()
6022
+ neutron_client = mock .Mock ()
6023
+
6024
+ api ._unbind_ports (
6025
+ self .context ,
6026
+ [uuids .port_a , uuids .port_b ],
6027
+ neutron_client ,
6028
+ neutron_client ,
6029
+ )
6030
+
6031
+ mock_show .assert_has_calls (
6032
+ [
6033
+ mock .call (
6034
+ self .context ,
6035
+ uuids .port_a ,
6036
+ fields = ['binding:profile' , 'network_id' ],
6037
+ neutron_client = neutron_client ,
6038
+ ),
6039
+ mock .call (
6040
+ self .context ,
6041
+ uuids .port_b ,
6042
+ fields = ['binding:profile' , 'network_id' ],
6043
+ neutron_client = neutron_client ,
6044
+ ),
6045
+ ]
6046
+ )
6047
+ # Only the port that exists should be updated
6048
+ neutron_client .update_port .assert_called_once_with (
6049
+ uuids .port_b ,
6050
+ {
6051
+ 'port' : {
6052
+ 'device_id' : '' ,
6053
+ 'device_owner' : '' ,
6054
+ 'binding:profile' : {},
6055
+ 'binding:host_id' : None ,
6056
+ }
6057
+ }
6058
+ )
6059
+ mock_log .exception .assert_not_called ()
6060
+ mock_log .debug .assert_called_with (
6061
+ 'Unable to show port %s as it no longer exists.' , uuids .port_a ,
6062
+ )
6063
+
6026
6064
@mock .patch ('nova.network.neutron.API._show_port' ,
6027
6065
side_effect = Exception )
6028
6066
@mock .patch .object (neutronapi .LOG , 'exception' )
@@ -6042,7 +6080,7 @@ def test_unbind_ports_port_show_unexpected_error(self,
6042
6080
6043
6081
@mock .patch ('nova.network.neutron.API._show_port' )
6044
6082
@mock .patch .object (neutronapi .LOG , 'exception' )
6045
- def test_unbind_ports_portnotfound (self , mock_log , mock_show ):
6083
+ def test_unbind_ports_port_update_portnotfound (self , mock_log , mock_show ):
6046
6084
api = neutronapi .API ()
6047
6085
neutron_client = mock .Mock ()
6048
6086
neutron_client .update_port = mock .Mock (
@@ -6058,7 +6096,9 @@ def test_unbind_ports_portnotfound(self, mock_log, mock_show):
6058
6096
6059
6097
@mock .patch ('nova.network.neutron.API._show_port' )
6060
6098
@mock .patch .object (neutronapi .LOG , 'exception' )
6061
- def test_unbind_ports_unexpected_error (self , mock_log , mock_show ):
6099
+ def test_unbind_ports_port_update_unexpected_error (
6100
+ self , mock_log , mock_show ,
6101
+ ):
6062
6102
api = neutronapi .API ()
6063
6103
neutron_client = mock .Mock ()
6064
6104
neutron_client .update_port = mock .Mock (
0 commit comments