1414import time
1515from unittest import mock
1616
17+ from cinder import context
18+ from cinder .tests .unit import fake_constants
1719from cinder .tests .unit .scheduler import fakes
1820from cinder .tests .unit .scheduler .test_host_filters \
1921 import BackendFiltersTestCase
@@ -37,6 +39,8 @@ def setUp(self):
3739 }
3840 }
3941 }
42+ self .context = context .RequestContext (fake_constants .USER_ID ,
43+ fake_constants .PROJECT_ID )
4044
4145 @mock .patch ('cinder.scheduler.filters.shard_filter.'
4246 'ShardFilter._update_cache' )
@@ -77,7 +81,7 @@ def test_shard_project_not_found(self, mock_update_cache):
7781 host = fakes .FakeBackendState ('host1' ,
7882 {'capabilities' : caps ,
7983 'vendor_name' : VMWARE_VENDOR })
80- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
84+ self .backend_no_pass ( host , self .props )
8185
8286 def test_snapshot (self ):
8387 snap_props = {
@@ -90,7 +94,7 @@ def test_snapshot(self):
9094 host = fakes .FakeBackendState ('host1' ,
9195 {'capabilities' : caps ,
9296 'vendor_name' : VMWARE_VENDOR })
93- self .assertTrue ( self . filt_cls . backend_passes (host , snap_props ) )
97+ self .backend_passes (host , snap_props )
9498
9599 def test_snapshot_None (self ):
96100 snap_props = {
@@ -103,57 +107,57 @@ def test_snapshot_None(self):
103107 host = fakes .FakeBackendState ('host1' ,
104108 {'capabilities' : caps ,
105109 'vendor_name' : VMWARE_VENDOR })
106- self .assertFalse ( self . filt_cls . backend_passes ( host , snap_props ) )
110+ self .backend_no_pass ( host , snap_props )
107111
108112 def test_shard_project_no_shards (self ):
109113 caps = {'vcenter-shard' : 'vc-a-1' }
110114 self .filt_cls ._PROJECT_SHARD_CACHE ['foo' ] = []
111115 host = fakes .FakeBackendState ('host1' ,
112116 {'capabilities' : caps ,
113117 'vendor_name' : VMWARE_VENDOR })
114- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
118+ self .backend_no_pass ( host , self .props )
115119
116120 def test_backend_without_shard (self ):
117121 host = fakes .FakeBackendState ('host1' , {'vendor_name' : VMWARE_VENDOR })
118- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
122+ self .backend_no_pass ( host , self .props )
119123
120124 def test_backend_shards_dont_match (self ):
121125 caps = {'vcenter-shard' : 'vc-a-1' }
122126 host = fakes .FakeBackendState ('host1' ,
123127 {'capabilities' : caps ,
124128 'vendor_name' : VMWARE_VENDOR })
125- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
129+ self .backend_no_pass ( host , self .props )
126130
127131 def test_backend_shards_match (self ):
128132 caps = {'vcenter-shard' : 'vc-b-0' }
129133 host = fakes .FakeBackendState ('host1' ,
130134 {'capabilities' : caps ,
131135 'vendor_name' : VMWARE_VENDOR })
132- self .assertTrue ( self . filt_cls . backend_passes (host , self .props ) )
136+ self .backend_passes (host , self .props )
133137
134138 def test_shard_override_matches (self ):
135139 caps = {'vcenter-shard' : 'vc-a-1' }
136140 host = fakes .FakeBackendState ('host1' ,
137141 {'capabilities' : caps ,
138142 'vendor_name' : VMWARE_VENDOR })
139143 self .props ['scheduler_hints' ] = {'vcenter-shard' : 'vc-a-1' }
140- self .assertTrue ( self . filt_cls . backend_passes (host , self .props ) )
144+ self .backend_passes (host , self .props )
141145
142146 def test_shard_override_no_match (self ):
143147 caps = {'vcenter-shard' : 'vc-a-0' }
144148 host = fakes .FakeBackendState ('host1' ,
145149 {'capabilities' : caps ,
146150 'vendor_name' : VMWARE_VENDOR })
147151 self .props ['scheduler_hints' ] = {'vcenter-shard' : 'vc-a-1' }
148- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
152+ self .backend_no_pass ( host , self .props )
149153
150154 def test_shard_override_no_data (self ):
151155 caps = {'vcenter-shard' : 'vc-a-0' }
152156 host = fakes .FakeBackendState ('host1' ,
153157 {'capabilities' : caps ,
154158 'vendor_name' : VMWARE_VENDOR })
155159 self .props ['scheduler_hints' ] = {'vcenter-shard' : None }
156- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
160+ self .backend_no_pass ( host , self .props )
157161
158162 def test_sharding_enabled_any_backend_match (self ):
159163 self .filt_cls ._PROJECT_SHARD_CACHE ['baz' ] = ['sharding_enabled' ]
@@ -162,7 +166,7 @@ def test_sharding_enabled_any_backend_match(self):
162166 host = fakes .FakeBackendState ('host1' ,
163167 {'capabilities' : caps ,
164168 'vendor_name' : VMWARE_VENDOR })
165- self .assertTrue ( self . filt_cls . backend_passes (host , self .props ) )
169+ self .backend_passes (host , self .props )
166170
167171 def test_sharding_enabled_and_single_shard_any_backend_match (self ):
168172 self .filt_cls ._PROJECT_SHARD_CACHE ['baz' ] = ['sharding_enabled' ,
@@ -172,7 +176,7 @@ def test_sharding_enabled_and_single_shard_any_backend_match(self):
172176 host = fakes .FakeBackendState ('host1' ,
173177 {'capabilities' : caps ,
174178 'vendor_name' : VMWARE_VENDOR })
175- self .assertTrue ( self . filt_cls . backend_passes (host , self .props ) )
179+ self .backend_passes (host , self .props )
176180
177181 def test_scheduler_hints_override_sharding_enabled (self ):
178182 self .filt_cls ._PROJECT_SHARD_CACHE ['baz' ] = ['sharding_enabled' ]
@@ -182,12 +186,12 @@ def test_scheduler_hints_override_sharding_enabled(self):
182186 host = fakes .FakeBackendState ('host0' ,
183187 {'capabilities' : caps0 ,
184188 'vendor_name' : VMWARE_VENDOR })
185- self .assertFalse ( self . filt_cls . backend_passes ( host , self .props ) )
189+ self .backend_no_pass ( host , self .props )
186190 caps1 = {'vcenter-shard' : 'vc-a-1' }
187191 host = fakes .FakeBackendState ('host1' ,
188192 {'capabilities' : caps1 ,
189193 'vendor_name' : VMWARE_VENDOR })
190- self .assertTrue ( self . filt_cls . backend_passes (host , self .props ) )
194+ self .backend_passes (host , self .props )
191195
192196 def test_noop_for_find_backend_by_connector_with_hint (self ):
193197 """Check if we pass any backend
@@ -204,7 +208,7 @@ def test_noop_for_find_backend_by_connector_with_hint(self):
204208 'vendor_name' : VMWARE_VENDOR })
205209 self .props ['scheduler_hints' ] = {'vcenter-shard' : 'vc-a-1' }
206210 self .props ['request_spec' ]['operation' ] = 'find_backend_for_connector'
207- self .assertTrue ( self . filt_cls . backend_passes (host , self .props ) )
211+ self .backend_passes (host , self .props )
208212
209213 def test_noop_for_find_backend_by_connector_without_hint (self ):
210214 """Check if we pass any backend
@@ -221,4 +225,52 @@ def test_noop_for_find_backend_by_connector_without_hint(self):
221225 {'capabilities' : caps ,
222226 'vendor_name' : VMWARE_VENDOR })
223227 self .props ['request_spec' ]['operation' ] = 'find_backend_for_connector'
224- self .assertTrue (self .filt_cls .backend_passes (host , self .props ))
228+ self .backend_passes (host , self .props )
229+
230+ @mock .patch ('cinder.context.get_admin_context' )
231+ @mock .patch ('cinder.db.get_host_by_volume_metadata' )
232+ def test_same_shard_for_k8s_volumes (self , mock_get_hosts ,
233+ mock_get_context ):
234+ CSI_KEY = 'cinder.csi.openstack.org/cluster'
235+ all_backends = [
236+ fakes .FakeBackendState (
237+ 'volume-vc-a-0@backend#pool1' ,
238+ {'capabilities' : {'vcenter-shard' : 'vc-a-0' },
239+ 'vendor_name' : VMWARE_VENDOR }),
240+ fakes .FakeBackendState (
241+ 'volume-vc-a-1@backend#pool2' ,
242+ {'capabilities' : {'vcenter-shard' : 'vc-a-1' },
243+ 'vendor_name' : VMWARE_VENDOR }),
244+ ]
245+ mock_get_context .return_value = self .context
246+ fake_meta = {
247+ CSI_KEY : 'cluster-1' ,
248+ }
249+ mock_get_hosts .return_value = 'volume-vc-a-1'
250+ self .filt_cls ._PROJECT_SHARD_CACHE ['baz' ] = ['sharding_enabled' ,
251+ 'vc-a-1' ]
252+ filter_props = dict (self .props )
253+ filter_props ['request_spec' ]['volume_properties' ].update ({
254+ 'project_id' : 'baz' ,
255+ 'metadata' : fake_meta
256+ })
257+ filter_props ['request_spec' ]['resource_properties' ] = {
258+ 'availability_zone' : 'az-1'
259+ }
260+
261+ filtered = self .filt_cls .filter_all (all_backends , filter_props )
262+
263+ mock_get_hosts .assert_called_once_with (
264+ key = CSI_KEY , value = fake_meta [CSI_KEY ], filters = {
265+ 'availability_zone' : 'az-1'
266+ })
267+ self .assertEqual (len (filtered ), 1 )
268+ self .assertEqual ('volume-vc-a-1@backend#pool2' , filtered [0 ].host )
269+
270+ def backend_passes (self , backend , filter_properties ):
271+ filtered = self .filt_cls .filter_all ([backend ], filter_properties )
272+ self .assertEqual (backend , filtered [0 ])
273+
274+ def backend_no_pass (self , backend , filter_properties ):
275+ filtered = self .filt_cls .filter_all ([backend ], filter_properties )
276+ self .assertEqual (0 , len (filtered ))
0 commit comments