]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/tests/test_ceph_service.py
1 # -*- coding: utf-8 -*-
2 # pylint: disable=dangerous-default-value,too-many-public-methods
6 from contextlib
import contextmanager
7 from unittest
import mock
11 from ..services
.ceph_service
import CephService
14 class CephServiceTest(unittest
.TestCase
):
16 'pool_name': 'good_pool',
19 'pool_name': 'bad_pool',
26 self
.list_patch
= mock
.patch('dashboard.services.ceph_service.CephService.get_pool_list')
27 self
.list = self
.list_patch
.start()
28 self
.list.return_value
= self
.pools
30 self
.mgr_patch
= mock
.patch('dashboard.mgr.get')
31 self
.mgr
= self
.mgr_patch
.start()
32 self
.mgr
.return_value
= {
34 '1': {'active+clean': 16},
35 '2': {'creating+incomplete': 16},
38 self
.service
= CephService()
41 self
.list_patch
.stop()
44 def test_get_pool_by_attribute_with_match(self
):
45 self
.assertEqual(self
.service
.get_pool_by_attribute('pool', 1), self
.pools
[0])
46 self
.assertEqual(self
.service
.get_pool_by_attribute('pool_name', 'bad_pool'), self
.pools
[1])
48 def test_get_pool_by_attribute_without_a_match(self
):
49 self
.assertEqual(self
.service
.get_pool_by_attribute('pool', 3), None)
50 self
.assertEqual(self
.service
.get_pool_by_attribute('not_there', 'sth'), None)
52 def test_get_pool_by_attribute_matching_a_not_always_set_attribute(self
):
53 self
.assertEqual(self
.service
.get_pool_by_attribute('flaky', 'option_x'), self
.pools
[1])
55 @mock.patch('dashboard.mgr.rados.pool_reverse_lookup', return_value
='good_pool')
56 def test_get_pool_name_from_id_with_match(self
, _mock
):
57 self
.assertEqual(self
.service
.get_pool_name_from_id(1), 'good_pool')
59 @mock.patch('dashboard.mgr.rados.pool_reverse_lookup', return_value
=None)
60 def test_get_pool_name_from_id_without_match(self
, _mock
):
61 self
.assertEqual(self
.service
.get_pool_name_from_id(3), None)
63 def test_get_pool_pg_status(self
):
64 self
.assertEqual(self
.service
.get_pool_pg_status('good_pool'), {'active+clean': 16})
66 def test_get_pg_status_without_match(self
):
67 self
.assertEqual(self
.service
.get_pool_pg_status('no-pool'), {})
71 def mock_smart_data(data
):
72 devices
= [{'devid': devid
} for devid
in data
]
74 def _get_smart_data(d
):
75 return {d
['devid']: data
[d
['devid']]}
77 with mock
.patch
.object(CephService
, '_get_smart_data_by_device', side_effect
=_get_smart_data
), \
78 mock
.patch
.object(CephService
, 'get_devices_by_host', return_value
=devices
), \
79 mock
.patch
.object(CephService
, 'get_devices_by_daemon', return_value
=devices
):
83 @pytest.mark
.parametrize(
86 ('host', ('osd0',), 'from host osd0'),
87 ('daemon', ('osd', '1'), 'with ID 1')
90 def test_get_smart_data(caplog
, by
, args
, log
):
91 # pylint: disable=protected-access
93 'aaa': {'device': {'name': '/dev/sda'}},
94 'bbb': {'device': {'name': '/dev/sdb'}},
96 with
mock_smart_data(expected_data
):
97 smart_data
= getattr(CephService
, 'get_smart_data_by_{}'.format(by
))(*args
)
98 getattr(CephService
, 'get_devices_by_{}'.format(by
)).assert_called_with(*args
)
99 CephService
._get
_smart
_data
_by
_device
.assert_called()
100 assert smart_data
== expected_data
102 with caplog
.at_level(logging
.DEBUG
):
103 with
mock_smart_data([]):
104 smart_data
= getattr(CephService
, 'get_smart_data_by_{}'.format(by
))(*args
)
105 getattr(CephService
, 'get_devices_by_{}'.format(by
)).assert_called_with(*args
)
106 CephService
._get
_smart
_data
_by
_device
.assert_not_called()
107 assert smart_data
== {}
108 assert log
in caplog
.text
111 @mock.patch
.object(CephService
, 'send_command')
112 def test_get_smart_data_by_device(send_command
):
113 # pylint: disable=protected-access
114 device_id
= 'Hitachi_HUA72201_JPW9K0N20D22SE'
115 osd_tree_payload
= {'nodes':
117 {'name': 'osd.1', 'status': 'down'},
118 {'name': 'osd.2', 'status': 'up'},
119 {'name': 'osd.3', 'status': 'up'}
121 health_metrics_payload
= {device_id
: {'ata_apm': {'enabled': False}}}
122 side_effect
= [osd_tree_payload
, health_metrics_payload
]
124 # Daemons associated: 1 osd down, 2 osd up.
125 send_command
.side_effect
= side_effect
126 smart_data
= CephService
._get
_smart
_data
_by
_device
(
127 {'devid': device_id
, 'daemons': ['osd.1', 'osd.2', 'osd.3']})
128 assert smart_data
== health_metrics_payload
129 send_command
.assert_has_calls([mock
.call('mon', 'osd tree'),
130 mock
.call('osd', 'smart', '2', devid
=device_id
)])
132 # Daemons associated: 1 osd down.
133 send_command
.reset_mock()
134 send_command
.side_effect
= [osd_tree_payload
]
135 smart_data
= CephService
._get
_smart
_data
_by
_device
({'devid': device_id
, 'daemons': ['osd.1']})
136 assert smart_data
== {}
137 send_command
.assert_has_calls([mock
.call('mon', 'osd tree')])
139 # Daemons associated: 1 osd down, 1 mon.
140 send_command
.reset_mock()
141 send_command
.side_effect
= side_effect
142 smart_data
= CephService
._get
_smart
_data
_by
_device
(
143 {'devid': device_id
, 'daemons': ['osd.1', 'mon.1']})
144 assert smart_data
== health_metrics_payload
145 send_command
.assert_has_calls([mock
.call('mon', 'osd tree'),
146 mock
.call('mon', 'device query-daemon-health-metrics',
149 # Daemons associated: 1 mon.
150 send_command
.reset_mock()
151 send_command
.side_effect
= side_effect
152 smart_data
= CephService
._get
_smart
_data
_by
_device
({'devid': device_id
, 'daemons': ['mon.1']})
153 assert smart_data
== health_metrics_payload
154 send_command
.assert_has_calls([mock
.call('mon', 'osd tree'),
155 mock
.call('mon', 'device query-daemon-health-metrics',
158 # Daemons associated: 1 other (non-osd, non-mon).
159 send_command
.reset_mock()
160 send_command
.side_effect
= [osd_tree_payload
]
161 smart_data
= CephService
._get
_smart
_data
_by
_device
({'devid': device_id
, 'daemons': ['rgw.1']})
162 assert smart_data
== {}
163 send_command
.assert_has_calls([mock
.call('mon', 'osd tree')])
165 # Daemons associated: no daemons.
166 send_command
.reset_mock()
167 smart_data
= CephService
._get
_smart
_data
_by
_device
({'devid': device_id
, 'daemons': []})
168 assert smart_data
== {}
169 send_command
.assert_has_calls([])