14
14
15
15
import contextlib
16
16
17
- from neutron .services .trunk import plugin as trunk_plugin
18
- from neutron .tests .functional import base
17
+ from neutron_lib .api .definitions import portbindings
19
18
from neutron_lib import constants as n_consts
20
- from neutron_lib .objects import registry as obj_reg
19
+ from neutron_lib .db import api as db_api
21
20
from neutron_lib .plugins import utils
22
21
from neutron_lib .services .trunk import constants as trunk_consts
23
22
from oslo_utils import uuidutils
24
23
25
24
from neutron .common .ovn import constants as ovn_const
25
+ from neutron .objects import ports as port_obj
26
+ from neutron .services .trunk import plugin as trunk_plugin
27
+ from neutron .tests .functional import base
26
28
27
29
28
30
class TestOVNTrunkDriver (base .TestOVNFunctionalBase ):
29
31
30
- def setUp (self ):
31
- super (TestOVNTrunkDriver , self ).setUp ()
32
+ def setUp (self , ** kwargs ):
33
+ super ().setUp (** kwargs )
32
34
self .trunk_plugin = trunk_plugin .TrunkPlugin ()
33
35
self .trunk_plugin .add_segmentation_type (
34
36
trunk_consts .SEGMENTATION_TYPE_VLAN ,
@@ -39,7 +41,8 @@ def trunk(self, sub_ports=None):
39
41
sub_ports = sub_ports or []
40
42
with self .network () as network :
41
43
with self .subnet (network = network ) as subnet :
42
- with self .port (subnet = subnet ) as parent_port :
44
+ with self .port (subnet = subnet ,
45
+ device_owner = 'compute:nova' ) as parent_port :
43
46
tenant_id = uuidutils .generate_uuid ()
44
47
trunk = {'trunk' : {
45
48
'port_id' : parent_port ['port' ]['id' ],
@@ -64,17 +67,14 @@ def _get_ovn_trunk_info(self):
64
67
if row .parent_name and row .tag :
65
68
device_owner = row .external_ids [
66
69
ovn_const .OVN_DEVICE_OWNER_EXT_ID_KEY ]
67
- revision_number = row .external_ids [
68
- ovn_const .OVN_REV_NUM_EXT_ID_KEY ]
69
70
ovn_trunk_info .append ({'port_id' : row .name ,
70
71
'parent_port_id' : row .parent_name ,
71
72
'tag' : row .tag ,
72
73
'device_owner' : device_owner ,
73
- 'revision_number' : revision_number ,
74
74
})
75
75
return ovn_trunk_info
76
76
77
- def _verify_trunk_info (self , trunk , has_items ):
77
+ def _verify_trunk_info (self , trunk , has_items , host = '' ):
78
78
ovn_subports_info = self ._get_ovn_trunk_info ()
79
79
neutron_subports_info = []
80
80
for subport in trunk .get ('sub_ports' , []):
@@ -83,19 +83,27 @@ def _verify_trunk_info(self, trunk, has_items):
83
83
'parent_port_id' : [trunk ['port_id' ]],
84
84
'tag' : [subport ['segmentation_id' ]],
85
85
'device_owner' : trunk_consts .TRUNK_SUBPORT_OWNER ,
86
- 'revision_number' : '2' ,
87
86
})
88
- # Check that the subport has the binding is active.
89
- binding = obj_reg .load_class ('PortBinding' ).get_object (
90
- self .context , port_id = subport ['port_id' ], host = '' )
91
- self .assertEqual (n_consts .PORT_STATUS_ACTIVE , binding ['status' ])
87
+ # Check the subport binding.
88
+ pb = port_obj .PortBinding .get_object (
89
+ self .context , port_id = subport ['port_id' ], host = host )
90
+ self .assertEqual (n_consts .PORT_STATUS_ACTIVE , pb .status )
91
+ self .assertEqual (host , pb .host )
92
92
93
93
self .assertCountEqual (ovn_subports_info , neutron_subports_info )
94
94
self .assertEqual (has_items , len (neutron_subports_info ) != 0 )
95
95
96
96
if trunk .get ('status' ):
97
97
self .assertEqual (trunk_consts .TRUNK_ACTIVE_STATUS , trunk ['status' ])
98
98
99
+ def _bind_port (self , port_id , host ):
100
+ with db_api .CONTEXT_WRITER .using (self .context ):
101
+ pb = port_obj .PortBinding .get_object (self .context ,
102
+ port_id = port_id , host = '' )
103
+ pb .delete ()
104
+ port_obj .PortBinding (self .context , port_id = port_id , host = host ,
105
+ vif_type = portbindings .VIF_TYPE_OVS ).create ()
106
+
99
107
def test_trunk_create (self ):
100
108
with self .trunk () as trunk :
101
109
self ._verify_trunk_info (trunk , has_items = False )
@@ -113,10 +121,22 @@ def test_subport_add(self):
113
121
new_trunk = self .trunk_plugin .get_trunk (self .context ,
114
122
trunk ['id' ])
115
123
self ._verify_trunk_info (new_trunk , has_items = True )
124
+ # Bind parent port. That will trigger the binding of the
125
+ # trunk subports too, using the same host ID.
126
+ self ._bind_port (trunk ['port_id' ], 'host1' )
127
+ self .mech_driver .set_port_status_up (trunk ['port_id' ])
128
+ self ._verify_trunk_info (new_trunk , has_items = True ,
129
+ host = 'host1' )
116
130
117
131
def test_subport_delete (self ):
118
132
with self .subport () as subport :
119
133
with self .trunk ([subport ]) as trunk :
134
+ # Bind parent port.
135
+ self ._bind_port (trunk ['port_id' ], 'host1' )
136
+ self .mech_driver .set_port_status_up (trunk ['port_id' ])
137
+ self ._verify_trunk_info (trunk , has_items = True ,
138
+ host = 'host1' )
139
+
120
140
self .trunk_plugin .remove_subports (self .context , trunk ['id' ],
121
141
{'sub_ports' : [subport ]})
122
142
new_trunk = self .trunk_plugin .get_trunk (self .context ,
0 commit comments