]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/mgr/dashboard/test_osd.py
1 # -*- coding: utf-8 -*-
3 from __future__
import absolute_import
7 from .helper
import DashboardTestCase
, JObj
, JAny
, JList
, JLeaf
, JTuple
10 class OsdTest(DashboardTestCase
):
12 AUTH_ROLES
= ['cluster-manager']
16 super(OsdTest
, cls
).setUpClass()
17 cls
._load
_module
('test_orchestrator')
18 cmd
= ['orch', 'set', 'backend', 'test_orchestrator']
19 cls
.mgr_cluster
.mon_manager
.raw_cluster_cmd(*cmd
)
22 self
._post
('/api/osd/0/mark_in')
24 @DashboardTestCase.RunAs('test', 'test', ['block-manager'])
25 def test_access_permissions(self
):
27 self
.assertStatus(403)
28 self
._get
('/api/osd/0')
29 self
.assertStatus(403)
31 def assert_in_and_not_none(self
, data
, properties
):
32 self
.assertSchema(data
, JObj({p
: JAny(none
=False) for p
in properties
}, allow_unknown
=True))
35 data
= self
._get
('/api/osd')
36 self
.assertStatus(200)
38 self
.assertGreaterEqual(len(data
), 1)
40 self
.assert_in_and_not_none(data
, ['host', 'tree', 'state', 'stats', 'stats_history'])
41 self
.assert_in_and_not_none(data
['host'], ['name'])
42 self
.assert_in_and_not_none(data
['tree'], ['id'])
43 self
.assert_in_and_not_none(data
['stats'], ['numpg', 'stat_bytes_used', 'stat_bytes',
45 self
.assert_in_and_not_none(data
['stats_history'], ['op_out_bytes', 'op_in_bytes'])
46 self
.assertSchema(data
['stats_history']['op_out_bytes'],
47 JList(JTuple([JLeaf(float), JLeaf(float)])))
49 def test_details(self
):
50 data
= self
._get
('/api/osd/0')
51 self
.assertStatus(200)
52 self
.assert_in_and_not_none(data
, ['osd_metadata', 'histogram'])
53 self
.assert_in_and_not_none(data
['histogram'], ['osd'])
54 self
.assert_in_and_not_none(data
['histogram']['osd'], ['op_w_latency_in_bytes_histogram',
55 'op_r_latency_out_bytes_histogram'])
58 self
._post
('/api/osd/0/scrub?deep=False')
59 self
.assertStatus(200)
61 self
._post
('/api/osd/0/scrub?deep=True')
62 self
.assertStatus(200)
64 def test_safe_to_delete(self
):
65 data
= self
._get
('/api/osd/safe_to_delete?svc_ids=0')
66 self
.assertStatus(200)
67 self
.assertSchema(data
, JObj({
68 'is_safe_to_delete': JAny(none
=True),
71 self
.assertTrue(data
['is_safe_to_delete'])
73 def test_osd_smart(self
):
74 self
._get
('/api/osd/0/smart')
75 self
.assertStatus(200)
77 def test_mark_out_and_in(self
):
78 self
._post
('/api/osd/0/mark_out')
79 self
.assertStatus(200)
81 self
._post
('/api/osd/0/mark_in')
82 self
.assertStatus(200)
84 def test_mark_down(self
):
85 self
._post
('/api/osd/0/mark_down')
86 self
.assertStatus(200)
88 def test_reweight(self
):
89 self
._post
('/api/osd/0/reweight', {'weight': 0.4})
90 self
.assertStatus(200)
92 def get_reweight_value():
93 self
._get
('/api/osd/0')
94 response
= self
.jsonBody()
95 if 'osd_map' in response
and 'weight' in response
['osd_map']:
96 return round(response
['osd_map']['weight'], 1)
97 self
.wait_until_equal(get_reweight_value
, 0.4, 10)
98 self
.assertStatus(200)
101 self
._post
('/api/osd/0/reweight', {'weight': 1})
103 def test_create_lost_destroy_remove(self
):
105 self
._task
_post
('/api/osd', {
108 'uuid': 'f860ca2e-757d-48ce-b74a-87052cad563f',
111 'tracking_id': 'bare-5'
113 self
.assertStatus(201)
116 self
._task
_post
('/api/osd', {
119 'uuid': 'f860ca2e-757d-48ce-b74a-87052cad563f',
122 'tracking_id': 'bare-5'
124 self
.assertStatus(400)
127 self
._post
('/api/osd/5/mark_lost')
128 self
.assertStatus(200)
130 self
._post
('/api/osd/5/destroy')
131 self
.assertStatus(200)
133 self
._post
('/api/osd/5/purge')
134 self
.assertStatus(200)
136 def test_create_with_drive_group(self
):
138 'method': 'drive_groups',
141 'service_type': 'osd',
142 'service_id': 'test',
167 'tracking_id': 'test'
169 self
._post
('/api/osd', data
)
170 self
.assertStatus(201)
172 def test_safe_to_destroy(self
):
173 osd_dump
= json
.loads(self
._ceph
_cmd
(['osd', 'dump', '-f', 'json']))
174 max_id
= max(map(lambda e
: e
['osd'], osd_dump
['osds']))
176 def get_pg_status_equal_unknown(osd_ids
):
177 self
._get
('/api/osd/safe_to_destroy?ids={}'.format(osd_ids
))
178 if 'message' in self
.jsonBody():
179 return 'pgs have unknown state' in self
.jsonBody()['message']
182 # 1 OSD safe to destroy
183 unused_osd_id
= max_id
+ 10
184 self
.wait_until_equal(
185 lambda: get_pg_status_equal_unknown(unused_osd_id
), False, 30)
186 self
.assertStatus(200)
187 self
.assertJsonBody({
188 'is_safe_to_destroy': True,
191 'safe_to_destroy': [unused_osd_id
],
195 # multiple OSDs safe to destroy
196 unused_osd_ids
= [max_id
+ 11, max_id
+ 12]
197 self
.wait_until_equal(
198 lambda: get_pg_status_equal_unknown(str(unused_osd_ids
)), False, 30)
199 self
.assertStatus(200)
200 self
.assertJsonBody({
201 'is_safe_to_destroy': True,
204 'safe_to_destroy': unused_osd_ids
,
208 # 1 OSD unsafe to destroy
209 def get_destroy_status():
210 self
._get
('/api/osd/safe_to_destroy?ids=0')
211 if 'is_safe_to_destroy' in self
.jsonBody():
212 return self
.jsonBody()['is_safe_to_destroy']
214 self
.wait_until_equal(get_destroy_status
, False, 10)
215 self
.assertStatus(200)
217 def test_osd_devices(self
):
218 data
= self
._get
('/api/osd/0/devices')
219 self
.assertStatus(200)
220 self
.assertSchema(data
, JList(JObj({
221 'daemons': JList(str),
223 'location': JList(JObj({
231 class OsdFlagsTest(DashboardTestCase
):
232 def __init__(self
, *args
, **kwargs
):
233 super(OsdFlagsTest
, self
).__init
__(*args
, **kwargs
)
234 self
._initial
_flags
= sorted( # These flags cannot be unset
235 ['sortbitwise', 'recovery_deletes', 'purged_snapdirs',
239 def _get_cluster_osd_flags(cls
):
241 json
.loads(cls
._ceph
_cmd
(['osd', 'dump',
242 '--format=json']))['flags_set'])
245 def _put_flags(cls
, flags
):
246 cls
._put
('/api/osd/flags', data
={'flags': flags
})
247 return sorted(cls
._resp
.json())
249 def test_list_osd_flags(self
):
250 flags
= self
._get
('/api/osd/flags')
251 self
.assertStatus(200)
252 self
.assertEqual(len(flags
), 4)
253 self
.assertEqual(sorted(flags
), self
._initial
_flags
)
255 def test_add_osd_flag(self
):
256 flags
= self
._put
_flags
([
257 'sortbitwise', 'recovery_deletes', 'purged_snapdirs', 'noout',
258 'pause', 'pglog_hardlimit'
260 self
.assertEqual(flags
, sorted([
261 'sortbitwise', 'recovery_deletes', 'purged_snapdirs', 'noout',
262 'pause', 'pglog_hardlimit'
266 self
._put
_flags
(self
._initial
_flags
)