]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/tests/test_osd_removal.py
3 from cephadm
.services
.osd
import OSDRemovalQueue
, OSD
6 from datetime
import datetime
11 def __init__(self
, osd_id
):
17 @pytest.mark
.parametrize(
18 "osd_id, osd_df, expected",
21 (1, dict(nodes
=[]), -1),
23 (1, dict(nodes
=[dict(id=1)]), -1),
25 (1, dict(nodes
=[dict(id=999, pgs
=1)]), -1),
27 (1, dict(nodes
=[dict(id=1, pgs
=1)]), 1),
30 def test_get_pg_count(self
, rm_util
, osd_id
, osd_df
, expected
):
31 with mock
.patch("cephadm.services.osd.RemoveUtil.osd_df", return_value
=osd_df
):
32 assert rm_util
.get_pg_count(osd_id
) == expected
34 @pytest.mark
.parametrize(
35 "osds, ok_to_stop, expected",
39 # all osds are ok_to_stop
40 ([1, 2], [True], [1, 2]),
41 # osds are ok_to_stop after the second iteration
42 ([1, 2], [False, True], [2]),
43 # osds are never ok_to_stop, (taking the sample size `(len(osd_ids))` into account),
44 # expected to get False
45 ([1, 2], [False, False], []),
48 def test_find_stop_threshold(self
, rm_util
, osds
, ok_to_stop
, expected
):
49 with mock
.patch("cephadm.services.osd.RemoveUtil.ok_to_stop", side_effect
=ok_to_stop
):
50 assert rm_util
.find_osd_stop_threshold(osds
) == expected
52 def test_process_removal_queue(self
, rm_util
):
54 # rm_util.process_removal_queue()
57 def test_ok_to_stop(self
, rm_util
):
58 rm_util
.ok_to_stop([MockOSD(1)])
59 rm_util
._run
_mon
_cmd
.assert_called_with({'prefix': 'osd ok-to-stop', 'ids': ['1']})
61 def test_safe_to_destroy(self
, rm_util
):
62 rm_util
.safe_to_destroy([1])
63 rm_util
._run
_mon
_cmd
.assert_called_with({'prefix': 'osd safe-to-destroy', 'ids': ['1']})
65 def test_destroy_osd(self
, rm_util
):
66 rm_util
.destroy_osd(1)
67 rm_util
._run
_mon
_cmd
.assert_called_with(
68 {'prefix': 'osd destroy-actual', 'id': 1, 'yes_i_really_mean_it': True})
70 def test_purge_osd(self
, rm_util
):
72 rm_util
._run
_mon
_cmd
.assert_called_with(
73 {'prefix': 'osd purge-actual', 'id': 1, 'yes_i_really_mean_it': True})
75 def test_load(self
, cephadm_module
, rm_util
):
85 "drain_started_at": "2020-09-14T11:41:53.960463",
86 "drain_stopped_at": None,
87 "drain_done_at": None,
88 "process_started_at": "2020-09-14T11:41:52.245832"
91 cephadm_module
.set_store('osd_remove_queue', data
)
92 cephadm_module
.to_remove_osds
.load_from_store()
94 expected
= OSDRemovalQueue(cephadm_module
)
95 expected
.osds
.add(OSD(osd_id
=35, remove_util
=rm_util
, draining
=True))
96 assert cephadm_module
.to_remove_osds
== expected
101 def test_start(self
, osd_obj
):
102 assert osd_obj
.started
is False
104 assert osd_obj
.started
is True
105 assert osd_obj
.stopped
is False
107 def test_start_draining_purge(self
, osd_obj
):
108 assert osd_obj
.draining
is False
109 assert osd_obj
.drain_started_at
is None
110 ret
= osd_obj
.start_draining()
111 osd_obj
.rm_util
.reweight_osd
.assert_called_with(osd_obj
, 0.0)
112 assert isinstance(osd_obj
.drain_started_at
, datetime
)
113 assert osd_obj
.draining
is True
114 assert osd_obj
.replace
is False
117 def test_start_draining_replace(self
, osd_obj
):
118 assert osd_obj
.draining
is False
119 assert osd_obj
.drain_started_at
is None
120 osd_obj
.replace
= True
121 ret
= osd_obj
.start_draining()
122 osd_obj
.rm_util
.set_osd_flag
.assert_called_with([osd_obj
], 'out')
123 assert isinstance(osd_obj
.drain_started_at
, datetime
)
124 assert osd_obj
.draining
is True
125 assert osd_obj
.replace
is True
128 def test_start_draining_stopped(self
, osd_obj
):
129 osd_obj
.stopped
= True
130 ret
= osd_obj
.start_draining()
131 assert osd_obj
.drain_started_at
is None
133 assert osd_obj
.draining
is False
135 def test_stop_draining_replace(self
, osd_obj
):
136 osd_obj
.replace
= True
137 ret
= osd_obj
.stop_draining()
138 osd_obj
.rm_util
.set_osd_flag
.assert_called_with([osd_obj
], 'in')
139 assert isinstance(osd_obj
.drain_stopped_at
, datetime
)
140 assert osd_obj
.draining
is False
143 def test_stop_draining_purge(self
, osd_obj
):
144 osd_obj
.original_weight
= 1.0
145 ret
= osd_obj
.stop_draining()
146 osd_obj
.rm_util
.reweight_osd
.assert_called_with(osd_obj
, 1.0)
147 assert isinstance(osd_obj
.drain_stopped_at
, datetime
)
148 assert osd_obj
.draining
is False
151 @mock.patch('cephadm.services.osd.OSD.stop_draining')
152 def test_stop(self
, stop_draining_mock
, osd_obj
):
154 assert osd_obj
.started
is False
155 assert osd_obj
.stopped
is True
156 stop_draining_mock
.assert_called_once()
158 @pytest.mark
.parametrize(
159 "draining, empty, expected",
161 # must be !draining! and !not empty! to yield True
162 (True, not True, True),
163 # not draining and not empty
164 (False, not True, False),
165 # not draining and empty
166 (False, True, False),
171 def test_is_draining(self
, osd_obj
, draining
, empty
, expected
):
172 with mock
.patch("cephadm.services.osd.OSD.is_empty", new_callable
=mock
.PropertyMock(return_value
=empty
)):
173 osd_obj
.draining
= draining
174 assert osd_obj
.is_draining
is expected
176 @mock.patch("cephadm.services.osd.RemoveUtil.ok_to_stop")
177 def test_is_ok_to_stop(self
, _
, osd_obj
):
178 osd_obj
.is_ok_to_stop
179 osd_obj
.rm_util
.ok_to_stop
.assert_called_once()
181 @pytest.mark
.parametrize(
182 "pg_count, expected",
190 def test_is_empty(self
, osd_obj
, pg_count
, expected
):
191 with mock
.patch("cephadm.services.osd.OSD.get_pg_count", return_value
=pg_count
):
192 assert osd_obj
.is_empty
is expected
194 @mock.patch("cephadm.services.osd.RemoveUtil.safe_to_destroy")
195 def test_safe_to_destroy(self
, _
, osd_obj
):
196 osd_obj
.safe_to_destroy()
197 osd_obj
.rm_util
.safe_to_destroy
.assert_called_once()
199 @mock.patch("cephadm.services.osd.RemoveUtil.set_osd_flag")
200 def test_down(self
, _
, osd_obj
):
202 osd_obj
.rm_util
.set_osd_flag
.assert_called_with([osd_obj
], 'down')
204 @mock.patch("cephadm.services.osd.RemoveUtil.destroy_osd")
205 def test_destroy_osd(self
, _
, osd_obj
):
207 osd_obj
.rm_util
.destroy_osd
.assert_called_once()
209 @mock.patch("cephadm.services.osd.RemoveUtil.purge_osd")
210 def test_purge(self
, _
, osd_obj
):
212 osd_obj
.rm_util
.purge_osd
.assert_called_once()
214 @mock.patch("cephadm.services.osd.RemoveUtil.get_pg_count")
215 def test_pg_count(self
, _
, osd_obj
):
216 osd_obj
.get_pg_count()
217 osd_obj
.rm_util
.get_pg_count
.assert_called_once()
219 def test_drain_status_human_not_started(self
, osd_obj
):
220 assert osd_obj
.drain_status_human() == 'not started'
222 def test_drain_status_human_started(self
, osd_obj
):
223 osd_obj
.started
= True
224 assert osd_obj
.drain_status_human() == 'started'
226 def test_drain_status_human_draining(self
, osd_obj
):
227 osd_obj
.started
= True
228 osd_obj
.draining
= True
229 assert osd_obj
.drain_status_human() == 'draining'
231 def test_drain_status_human_done(self
, osd_obj
):
232 osd_obj
.started
= True
233 osd_obj
.draining
= False
234 osd_obj
.drain_done_at
= datetime
.utcnow()
235 assert osd_obj
.drain_status_human() == 'done, waiting for purge'
238 class TestOSDRemovalQueue
:
240 def test_queue_size(self
, osd_obj
):
241 q
= OSDRemovalQueue(mock
.Mock())
242 assert q
.queue_size() == 0
244 assert q
.queue_size() == 1
246 @mock.patch("cephadm.services.osd.OSD.start")
247 @mock.patch("cephadm.services.osd.OSD.exists")
248 def test_enqueue(self
, exist
, start
, osd_obj
):
249 q
= OSDRemovalQueue(mock
.Mock())
251 osd_obj
.start
.assert_called_once()
253 @mock.patch("cephadm.services.osd.OSD.stop")
254 @mock.patch("cephadm.services.osd.OSD.exists")
255 def test_rm_raise(self
, exist
, stop
, osd_obj
):
256 q
= OSDRemovalQueue(mock
.Mock())
257 with pytest
.raises(KeyError):
259 osd_obj
.stop
.assert_called_once()
261 @mock.patch("cephadm.services.osd.OSD.stop")
262 @mock.patch("cephadm.services.osd.OSD.exists")
263 def test_rm(self
, exist
, stop
, osd_obj
):
264 q
= OSDRemovalQueue(mock
.Mock())
267 osd_obj
.stop
.assert_called_once()