@@ -5212,7 +5212,8 @@ def test_get_preexisting_port_ids(self, mock_get_nw_info):
52125212 self .assertEqual (['2' , '3' ], result , "Invalid preexisting ports" )
52135213
52145214 @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 ):
52165217 mock_ctx = mock .Mock (is_admin = False )
52175218 ports = ["1" , "2" , "3" ]
52185219
@@ -5228,23 +5229,16 @@ def _test_unbind_ports_get_client(self, mock_neutron, mock_show):
52285229 self .assertEqual (1 , mock_neutron .call_count )
52295230 mock_neutron .assert_has_calls (get_client_calls , True )
52305231
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-
52405232 @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 ):
52425235 mock_client = mock .Mock ()
52435236 mock_update_port = mock .Mock ()
52445237 mock_client .update_port = mock_update_port
52455238 mock_ctx = mock .Mock (is_admin = False )
52465239 ports = ["1" , "2" , "3" ]
52475240 mock_show .side_effect = [{"id" : "1" }, {"id" : "2" }, {"id" : "3" }]
5241+
52485242 api = neutronapi .API ()
52495243 api ._unbind_ports (mock_ctx , ports , mock_neutron , mock_client )
52505244
@@ -5258,14 +5252,6 @@ def _test_unbind_ports(self, mock_neutron, mock_show):
52585252 self .assertEqual (3 , mock_update_port .call_count )
52595253 mock_update_port .assert_has_calls (update_port_calls )
52605254
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-
52695255 def test_unbind_ports_no_port_ids (self ):
52705256 # Tests that None entries in the ports list are filtered out.
52715257 mock_client = mock .Mock ()
@@ -6014,7 +6000,6 @@ def test_get_instance_id_by_floating_address_port_not_found(self,
60146000 def test_unbind_ports_port_show_portnotfound (self , mock_log , mock_show ):
60156001 api = neutronapi .API ()
60166002 neutron_client = mock .Mock ()
6017- mock_show .return_value = {'id' : uuids .port }
60186003 api ._unbind_ports (self .context , [uuids .port_id ],
60196004 neutron_client , neutron_client )
60206005 mock_show .assert_called_once_with (
@@ -6023,6 +6008,59 @@ def test_unbind_ports_port_show_portnotfound(self, mock_log, mock_show):
60236008 neutron_client = mock .ANY )
60246009 mock_log .assert_not_called ()
60256010
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+
60266064 @mock .patch ('nova.network.neutron.API._show_port' ,
60276065 side_effect = Exception )
60286066 @mock .patch .object (neutronapi .LOG , 'exception' )
@@ -6042,7 +6080,7 @@ def test_unbind_ports_port_show_unexpected_error(self,
60426080
60436081 @mock .patch ('nova.network.neutron.API._show_port' )
60446082 @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 ):
60466084 api = neutronapi .API ()
60476085 neutron_client = mock .Mock ()
60486086 neutron_client .update_port = mock .Mock (
@@ -6058,7 +6096,9 @@ def test_unbind_ports_portnotfound(self, mock_log, mock_show):
60586096
60596097 @mock .patch ('nova.network.neutron.API._show_port' )
60606098 @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+ ):
60626102 api = neutronapi .API ()
60636103 neutron_client = mock .Mock ()
60646104 neutron_client .update_port = mock .Mock (
0 commit comments