]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/tests/test_rbd_mirroring.py
import ceph 16.2.7
[ceph.git] / ceph / src / pybind / mgr / dashboard / tests / test_rbd_mirroring.py
1 from __future__ import absolute_import
2
3 import json
4
5 try:
6 import mock
7 except ImportError:
8 import unittest.mock as mock
9
10 from .. import mgr
11 from ..controllers.rbd_mirroring import RbdMirroring, RbdMirroringPoolBootstrap, RbdMirroringSummary
12 from ..controllers.summary import Summary
13 from ..services import progress
14 from ..tests import ControllerTestCase
15
16 mock_list_servers = [{
17 'hostname': 'ceph-host',
18 'services': [{'id': 3, 'type': 'rbd-mirror'}]
19 }]
20
21 mock_get_metadata = {
22 'id': 1,
23 'instance_id': 3,
24 'ceph_version': 'ceph version 13.0.0-5719 mimic (dev)'
25 }
26
27 _status = {
28 1: {
29 'callouts': {},
30 'image_local_count': 5,
31 'image_remote_count': 6,
32 'image_error_count': 7,
33 'image_warning_count': 8,
34 'name': 'pool_name'
35 }
36 }
37
38 mock_get_daemon_status = {
39 'json': json.dumps(_status)
40 }
41
42 mock_osd_map = {
43 'pools': [{
44 'pool_name': 'rbd',
45 'application_metadata': {'rbd'}
46 }]
47 }
48
49
50 class RbdMirroringControllerTest(ControllerTestCase):
51
52 @classmethod
53 def setup_server(cls):
54 cls.setup_controllers([RbdMirroring])
55
56 @mock.patch('dashboard.controllers.rbd_mirroring.rbd.RBD')
57 def test_site_name(self, mock_rbd):
58 result = {'site_name': 'fsid'}
59 mock_rbd_instance = mock_rbd.return_value
60 mock_rbd_instance.mirror_site_name_get.return_value = \
61 result['site_name']
62
63 self._get('/api/block/mirroring/site_name')
64 self.assertStatus(200)
65 self.assertJsonBody(result)
66
67 result['site_name'] = 'site-a'
68 mock_rbd_instance.mirror_site_name_get.return_value = \
69 result['site_name']
70 self._put('/api/block/mirroring/site_name', result)
71 self.assertStatus(200)
72 self.assertJsonBody(result)
73 mock_rbd_instance.mirror_site_name_set.assert_called_with(
74 mock.ANY, result['site_name'])
75
76
77 class RbdMirroringPoolBootstrapControllerTest(ControllerTestCase):
78
79 @classmethod
80 def setup_server(cls):
81 cls.setup_controllers([RbdMirroringPoolBootstrap])
82
83 @mock.patch('dashboard.controllers.rbd_mirroring.rbd.RBD')
84 def test_token(self, mock_rbd):
85 mock_rbd_instance = mock_rbd.return_value
86 mock_rbd_instance.mirror_peer_bootstrap_create.return_value = "1234"
87
88 self._post('/api/block/mirroring/pool/abc/bootstrap/token')
89 self.assertStatus(200)
90 self.assertJsonBody({"token": "1234"})
91 mgr.rados.open_ioctx.assert_called_with("abc")
92
93 mock_rbd_instance.mirror_peer_bootstrap_create.assert_called()
94
95 @mock.patch('dashboard.controllers.rbd_mirroring.rbd')
96 def test_peer(self, mock_rbd_module):
97 mock_rbd_instance = mock_rbd_module.RBD.return_value
98
99 values = {
100 "direction": "invalid",
101 "token": "1234"
102 }
103 self._post('/api/block/mirroring/pool/abc/bootstrap/peer', values)
104 self.assertStatus(500)
105 mgr.rados.open_ioctx.assert_called_with("abc")
106
107 values["direction"] = "rx"
108 self._post('/api/block/mirroring/pool/abc/bootstrap/peer', values)
109 self.assertStatus(200)
110 self.assertJsonBody({})
111 mgr.rados.open_ioctx.assert_called_with("abc")
112
113 mock_rbd_instance.mirror_peer_bootstrap_import.assert_called_with(
114 mock.ANY, mock_rbd_module.RBD_MIRROR_PEER_DIRECTION_RX, '1234')
115
116
117 class RbdMirroringSummaryControllerTest(ControllerTestCase):
118
119 @classmethod
120 def setup_server(cls):
121 mgr.list_servers.return_value = mock_list_servers
122 mgr.get_metadata = mock.Mock(return_value=mock_get_metadata)
123 mgr.get_daemon_status.return_value = mock_get_daemon_status
124 mgr.get.side_effect = lambda key: {
125 'osd_map': mock_osd_map,
126 'health': {'json': '{"status": 1}'},
127 'fs_map': {'filesystems': []},
128 'mgr_map': {
129 'services': {
130 'dashboard': 'https://ceph.dev:11000/'
131 },
132 }
133 }[key]
134 mgr.url_prefix = ''
135 mgr.get_mgr_id.return_value = 0
136 mgr.have_mon_connection.return_value = True
137 mgr.version = 'ceph version 13.1.0-534-g23d3751b89 ' \
138 '(23d3751b897b31d2bda57aeaf01acb5ff3c4a9cd) ' \
139 'nautilus (dev)'
140
141 progress.get_progress_tasks = mock.MagicMock()
142 progress.get_progress_tasks.return_value = ([], [])
143
144 cls.setup_controllers([RbdMirroringSummary, Summary], '/test')
145
146 @mock.patch('dashboard.controllers.rbd_mirroring.rbd.RBD')
147 def test_default(self, mock_rbd):
148 mock_rbd_instance = mock_rbd.return_value
149 mock_rbd_instance.mirror_site_name_get.return_value = 'site-a'
150
151 self._get('/test/api/block/mirroring/summary')
152 result = self.json_body()
153 self.assertStatus(200)
154 self.assertEqual(result['site_name'], 'site-a')
155 self.assertEqual(result['status'], 0)
156 for k in ['daemons', 'pools', 'image_error', 'image_syncing', 'image_ready']:
157 self.assertIn(k, result['content_data'])
158
159 @mock.patch('dashboard.controllers.BaseController._has_permissions')
160 @mock.patch('dashboard.controllers.rbd_mirroring.rbd.RBD')
161 def test_summary(self, mock_rbd, has_perms_mock):
162 """We're also testing `summary`, as it also uses code from `rbd_mirroring.py`"""
163 mock_rbd_instance = mock_rbd.return_value
164 mock_rbd_instance.mirror_site_name_get.return_value = 'site-a'
165
166 has_perms_mock.return_value = True
167 self._get('/test/api/summary')
168 self.assertStatus(200)
169
170 summary = self.json_body()['rbd_mirroring']
171 self.assertEqual(summary, {'errors': 0, 'warnings': 1})