@@ -97,13 +97,23 @@ def _verify_trunk_info(self, trunk, has_items, host=''):
97
97
if trunk .get ('status' ):
98
98
self .assertEqual (trunk_consts .TRUNK_ACTIVE_STATUS , trunk ['status' ])
99
99
100
- def _bind_port (self , port_id , host ):
100
+ def _bind_port (self , port_id , host_source , host_dest = None ):
101
101
with db_api .CONTEXT_WRITER .using (self .context ):
102
- pb = port_obj .PortBinding .get_object (self .context ,
103
- port_id = port_id , host = '' )
104
- pb .delete ()
105
- port_obj .PortBinding (self .context , port_id = port_id , host = host ,
106
- vif_type = portbindings .VIF_TYPE_OVS ).create ()
102
+ for pb in port_obj .PortBinding .get_objects (self .context ,
103
+ port_id = port_id ):
104
+ pb .delete ()
105
+ profile = {}
106
+ if host_dest :
107
+ # When "host_dest" there are 2 port bindings, as in a live
108
+ # migration; the second one (destination host) is inactive.
109
+ profile [ovn_const .MIGRATING_ATTR ] = host_dest
110
+ port_obj .PortBinding (
111
+ self .context , port_id = port_id , host = host_dest ,
112
+ vif_type = portbindings .VIF_TYPE_OVS ,
113
+ status = n_consts .INACTIVE ).create ()
114
+ port_obj .PortBinding (
115
+ self .context , port_id = port_id , host = host_source ,
116
+ profile = profile , vif_type = portbindings .VIF_TYPE_OVS ).create ()
107
117
108
118
def test_trunk_create (self ):
109
119
with self .trunk () as trunk :
@@ -148,6 +158,21 @@ def test_subport_add(self):
148
158
self ._verify_trunk_info (new_trunk , has_items = True ,
149
159
host = 'host1' )
150
160
161
+ def test_subport_add_live_migration_multiple_port_binding (self ):
162
+ with self .subport () as subport :
163
+ with self .trunk () as trunk :
164
+ self .trunk_plugin .add_subports (self .context , trunk ['id' ],
165
+ {'sub_ports' : [subport ]})
166
+ new_trunk = self .trunk_plugin .get_trunk (self .context ,
167
+ trunk ['id' ])
168
+ self ._verify_trunk_info (new_trunk , has_items = True )
169
+ # Bind parent port. That will trigger the binding of the
170
+ # trunk subports too, using the same host ID.
171
+ self ._bind_port (trunk ['port_id' ], 'host1' , host_dest = 'host2' )
172
+ self .mech_driver .set_port_status_up (trunk ['port_id' ])
173
+ self ._verify_trunk_info (new_trunk , has_items = True ,
174
+ host = 'host2' )
175
+
151
176
def test_subport_delete (self ):
152
177
with self .subport () as subport :
153
178
with self .trunk ([subport ]) as trunk :
0 commit comments