]>
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_mark_out_and_in(self
):
65 self
._post
('/api/osd/0/mark_out')
66 self
.assertStatus(200)
68 self
._post
('/api/osd/0/mark_in')
69 self
.assertStatus(200)
71 def test_mark_down(self
):
72 self
._post
('/api/osd/0/mark_down')
73 self
.assertStatus(200)
75 def test_reweight(self
):
76 self
._post
('/api/osd/0/reweight', {'weight': 0.4})
77 self
.assertStatus(200)
79 def get_reweight_value():
80 self
._get
('/api/osd/0')
81 response
= self
.jsonBody()
82 if 'osd_map' in response
and 'weight' in response
['osd_map']:
83 return round(response
['osd_map']['weight'], 1)
84 self
.wait_until_equal(get_reweight_value
, 0.4, 10)
85 self
.assertStatus(200)
88 self
._post
('/api/osd/0/reweight', {'weight': 1})
90 def test_create_lost_destroy_remove(self
):
92 self
._task
_post
('/api/osd', {
95 'uuid': 'f860ca2e-757d-48ce-b74a-87052cad563f',
98 'tracking_id': 'bare-5'
100 self
.assertStatus(201)
102 self
._post
('/api/osd/5/mark_lost')
103 self
.assertStatus(200)
105 self
._post
('/api/osd/5/destroy')
106 self
.assertStatus(200)
108 self
._post
('/api/osd/5/purge')
109 self
.assertStatus(200)
111 def test_create_with_drive_group(self
):
113 'method': 'drive_groups',
116 'service_type': 'osd',
117 'service_id': 'test',
142 'tracking_id': 'test'
144 self
._post
('/api/osd', data
)
145 self
.assertStatus(201)
147 def test_safe_to_destroy(self
):
148 osd_dump
= json
.loads(self
._ceph
_cmd
(['osd', 'dump', '-f', 'json']))
149 max_id
= max(map(lambda e
: e
['osd'], osd_dump
['osds']))
151 def get_pg_status_equal_unknown(osd_ids
):
152 self
._get
('/api/osd/safe_to_destroy?ids={}'.format(osd_ids
))
153 if 'message' in self
.jsonBody():
154 return 'pgs have unknown state' in self
.jsonBody()['message']
157 # 1 OSD safe to destroy
158 unused_osd_id
= max_id
+ 10
159 self
.wait_until_equal(
160 lambda: get_pg_status_equal_unknown(unused_osd_id
), False, 30)
161 self
.assertStatus(200)
162 self
.assertJsonBody({
163 'is_safe_to_destroy': True,
166 'safe_to_destroy': [unused_osd_id
],
170 # multiple OSDs safe to destroy
171 unused_osd_ids
= [max_id
+ 11, max_id
+ 12]
172 self
.wait_until_equal(
173 lambda: get_pg_status_equal_unknown(str(unused_osd_ids
)), False, 30)
174 self
.assertStatus(200)
175 self
.assertJsonBody({
176 'is_safe_to_destroy': True,
179 'safe_to_destroy': unused_osd_ids
,
183 # 1 OSD unsafe to destroy
184 def get_destroy_status():
185 self
._get
('/api/osd/safe_to_destroy?ids=0')
186 if 'is_safe_to_destroy' in self
.jsonBody():
187 return self
.jsonBody()['is_safe_to_destroy']
189 self
.wait_until_equal(get_destroy_status
, False, 10)
190 self
.assertStatus(200)
192 def test_osd_devices(self
):
193 data
= self
._get
('/api/osd/0/devices')
194 self
.assertStatus(200)
195 self
.assertSchema(data
, JList(JObj({
196 'daemons': JList(str),
198 'location': JList(JObj({
206 class OsdFlagsTest(DashboardTestCase
):
207 def __init__(self
, *args
, **kwargs
):
208 super(OsdFlagsTest
, self
).__init
__(*args
, **kwargs
)
209 self
._initial
_flags
= sorted( # These flags cannot be unset
210 ['sortbitwise', 'recovery_deletes', 'purged_snapdirs',
214 def _get_cluster_osd_flags(cls
):
216 json
.loads(cls
._ceph
_cmd
(['osd', 'dump',
217 '--format=json']))['flags_set'])
220 def _put_flags(cls
, flags
):
221 cls
._put
('/api/osd/flags', data
={'flags': flags
})
222 return sorted(cls
._resp
.json())
224 def test_list_osd_flags(self
):
225 flags
= self
._get
('/api/osd/flags')
226 self
.assertStatus(200)
227 self
.assertEqual(len(flags
), 4)
228 self
.assertEqual(sorted(flags
), self
._initial
_flags
)
230 def test_add_osd_flag(self
):
231 flags
= self
._put
_flags
([
232 'sortbitwise', 'recovery_deletes', 'purged_snapdirs', 'noout',
233 'pause', 'pglog_hardlimit'
235 self
.assertEqual(flags
, sorted([
236 'sortbitwise', 'recovery_deletes', 'purged_snapdirs', 'noout',
237 'pause', 'pglog_hardlimit'
241 self
._put
_flags
(self
._initial
_flags
)