Coverage for manila/tests/scheduler/test_host_manager.py: 99%
299 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2011 OpenStack, LLC
2# Copyright (c) 2015 Rushil Chugh
3# Copyright (c) 2015 Clinton Knight
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17"""
18Tests For HostManager
19"""
21import copy
22from unittest import mock
24import ddt
25from oslo_config import cfg
26from oslo_utils import timeutils
28from manila import context
29from manila import db
30from manila import exception
31from manila.scheduler.filters import base_host
32from manila.scheduler import host_manager
33from manila.scheduler import utils as scheduler_utils
34from manila import test
35from manila.tests.scheduler import fakes
36from manila import utils
39CONF = cfg.CONF
42class FakeFilterClass1(base_host.BaseHostFilter):
43 def host_passes(self, host_state, filter_properties):
44 pass
47class FakeFilterClass2(base_host.BaseHostFilter):
48 def host_passes(self, host_state, filter_properties):
49 pass
52@ddt.ddt
53class HostManagerTestCase(test.TestCase):
54 """Test case for HostManager class."""
56 def setUp(self):
57 super(HostManagerTestCase, self).setUp()
58 self.host_manager = host_manager.HostManager()
59 self.fake_hosts = [host_manager.HostState('fake_host%s' % x)
60 for x in range(1, 5)]
62 def test_choose_host_filters_not_found(self):
63 self.flags(scheduler_default_filters='FakeFilterClass3')
64 self.host_manager.filter_classes = [FakeFilterClass1,
65 FakeFilterClass2]
66 self.assertRaises(exception.SchedulerHostFilterNotFound,
67 self.host_manager._choose_host_filters, None)
69 def test_choose_host_filters(self):
70 self.flags(scheduler_default_filters=['FakeFilterClass2'])
71 self.host_manager.filter_classes = [FakeFilterClass1,
72 FakeFilterClass2]
74 # Test 'share' returns 1 correct function
75 filter_classes = self.host_manager._choose_host_filters(None)
76 self.assertEqual(1, len(filter_classes))
77 self.assertEqual('FakeFilterClass2', filter_classes[0].__name__)
79 def _verify_result(self, info, result):
80 for x in info['got_fprops']:
81 self.assertEqual(info['expected_fprops'], x)
82 self.assertEqual(set(info['expected_objs']), set(info['got_objs']))
83 self.assertEqual(set(info['got_objs']), set(result))
85 def test_get_filtered_hosts(self):
86 fake_properties = {'moo': 1, 'cow': 2}
87 info = {
88 'expected_objs': self.fake_hosts,
89 'expected_fprops': fake_properties,
90 }
91 with mock.patch.object(self.host_manager, '_choose_host_filters',
92 mock.Mock(return_value=[FakeFilterClass1])):
93 info['got_objs'] = []
94 info['got_fprops'] = []
96 def fake_filter_one(_self, obj, filter_props):
97 info['got_objs'].append(obj)
98 info['got_fprops'].append(filter_props)
99 return True
101 self.mock_object(FakeFilterClass1, '_filter_one', fake_filter_one)
102 result, last_filter = self.host_manager.get_filtered_hosts(
103 self.fake_hosts, fake_properties)
104 self._verify_result(info, result)
105 self.host_manager._choose_host_filters.assert_called_once_with(
106 mock.ANY)
108 def test_update_service_capabilities_for_shares(self):
109 service_states = self.host_manager.service_states
110 self.assertDictEqual(service_states, {})
111 host1_share_capabs = dict(free_capacity_gb=4321, timestamp=1)
112 host2_share_capabs = dict(free_capacity_gb=5432, timestamp=1)
113 host3_share_capabs = dict(free_capacity_gb=6543, timestamp=1)
114 service_name = 'share'
115 self.host_manager.update_service_capabilities(
116 service_name, 'host1', host1_share_capabs, 31337)
118 self.host_manager.update_service_capabilities(
119 service_name, 'host2', host2_share_capabs, 31338)
121 self.host_manager.update_service_capabilities(
122 service_name, 'host3', host3_share_capabs, 31339)
124 # Make sure dictionary isn't re-assigned
125 self.assertEqual(service_states, self.host_manager.service_states)
126 # Make sure original dictionary wasn't copied
127 self.assertEqual(1, host1_share_capabs['timestamp'])
129 host1_share_capabs['timestamp'] = 31337
130 host2_share_capabs['timestamp'] = 31338
131 host3_share_capabs['timestamp'] = 31339
133 expected = {
134 'host1': host1_share_capabs,
135 'host2': host2_share_capabs,
136 'host3': host3_share_capabs,
137 }
138 self.assertDictEqual(service_states, expected)
140 def test_get_all_host_states_share(self):
141 fake_context = context.RequestContext('user', 'project')
142 topic = CONF.share_topic
143 tmp_pools = copy.deepcopy(fakes.SHARE_SERVICES_WITH_POOLS)
144 tmp_enable_pools = tmp_pools[:-2]
145 self.mock_object(
146 db, 'service_get_all_by_topic',
147 mock.Mock(return_value=tmp_enable_pools))
148 self.mock_object(utils, 'service_is_up', mock.Mock(return_value=True))
150 with mock.patch.dict(self.host_manager.service_states,
151 fakes.SHARE_SERVICE_STATES_WITH_POOLS):
152 # Get service
153 self.host_manager.get_all_host_states_share(fake_context)
155 # Disabled one service
156 tmp_enable_pools.pop()
157 self.mock_object(
158 db, 'service_get_all_by_topic',
159 mock.Mock(return_value=tmp_enable_pools))
161 # Get service again
162 self.host_manager.get_all_host_states_share(fake_context)
163 host_state_map = self.host_manager.host_state_map
165 self.assertEqual(3, len(host_state_map))
166 # Check that service is up
167 for i in range(3):
168 share_node = fakes.SHARE_SERVICES_WITH_POOLS[i]
169 host = share_node['host']
170 self.assertEqual(share_node, host_state_map[host].service)
171 db.service_get_all_by_topic.assert_called_once_with(
172 fake_context, topic, consider_disabled=False)
174 def test_get_pools_no_pools(self):
175 fake_context = context.RequestContext('user', 'project')
176 self.mock_object(utils, 'service_is_up', mock.Mock(return_value=True))
177 self.mock_object(
178 db, 'service_get_all_by_topic',
179 mock.Mock(return_value=fakes.SHARE_SERVICES_NO_POOLS))
180 host_manager.LOG.warning = mock.Mock()
182 with mock.patch.dict(self.host_manager.service_states,
183 fakes.SERVICE_STATES_NO_POOLS):
185 res = self.host_manager.get_pools(context=fake_context)
187 expected = [
188 {
189 'name': 'host1#AAA',
190 'host': 'host1',
191 'backend': None,
192 'pool': 'AAA',
193 'capabilities': {
194 'timestamp': None,
195 'share_backend_name': 'AAA',
196 'free_capacity_gb': 200,
197 'driver_version': None,
198 'total_capacity_gb': 512,
199 'reserved_percentage': 0,
200 'reserved_snapshot_percentage': 0,
201 'reserved_share_extend_percentage': 0,
202 'provisioned_capacity_gb': 312,
203 'max_over_subscription_ratio': 1.0,
204 'thin_provisioning': False,
205 'vendor_name': None,
206 'storage_protocol': None,
207 'driver_handles_share_servers': False,
208 'snapshot_support': False,
209 'create_share_from_snapshot_support': False,
210 'revert_to_snapshot_support': True,
211 'mount_snapshot_support': True,
212 'dedupe': False,
213 'compression': False,
214 'replication_type': None,
215 'replication_domain': None,
216 'sg_consistent_snapshot_support': None,
217 'security_service_update_support': False,
218 'network_allocation_update_support': False,
219 'share_server_multiple_subnet_support': False,
220 'mount_point_name_support': False,
221 'share_replicas_migration_support': False,
222 'encryption_support': None
223 },
224 }, {
225 'name': 'host2@back1#BBB',
226 'host': 'host2',
227 'backend': 'back1',
228 'pool': 'BBB',
229 'capabilities': {
230 'timestamp': None,
231 'share_backend_name': 'BBB',
232 'free_capacity_gb': 100,
233 'driver_version': None,
234 'total_capacity_gb': 256,
235 'reserved_percentage': 0,
236 'reserved_snapshot_percentage': 0,
237 'reserved_share_extend_percentage': 0,
238 'provisioned_capacity_gb': 400,
239 'max_over_subscription_ratio': 2.0,
240 'thin_provisioning': True,
241 'vendor_name': None,
242 'storage_protocol': None,
243 'driver_handles_share_servers': False,
244 'snapshot_support': True,
245 'create_share_from_snapshot_support': True,
246 'revert_to_snapshot_support': False,
247 'mount_snapshot_support': False,
248 'dedupe': False,
249 'compression': False,
250 'replication_type': None,
251 'replication_domain': None,
252 'sg_consistent_snapshot_support': None,
253 'security_service_update_support': False,
254 'network_allocation_update_support': False,
255 'share_server_multiple_subnet_support': False,
256 'mount_point_name_support': False,
257 'share_replicas_migration_support': False,
258 'encryption_support': None
259 },
260 }, {
261 'name': 'host2@back2#CCC',
262 'host': 'host2',
263 'backend': 'back2',
264 'pool': 'CCC',
265 'capabilities': {
266 'timestamp': None,
267 'share_backend_name': 'CCC',
268 'free_capacity_gb': 700,
269 'driver_version': None,
270 'total_capacity_gb': 10000,
271 'reserved_percentage': 0,
272 'reserved_snapshot_percentage': 0,
273 'reserved_share_extend_percentage': 0,
274 'provisioned_capacity_gb': 50000,
275 'max_over_subscription_ratio': 20.0,
276 'thin_provisioning': True,
277 'vendor_name': None,
278 'storage_protocol': None,
279 'driver_handles_share_servers': False,
280 'snapshot_support': True,
281 'create_share_from_snapshot_support': True,
282 'revert_to_snapshot_support': False,
283 'mount_snapshot_support': False,
284 'dedupe': False,
285 'compression': False,
286 'replication_type': None,
287 'replication_domain': None,
288 'sg_consistent_snapshot_support': None,
289 'security_service_update_support': False,
290 'network_allocation_update_support': False,
291 'share_server_multiple_subnet_support': False,
292 'mount_point_name_support': False,
293 'share_replicas_migration_support': False,
294 'encryption_support': None
295 },
296 },
297 ]
298 self.assertIsInstance(res, list)
299 self.assertEqual(len(expected), len(res))
300 for pool in expected:
301 self.assertIn(pool, res)
303 def test_get_pools(self):
304 fake_context = context.RequestContext('user', 'project')
305 self.mock_object(utils, 'service_is_up', mock.Mock(return_value=True))
306 self.mock_object(
307 db, 'service_get_all_by_topic',
308 mock.Mock(return_value=fakes.SHARE_SERVICES_WITH_POOLS))
309 host_manager.LOG.warning = mock.Mock()
311 with mock.patch.dict(self.host_manager.service_states,
312 fakes.SHARE_SERVICE_STATES_WITH_POOLS):
314 res = self.host_manager.get_pools(fake_context)
316 expected = [
317 {
318 'name': 'host1@AAA#pool1',
319 'host': 'host1',
320 'backend': 'AAA',
321 'pool': 'pool1',
322 'capabilities': {
323 'pool_name': 'pool1',
324 'timestamp': None,
325 'share_backend_name': 'AAA',
326 'free_capacity_gb': 41,
327 'driver_version': None,
328 'total_capacity_gb': 51,
329 'reserved_percentage': 0,
330 'reserved_snapshot_percentage': 0,
331 'reserved_share_extend_percentage': 0,
332 'provisioned_capacity_gb': 10,
333 'max_over_subscription_ratio': 1.0,
334 'thin_provisioning': False,
335 'vendor_name': None,
336 'storage_protocol': None,
337 'driver_handles_share_servers': False,
338 'snapshot_support': True,
339 'create_share_from_snapshot_support': True,
340 'revert_to_snapshot_support': True,
341 'mount_snapshot_support': False,
342 'dedupe': False,
343 'compression': False,
344 'replication_type': None,
345 'replication_domain': None,
346 'sg_consistent_snapshot_support': None,
347 'security_service_update_support': False,
348 'network_allocation_update_support': False,
349 'share_server_multiple_subnet_support': False,
350 'mount_point_name_support': False,
351 'share_replicas_migration_support': False,
352 'encryption_support': None
353 },
354 }, {
355 'name': 'host2@BBB#pool2',
356 'host': 'host2',
357 'backend': 'BBB',
358 'pool': 'pool2',
359 'capabilities': {
360 'pool_name': 'pool2',
361 'timestamp': None,
362 'share_backend_name': 'BBB',
363 'free_capacity_gb': 42,
364 'driver_version': None,
365 'total_capacity_gb': 52,
366 'reserved_percentage': 0,
367 'reserved_snapshot_percentage': 0,
368 'reserved_share_extend_percentage': 0,
369 'provisioned_capacity_gb': 60,
370 'max_over_subscription_ratio': 2.0,
371 'thin_provisioning': True,
372 'vendor_name': None,
373 'storage_protocol': None,
374 'driver_handles_share_servers': False,
375 'snapshot_support': True,
376 'create_share_from_snapshot_support': True,
377 'revert_to_snapshot_support': False,
378 'mount_snapshot_support': False,
379 'dedupe': False,
380 'compression': False,
381 'replication_type': None,
382 'replication_domain': None,
383 'sg_consistent_snapshot_support': None,
384 'security_service_update_support': False,
385 'network_allocation_update_support': False,
386 'share_server_multiple_subnet_support': False,
387 'mount_point_name_support': False,
388 'share_replicas_migration_support': False,
389 'encryption_support': None
390 },
391 }, {
392 'name': 'host3@CCC#pool3',
393 'host': 'host3',
394 'backend': 'CCC',
395 'pool': 'pool3',
396 'capabilities': {
397 'pool_name': 'pool3',
398 'timestamp': None,
399 'share_backend_name': 'CCC',
400 'free_capacity_gb': 43,
401 'driver_version': None,
402 'total_capacity_gb': 53,
403 'reserved_percentage': 0,
404 'reserved_snapshot_percentage': 0,
405 'reserved_share_extend_percentage': 0,
406 'provisioned_capacity_gb': 100,
407 'max_over_subscription_ratio': 20.0,
408 'thin_provisioning': True,
409 'vendor_name': None,
410 'storage_protocol': None,
411 'driver_handles_share_servers': False,
412 'snapshot_support': True,
413 'create_share_from_snapshot_support': True,
414 'revert_to_snapshot_support': False,
415 'mount_snapshot_support': False,
416 'dedupe': False,
417 'compression': False,
418 'replication_type': None,
419 'replication_domain': None,
420 'sg_consistent_snapshot_support': None,
421 'security_service_update_support': False,
422 'network_allocation_update_support': False,
423 'share_server_multiple_subnet_support': False,
424 'mount_point_name_support': False,
425 'share_replicas_migration_support': False,
426 'encryption_support': None
427 },
428 }, {
429 'name': 'host4@DDD#pool4a',
430 'host': 'host4',
431 'backend': 'DDD',
432 'pool': 'pool4a',
433 'capabilities': {
434 'pool_name': 'pool4a',
435 'timestamp': None,
436 'share_backend_name': 'DDD',
437 'free_capacity_gb': 441,
438 'driver_version': None,
439 'total_capacity_gb': 541,
440 'reserved_percentage': 0,
441 'reserved_snapshot_percentage': 0,
442 'reserved_share_extend_percentage': 0,
443 'provisioned_capacity_gb': 800,
444 'max_over_subscription_ratio': 2.0,
445 'thin_provisioning': True,
446 'vendor_name': None,
447 'storage_protocol': None,
448 'driver_handles_share_servers': False,
449 'snapshot_support': True,
450 'create_share_from_snapshot_support': True,
451 'revert_to_snapshot_support': False,
452 'mount_snapshot_support': False,
453 'dedupe': False,
454 'compression': False,
455 'replication_type': None,
456 'replication_domain': None,
457 'sg_consistent_snapshot_support': None,
458 'security_service_update_support': False,
459 'network_allocation_update_support': False,
460 'share_server_multiple_subnet_support': False,
461 'mount_point_name_support': False,
462 'share_replicas_migration_support': False,
463 'encryption_support': None
464 },
465 }, {
466 'name': 'host4@DDD#pool4b',
467 'host': 'host4',
468 'backend': 'DDD',
469 'pool': 'pool4b',
470 'capabilities': {
471 'pool_name': 'pool4b',
472 'timestamp': None,
473 'share_backend_name': 'DDD',
474 'free_capacity_gb': 442,
475 'driver_version': None,
476 'total_capacity_gb': 542,
477 'reserved_percentage': 0,
478 'reserved_snapshot_percentage': 0,
479 'reserved_share_extend_percentage': 0,
480 'provisioned_capacity_gb': 2000,
481 'max_over_subscription_ratio': 10.0,
482 'thin_provisioning': True,
483 'vendor_name': None,
484 'storage_protocol': None,
485 'driver_handles_share_servers': False,
486 'snapshot_support': True,
487 'create_share_from_snapshot_support': True,
488 'revert_to_snapshot_support': False,
489 'mount_snapshot_support': False,
490 'dedupe': False,
491 'compression': False,
492 'replication_type': None,
493 'replication_domain': None,
494 'sg_consistent_snapshot_support': None,
495 'security_service_update_support': False,
496 'network_allocation_update_support': False,
497 'share_server_multiple_subnet_support': False,
498 'mount_point_name_support': False,
499 'share_replicas_migration_support': False,
500 'encryption_support': None,
501 },
502 },
503 ]
504 self.assertIsInstance(res, list)
505 self.assertIsInstance(self.host_manager.host_state_map, dict)
506 self.assertEqual(len(expected), len(res))
507 for pool in expected:
508 self.assertIn(pool, res)
510 def test_get_pools_host_down(self):
511 fake_context = context.RequestContext('user', 'project')
512 mock_service_is_up = self.mock_object(utils, 'service_is_up')
513 self.mock_object(
514 db, 'service_get_all_by_topic',
515 mock.Mock(return_value=fakes.SHARE_SERVICES_NO_POOLS))
516 host_manager.LOG.warning = mock.Mock()
518 with mock.patch.dict(self.host_manager.service_states,
519 fakes.SERVICE_STATES_NO_POOLS):
521 # Initialize host data with all services present
522 mock_service_is_up.side_effect = [True, True, True]
524 # Call once to update the host state map
525 self.host_manager.get_pools(fake_context)
527 self.assertEqual(len(fakes.SHARE_SERVICES_NO_POOLS),
528 len(self.host_manager.host_state_map))
530 # Then mock one host as down
531 mock_service_is_up.side_effect = [True, True, False]
533 res = self.host_manager.get_pools(fake_context)
535 expected = [
536 {
537 'name': 'host1#AAA',
538 'host': 'host1',
539 'backend': None,
540 'pool': 'AAA',
541 'capabilities': {
542 'timestamp': None,
543 'driver_handles_share_servers': False,
544 'snapshot_support': False,
545 'create_share_from_snapshot_support': False,
546 'revert_to_snapshot_support': True,
547 'mount_snapshot_support': True,
548 'share_backend_name': 'AAA',
549 'free_capacity_gb': 200,
550 'driver_version': None,
551 'total_capacity_gb': 512,
552 'reserved_percentage': 0,
553 'reserved_snapshot_percentage': 0,
554 'reserved_share_extend_percentage': 0,
555 'vendor_name': None,
556 'storage_protocol': None,
557 'provisioned_capacity_gb': 312,
558 'max_over_subscription_ratio': 1.0,
559 'thin_provisioning': False,
560 'dedupe': False,
561 'compression': False,
562 'replication_type': None,
563 'replication_domain': None,
564 'sg_consistent_snapshot_support': None,
565 'security_service_update_support': False,
566 'network_allocation_update_support': False,
567 'share_server_multiple_subnet_support': False,
568 'mount_point_name_support': False,
569 'share_replicas_migration_support': False,
570 'encryption_support': None
571 },
572 }, {
573 'name': 'host2@back1#BBB',
574 'host': 'host2',
575 'backend': 'back1',
576 'pool': 'BBB',
577 'capabilities': {
578 'timestamp': None,
579 'driver_handles_share_servers': False,
580 'snapshot_support': True,
581 'create_share_from_snapshot_support': True,
582 'revert_to_snapshot_support': False,
583 'mount_snapshot_support': False,
584 'share_backend_name': 'BBB',
585 'free_capacity_gb': 100,
586 'driver_version': None,
587 'total_capacity_gb': 256,
588 'reserved_percentage': 0,
589 'reserved_snapshot_percentage': 0,
590 'reserved_share_extend_percentage': 0,
591 'vendor_name': None,
592 'storage_protocol': None,
593 'provisioned_capacity_gb': 400,
594 'max_over_subscription_ratio': 2.0,
595 'thin_provisioning': True,
596 'dedupe': False,
597 'compression': False,
598 'replication_type': None,
599 'replication_domain': None,
600 'sg_consistent_snapshot_support': None,
601 'security_service_update_support': False,
602 'network_allocation_update_support': False,
603 'share_server_multiple_subnet_support': False,
604 'mount_point_name_support': False,
605 'share_replicas_migration_support': False,
606 'encryption_support': None
607 },
608 },
609 ]
610 self.assertIsInstance(res, list)
611 self.assertIsInstance(self.host_manager.host_state_map, dict)
612 self.assertEqual(len(expected), len(res))
613 self.assertEqual(len(expected),
614 len(self.host_manager.host_state_map))
615 for pool in expected:
616 self.assertIn(pool, res)
618 def test_get_pools_with_filters(self):
619 fake_context = context.RequestContext('user', 'project')
620 self.mock_object(utils, 'service_is_up', mock.Mock(return_value=True))
621 self.mock_object(
622 db, 'service_get_all_by_topic',
623 mock.Mock(return_value=fakes.SHARE_SERVICES_WITH_POOLS))
624 host_manager.LOG.warning = mock.Mock()
626 with mock.patch.dict(self.host_manager.service_states,
627 fakes.SHARE_SERVICE_STATES_WITH_POOLS):
629 res = self.host_manager.get_pools(
630 context=fake_context,
631 filters={'host': 'host2', 'pool': 'pool*',
632 'capabilities': {'dedupe': 'False'}})
634 expected = [
635 {
636 'name': 'host2@BBB#pool2',
637 'host': 'host2',
638 'backend': 'BBB',
639 'pool': 'pool2',
640 'capabilities': {
641 'pool_name': 'pool2',
642 'timestamp': None,
643 'driver_handles_share_servers': False,
644 'snapshot_support': True,
645 'create_share_from_snapshot_support': True,
646 'revert_to_snapshot_support': False,
647 'mount_snapshot_support': False,
648 'share_backend_name': 'BBB',
649 'free_capacity_gb': 42,
650 'driver_version': None,
651 'total_capacity_gb': 52,
652 'reserved_percentage': 0,
653 'reserved_snapshot_percentage': 0,
654 'reserved_share_extend_percentage': 0,
655 'provisioned_capacity_gb': 60,
656 'max_over_subscription_ratio': 2.0,
657 'thin_provisioning': True,
658 'vendor_name': None,
659 'storage_protocol': None,
660 'dedupe': False,
661 'compression': False,
662 'replication_type': None,
663 'replication_domain': None,
664 'sg_consistent_snapshot_support': None,
665 'security_service_update_support': False,
666 'network_allocation_update_support': False,
667 'share_server_multiple_subnet_support': False,
668 'mount_point_name_support': False,
669 'share_replicas_migration_support': False,
670 'encryption_support': None
671 },
672 },
673 ]
674 self.assertIsInstance(res, list)
675 self.assertEqual(len(expected), len(res))
676 for pool in expected:
677 self.assertIn(pool, res)
679 @ddt.data(
680 None,
681 {},
682 {'key1': 'value1'},
683 {'capabilities': {'dedupe': 'False'}},
684 {'capabilities': {'dedupe': '<is> False'}},
685 {'key1': 'value1', 'key2': 'value*'},
686 {'key1': '.*', 'key2': '.*'},
687 )
688 def test_passes_filters_true(self, filter):
690 data = {
691 'key1': 'value1',
692 'key2': 'value2',
693 'key3': 'value3',
694 'capabilities': {'dedupe': False},
695 }
696 self.assertTrue(self.host_manager._passes_filters(data, filter))
698 @ddt.data(
699 {'key1': 'value$'},
700 {'key4': 'value'},
701 {'capabilities': {'dedupe': 'True'}},
702 {'capabilities': {'dedupe': '<is> True'}},
703 {'key1': 'value1.+', 'key2': 'value*'},
704 )
705 def test_passes_filters_false(self, filter):
707 data = {
708 'key1': 'value1',
709 'key2': 'value2',
710 'key3': 'value3',
711 'capabilities': {'dedupe': False},
712 }
713 self.assertFalse(self.host_manager._passes_filters(data, filter))
716class HostStateTestCase(test.TestCase):
717 """Test case for HostState class."""
719 def test_update_from_share_capability_nopool(self):
720 fake_context = context.RequestContext('user', 'project', is_admin=True)
721 share_capability = {'total_capacity_gb': 0,
722 'free_capacity_gb': 100,
723 'reserved_percentage': 0,
724 'reserved_snapshot_percentage': 0,
725 'reserved_share_extend_percentage': 0,
726 'timestamp': None,
727 'ipv4_support': True,
728 'ipv6_support': False}
729 fake_host = host_manager.HostState('host1', share_capability)
730 self.assertIsNone(fake_host.free_capacity_gb)
732 fake_host.update_from_share_capability(share_capability,
733 context=fake_context)
734 # Backend level stats remain uninitialized
735 self.assertEqual(0, fake_host.total_capacity_gb)
736 self.assertIsNone(fake_host.free_capacity_gb)
737 self.assertTrue(fake_host.ipv4_support)
738 self.assertFalse(fake_host.ipv6_support)
739 # Pool stats has been updated
740 self.assertEqual(0, fake_host.pools['_pool0'].total_capacity_gb)
741 self.assertEqual(100, fake_host.pools['_pool0'].free_capacity_gb)
742 self.assertTrue(fake_host.pools['_pool0'].ipv4_support)
743 self.assertFalse(fake_host.pools['_pool0'].ipv6_support)
745 # Test update for existing host state
746 share_capability.update(dict(total_capacity_gb=1000))
747 fake_host.update_from_share_capability(share_capability,
748 context=fake_context)
749 self.assertEqual(1000, fake_host.pools['_pool0'].total_capacity_gb)
751 # Test update for existing host state with different backend name
752 share_capability.update(dict(share_backend_name='magic'))
753 fake_host.update_from_share_capability(share_capability,
754 context=fake_context)
755 self.assertEqual(1000, fake_host.pools['magic'].total_capacity_gb)
756 self.assertEqual(100, fake_host.pools['magic'].free_capacity_gb)
757 # 'pool0' becomes nonactive pool, and is deleted
758 self.assertRaises(KeyError, lambda: fake_host.pools['pool0'])
760 def test_update_from_share_capability_with_pools(self):
761 fake_context = context.RequestContext('user', 'project', is_admin=True)
762 fake_host = host_manager.HostState('host1#pool1')
763 self.assertIsNone(fake_host.free_capacity_gb)
764 capability = {
765 'share_backend_name': 'Backend1',
766 'vendor_name': 'OpenStack',
767 'driver_version': '1.1',
768 'storage_protocol': 'NFS_CIFS',
769 'ipv4_support': True,
770 'ipv6_support': False,
771 'pools': [
772 {'pool_name': 'pool1',
773 'total_capacity_gb': 500,
774 'free_capacity_gb': 230,
775 'allocated_capacity_gb': 270,
776 'qos': 'False',
777 'reserved_percentage': 0,
778 'reserved_snapshot_percentage': 0,
779 'reserved_share_extend_percentage': 0,
780 'dying_disks': 100,
781 'super_hero_1': 'spider-man',
782 'super_hero_2': 'flash',
783 'super_hero_3': 'neoncat',
784 },
785 {'pool_name': 'pool2',
786 'total_capacity_gb': 1024,
787 'free_capacity_gb': 1024,
788 'allocated_capacity_gb': 0,
789 'qos': 'False',
790 'reserved_percentage': 0,
791 'reserved_snapshot_percentage': 0,
792 'reserved_share_extend_percentage': 0,
793 'dying_disks': 200,
794 'super_hero_1': 'superman',
795 'super_hero_2': 'Hulk',
796 }
797 ],
798 'timestamp': None,
799 }
801 fake_host.update_from_share_capability(capability,
802 context=fake_context)
804 self.assertEqual('Backend1', fake_host.share_backend_name)
805 self.assertEqual('NFS_CIFS', fake_host.storage_protocol)
806 self.assertEqual('OpenStack', fake_host.vendor_name)
807 self.assertEqual('1.1', fake_host.driver_version)
808 self.assertTrue(fake_host.ipv4_support)
809 self.assertFalse(fake_host.ipv6_support)
811 # Backend level stats remain uninitialized
812 self.assertEqual(0, fake_host.total_capacity_gb)
813 self.assertIsNone(fake_host.free_capacity_gb)
814 # Pool stats has been updated
815 self.assertEqual(2, len(fake_host.pools))
817 self.assertEqual(500, fake_host.pools['pool1'].total_capacity_gb)
818 self.assertEqual(230, fake_host.pools['pool1'].free_capacity_gb)
819 self.assertTrue(fake_host.pools['pool1'].ipv4_support)
820 self.assertFalse(fake_host.pools['pool1'].ipv6_support)
821 self.assertEqual(1024, fake_host.pools['pool2'].total_capacity_gb)
822 self.assertEqual(1024, fake_host.pools['pool2'].free_capacity_gb)
823 self.assertTrue(fake_host.pools['pool2'].ipv4_support)
824 self.assertFalse(fake_host.pools['pool2'].ipv6_support)
826 capability = {
827 'share_backend_name': 'Backend1',
828 'vendor_name': 'OpenStack',
829 'driver_version': '1.0',
830 'storage_protocol': 'NFS_CIFS',
831 'pools': [
832 {'pool_name': 'pool3',
833 'total_capacity_gb': 10000,
834 'free_capacity_gb': 10000,
835 'allocated_capacity_gb': 0,
836 'qos': 'False',
837 'reserved_percentage': 0,
838 'reserved_snapshot_percentage': 0,
839 'reserved_share_extend_percentage': 0,
840 },
841 ],
842 'timestamp': None,
843 }
845 # test update HostState Record
846 fake_host.update_from_share_capability(capability,
847 context=fake_context)
849 self.assertEqual('1.0', fake_host.driver_version)
851 # Non-active pool stats has been removed
852 self.assertEqual(1, len(fake_host.pools))
854 self.assertRaises(KeyError, lambda: fake_host.pools['pool1'])
855 self.assertRaises(KeyError, lambda: fake_host.pools['pool2'])
857 self.assertEqual(10000, fake_host.pools['pool3'].total_capacity_gb)
858 self.assertEqual(10000, fake_host.pools['pool3'].free_capacity_gb)
860 def test_update_from_share_unknown_capability(self):
861 share_capability = {
862 'total_capacity_gb': 'unknown',
863 'free_capacity_gb': 'unknown',
864 'allocated_capacity_gb': 1,
865 'reserved_percentage': 0,
866 'reserved_snapshot_percentage': 0,
867 'reserved_share_extend_percentage': 0,
868 'timestamp': None
869 }
870 fake_context = context.RequestContext('user', 'project', is_admin=True)
871 fake_host = host_manager.HostState('host1#_pool0')
872 self.assertIsNone(fake_host.free_capacity_gb)
873 fake_host.update_from_share_capability(share_capability,
874 context=fake_context)
875 # Backend level stats remain uninitialized
876 self.assertEqual(fake_host.total_capacity_gb, 0)
877 self.assertIsNone(fake_host.free_capacity_gb)
878 # Pool stats has been updated
879 self.assertEqual(fake_host.pools['_pool0'].total_capacity_gb,
880 'unknown')
881 self.assertEqual(fake_host.pools['_pool0'].free_capacity_gb,
882 'unknown')
884 def test_consume_from_share_capability(self):
885 fake_context = context.RequestContext('user', 'project', is_admin=True)
886 share_size = 10
887 free_capacity = 100
888 provisioned_capacity_gb = 50
889 fake_share = {'id': 'foo', 'size': share_size}
890 share_capability = {
891 'total_capacity_gb': free_capacity * 2,
892 'free_capacity_gb': free_capacity,
893 'provisioned_capacity_gb': provisioned_capacity_gb,
894 'allocated_capacity_gb': provisioned_capacity_gb,
895 'reserved_percentage': 0,
896 'reserved_snapshot_percentage': 0,
897 'reserved_share_extend_percentage': 0,
898 'timestamp': None
899 }
900 fake_host = host_manager.PoolState('host1', share_capability, '_pool0')
902 fake_host.update_from_share_capability(share_capability,
903 context=fake_context)
904 fake_host.consume_from_share(fake_share)
905 self.assertEqual(fake_host.free_capacity_gb,
906 free_capacity - share_size)
907 self.assertEqual(fake_host.provisioned_capacity_gb,
908 provisioned_capacity_gb + share_size)
909 self.assertEqual(fake_host.allocated_capacity_gb,
910 provisioned_capacity_gb + share_size)
912 def test_consume_from_share_unknown_capability(self):
913 share_capability = {
914 'total_capacity_gb': 'unknown',
915 'free_capacity_gb': 'unknown',
916 'provisioned_capacity_gb': None,
917 'allocated_capacity_gb': 0,
918 'reserved_percentage': 0,
919 'reserved_snapshot_percentage': 0,
920 'reserved_share_extend_percentage': 0,
921 'timestamp': None
922 }
923 fake_context = context.RequestContext('user', 'project', is_admin=True)
924 fake_host = host_manager.PoolState('host1', share_capability, '_pool0')
925 share_size = 1000
926 fake_share = {'id': 'foo', 'size': share_size}
928 fake_host.update_from_share_capability(share_capability,
929 context=fake_context)
930 fake_host.consume_from_share(fake_share)
931 self.assertEqual(fake_host.total_capacity_gb, 'unknown')
932 self.assertEqual(fake_host.free_capacity_gb, 'unknown')
933 self.assertIsNone(fake_host.provisioned_capacity_gb)
934 self.assertEqual(fake_host.allocated_capacity_gb, share_size)
936 def test_consume_from_share_invalid_capacity(self):
937 fake_host = host_manager.PoolState('host1', {}, '_pool0')
938 fake_host.free_capacity_gb = 'invalid_foo_string'
939 fake_host.provisioned_capacity_gb = None
940 fake_host.allocated_capacity_gb = 0
941 fake_share = {'id': 'fake', 'size': 10}
943 self.assertRaises(exception.InvalidCapacity,
944 fake_host.consume_from_share, fake_share)
946 def test_repr(self):
948 capability = {
949 'share_backend_name': 'Backend1',
950 'vendor_name': 'OpenStack',
951 'driver_version': '1.0',
952 'storage_protocol': 'NFS_CIFS',
953 'total_capacity_gb': 20000,
954 'free_capacity_gb': 15000,
955 'allocated_capacity_gb': 5000,
956 'timestamp': None,
957 'reserved_percentage': 0,
958 'reserved_snapshot_percentage': 0,
959 'reserved_share_extend_percentage': 0,
960 }
961 fake_context = context.RequestContext('user', 'project', is_admin=True)
962 fake_host = host_manager.HostState('host1')
963 fake_host.update_from_share_capability(capability,
964 context=fake_context)
966 result = fake_host.__repr__()
967 expected = ("host: 'host1', free_capacity_gb: None, "
968 "pools: {'Backend1': host: 'host1#Backend1', "
969 "free_capacity_gb: 15000, pools: None}")
970 self.assertEqual(expected, result)
973@ddt.ddt
974class PoolStateTestCase(test.TestCase):
975 """Test case for HostState class."""
977 @ddt.data(
978 {
979 'share_capability':
980 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
981 'reserved_percentage': 0, 'timestamp': None,
982 'reserved_snapshot_percentage': 0,
983 'reserved_share_extend_percentage': 0,
984 'thin_provisioning': True,
985 'cap1': 'val1', 'cap2': 'val2'},
986 'instances':
987 [
988 {
989 'id': 1, 'host': 'host1',
990 'status': 'available',
991 'share_id': 11, 'size': 4,
992 'updated_at': timeutils.utcnow()
993 },
994 {
995 'id': 2, 'host': 'host1',
996 'status': 'available',
997 'share_id': 12, 'size': None,
998 'updated_at': timeutils.utcnow()
999 },
1000 ]
1001 },
1002 {
1003 'share_capability':
1004 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1005 'reserved_percentage': 0, 'timestamp': None,
1006 'reserved_snapshot_percentage': 0,
1007 'reserved_share_extend_percentage': 0,
1008 'thin_provisioning': False, 'cap1': 'val1', 'cap2': 'val2'},
1009 'instances':
1010 [
1011 {
1012 'id': 1, 'host': 'host1',
1013 'status': 'available',
1014 'share_id': 11, 'size': 1,
1015 'updated_at': timeutils.utcnow()
1016 },
1017 {
1018 'id': 2, 'host': 'host1',
1019 'status': 'available',
1020 'share_id': 12, 'size': None,
1021 'updated_at': timeutils.utcnow()
1022 },
1023 ]
1024 },
1025 {
1026 'share_capability':
1027 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1028 'reserved_percentage': 0, 'timestamp': None,
1029 'reserved_snapshot_percentage': 0,
1030 'reserved_share_extend_percentage': 0,
1031 'thin_provisioning': [False], 'cap1': 'val1', 'cap2': 'val2'},
1032 'instances':
1033 [
1034 {
1035 'id': 1, 'host': 'host1',
1036 'status': 'available',
1037 'share_id': 11, 'size': 1,
1038 'updated_at': timeutils.utcnow()
1039 },
1040 {
1041 'id': 2, 'host': 'host1',
1042 'status': 'available',
1043 'share_id': 12, 'size': None,
1044 'updated_at': timeutils.utcnow()
1045 },
1046 ]
1047 },
1048 {
1049 'share_capability':
1050 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1051 'reserved_percentage': 0, 'timestamp': None,
1052 'reserved_snapshot_percentage': 0,
1053 'reserved_share_extend_percentage': 0,
1054 'thin_provisioning': [True, False], 'cap1': 'val1',
1055 'cap2': 'val2'},
1056 'instances':
1057 [
1058 {
1059 'id': 1, 'host': 'host1',
1060 'status': 'available',
1061 'share_id': 11, 'size': 4,
1062 'updated_at': timeutils.utcnow()
1063 },
1064 {
1065 'id': 2, 'host': 'host1',
1066 'status': 'available',
1067 'share_id': 12, 'size': None,
1068 'updated_at': timeutils.utcnow()
1069 },
1070 ]
1071 },
1072 {
1073 'share_capability':
1074 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1075 'reserved_percentage': 0, 'timestamp': None,
1076 'reserved_snapshot_percentage': 0,
1077 'reserved_share_extend_percentage': 0,
1078 'cap1': 'val1', 'cap2': 'val2', 'ipv4_support': True,
1079 'ipv6_support': False},
1080 'instances': []
1081 },
1082 {
1083 'share_capability':
1084 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1085 'reserved_percentage': 0, 'timestamp': None,
1086 'reserved_snapshot_percentage': 0,
1087 'reserved_share_extend_percentage': 0,
1088 'thin_provisioning': True, 'cap1': 'val1', 'cap2': 'val2',
1089 'ipv4_support': True, 'ipv6_support': False},
1090 'instances': []
1091 },
1092 {
1093 'share_capability':
1094 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1095 'reserved_percentage': 0, 'timestamp': None,
1096 'reserved_snapshot_percentage': 0,
1097 'reserved_share_extend_percentage': 0,
1098 'thin_provisioning': [False], 'cap1': 'val1', 'cap2': 'val2',
1099 'ipv4_support': True, 'ipv6_support': False},
1100 'instances': []
1101 },
1102 {
1103 'share_capability':
1104 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1105 'reserved_percentage': 0, 'timestamp': None,
1106 'reserved_snapshot_percentage': 0,
1107 'reserved_share_extend_percentage': 0,
1108 'thin_provisioning': [True, False], 'cap1': 'val1',
1109 'cap2': 'val2', 'ipv4_support': True, 'ipv6_support': False},
1110 'instances': []
1111 },
1112 {
1113 'share_capability':
1114 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1115 'allocated_capacity_gb': 256, 'reserved_percentage': 0,
1116 'reserved_snapshot_percentage': 0,
1117 'reserved_share_extend_percentage': 0,
1118 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2',
1119 'ipv4_support': False, 'ipv6_support': True
1120 },
1121 'instances':
1122 [
1123 {
1124 'id': 1, 'host': 'host1',
1125 'status': 'available',
1126 'share_id': 11, 'size': 4,
1127 'updated_at': timeutils.utcnow()
1128 },
1129 ]
1130 },
1131 {
1132 'share_capability':
1133 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1134 'allocated_capacity_gb': 256, 'reserved_percentage': 0,
1135 'reserved_snapshot_percentage': 0,
1136 'reserved_share_extend_percentage': 0,
1137 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2',
1138 'ipv4_support': True, 'ipv6_support': True},
1139 'instances': []
1140 },
1141 {
1142 'share_capability':
1143 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1144 'provisioned_capacity_gb': 256, 'reserved_percentage': 0,
1145 'reserved_snapshot_percentage': 0,
1146 'reserved_share_extend_percentage': 0,
1147 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2',
1148 'ipv4_support': False, 'ipv6_support': False
1149 },
1150 'instances':
1151 [
1152 {
1153 'id': 1, 'host': 'host1',
1154 'status': 'available',
1155 'share_id': 11, 'size': 1,
1156 'updated_at': timeutils.utcnow()
1157 },
1158 ]
1159 },
1160 {
1161 'share_capability':
1162 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1163 'allocated_capacity_gb': 256, 'provisioned_capacity_gb': 1,
1164 'thin_provisioning': True, 'reserved_percentage': 0,
1165 'reserved_snapshot_percentage': 0,
1166 'reserved_share_extend_percentage': 0,
1167 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2'},
1168 'instances':
1169 [
1170 {
1171 'id': 1, 'host': 'host1',
1172 'status': 'available',
1173 'share_id': 11, 'size': 1,
1174 'updated_at': timeutils.utcnow()
1175 },
1176 ]
1177 },
1178 {
1179 'share_capability':
1180 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1181 'allocated_capacity_gb': 256, 'provisioned_capacity_gb': 1,
1182 'thin_provisioning': [False], 'reserved_percentage': 0,
1183 'reserved_snapshot_percentage': 0,
1184 'reserved_share_extend_percentage': 0,
1185 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2'},
1186 'instances':
1187 [
1188 {
1189 'id': 1, 'host': 'host1',
1190 'status': 'available',
1191 'share_id': 11, 'size': 1,
1192 'updated_at': timeutils.utcnow()
1193 },
1194 ]
1195 },
1196 {
1197 'share_capability':
1198 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1199 'allocated_capacity_gb': 256, 'provisioned_capacity_gb': 1,
1200 'thin_provisioning': [True, False], 'reserved_percentage': 0,
1201 'reserved_snapshot_percentage': 0,
1202 'reserved_share_extend_percentage': 0,
1203 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2'},
1204 'instances':
1205 [
1206 {
1207 'id': 1, 'host': 'host1',
1208 'status': 'available',
1209 'share_id': 11, 'size': 1,
1210 'updated_at': timeutils.utcnow()
1211 },
1212 ]
1213 },
1214 {
1215 'share_capability':
1216 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1217 'allocated_capacity_gb': 256, 'provisioned_capacity_gb': 256,
1218 'thin_provisioning': False, 'reserved_percentage': 0,
1219 'reserved_snapshot_percentage': 0,
1220 'reserved_share_extend_percentage': 0,
1221 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2'},
1222 'instances':
1223 [
1224 {
1225 'id': 1, 'host': 'host1',
1226 'status': 'available',
1227 'share_id': 11, 'size': 1,
1228 'updated_at': timeutils.utcnow()
1229 },
1230 ]
1231 },
1232 {
1233 'share_capability':
1234 {'total_capacity_gb': 1024, 'free_capacity_gb': 512,
1235 'allocated_capacity_gb': 256, 'provisioned_capacity_gb': 256,
1236 'thin_provisioning': [False], 'reserved_percentage': 0,
1237 'reserved_snapshot_percentage': 0,
1238 'reserved_share_extend_percentage': 0,
1239 'timestamp': None, 'cap1': 'val1', 'cap2': 'val2'},
1240 'instances':
1241 [
1242 {
1243 'id': 1, 'host': 'host1',
1244 'status': 'available',
1245 'share_id': 11, 'size': 1,
1246 'updated_at': timeutils.utcnow()
1247 },
1248 ]
1249 },
1250 )
1251 @ddt.unpack
1252 def test_update_from_share_capability(self, share_capability, instances):
1253 fake_context = context.RequestContext('user', 'project', is_admin=True)
1254 sizes = [instance['size'] or 0 for instance in instances]
1255 self.mock_object(
1256 db, 'share_instance_sizes_sum_by_host',
1257 mock.Mock(return_value=sum(sizes)))
1258 fake_pool = host_manager.PoolState('host1', None, 'pool0')
1259 self.assertIsNone(fake_pool.free_capacity_gb)
1261 fake_pool.update_from_share_capability(share_capability,
1262 context=fake_context)
1264 self.assertEqual('host1#pool0', fake_pool.host)
1265 self.assertEqual('pool0', fake_pool.pool_name)
1266 self.assertEqual(1024, fake_pool.total_capacity_gb)
1267 self.assertEqual(512, fake_pool.free_capacity_gb)
1268 self.assertDictEqual(share_capability, dict(fake_pool.capabilities))
1270 if 'thin_provisioning' in share_capability:
1271 thin_provisioned = scheduler_utils.thin_provisioning(
1272 share_capability['thin_provisioning'])
1273 else:
1274 thin_provisioned = False
1276 if thin_provisioned:
1277 self.assertEqual(thin_provisioned, fake_pool.thin_provisioning)
1278 if 'provisioned_capacity_gb' not in share_capability or (
1279 share_capability['provisioned_capacity_gb'] is None):
1280 db.share_instance_sizes_sum_by_host.assert_called_once_with(
1281 fake_context, fake_pool.host)
1282 if len(instances) > 0:
1283 self.assertEqual(4, fake_pool.provisioned_capacity_gb)
1284 else:
1285 self.assertEqual(0, fake_pool.provisioned_capacity_gb)
1286 else:
1287 self.assertFalse(db.share_instance_sizes_sum_by_host.called)
1288 self.assertEqual(share_capability['provisioned_capacity_gb'],
1289 fake_pool.provisioned_capacity_gb)
1290 else:
1291 self.assertFalse(fake_pool.thin_provisioning)
1292 self.assertFalse(db.share_instance_sizes_sum_by_host.called)
1293 if 'provisioned_capacity_gb' not in share_capability or (
1294 share_capability['provisioned_capacity_gb'] is None):
1295 self.assertIsNone(fake_pool.provisioned_capacity_gb)
1296 else:
1297 self.assertEqual(share_capability['provisioned_capacity_gb'],
1298 fake_pool.provisioned_capacity_gb)
1300 if 'allocated_capacity_gb' in share_capability:
1301 self.assertEqual(share_capability['allocated_capacity_gb'],
1302 fake_pool.allocated_capacity_gb)
1303 else:
1304 self.assertEqual(0, fake_pool.allocated_capacity_gb)
1306 if 'ipv4_support' in share_capability:
1307 self.assertEqual(share_capability['ipv4_support'],
1308 fake_pool.ipv4_support)
1309 if 'ipv6_support' in share_capability:
1310 self.assertEqual(share_capability['ipv6_support'],
1311 fake_pool.ipv6_support)