1 from __future__
import absolute_import
8 import unittest
.mock
as mock
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
16 mock_list_servers
= [{
17 'hostname': 'ceph-host',
18 'services': [{'id': 3, 'type': 'rbd-mirror'}]
24 'ceph_version': 'ceph version 13.0.0-5719 mimic (dev)'
30 'image_local_count': 5,
31 'image_remote_count': 6,
32 'image_error_count': 7,
33 'image_warning_count': 8,
38 mock_get_daemon_status
= {
39 'json': json
.dumps(_status
)
45 'application_metadata': {'rbd'}
50 class RbdMirroringControllerTest(ControllerTestCase
):
53 def setup_server(cls
):
54 cls
.setup_controllers([RbdMirroring
])
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
= \
63 self
._get
('/api/block/mirroring/site_name')
64 self
.assertStatus(200)
65 self
.assertJsonBody(result
)
67 result
['site_name'] = 'site-a'
68 mock_rbd_instance
.mirror_site_name_get
.return_value
= \
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'])
77 class RbdMirroringPoolBootstrapControllerTest(ControllerTestCase
):
80 def setup_server(cls
):
81 cls
.setup_controllers([RbdMirroringPoolBootstrap
])
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"
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")
93 mock_rbd_instance
.mirror_peer_bootstrap_create
.assert_called()
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
100 "direction": "invalid",
103 self
._post
('/api/block/mirroring/pool/abc/bootstrap/peer', values
)
104 self
.assertStatus(500)
105 mgr
.rados
.open_ioctx
.assert_called_with("abc")
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")
113 mock_rbd_instance
.mirror_peer_bootstrap_import
.assert_called_with(
114 mock
.ANY
, mock_rbd_module
.RBD_MIRROR_PEER_DIRECTION_RX
, '1234')
117 class RbdMirroringSummaryControllerTest(ControllerTestCase
):
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': []},
130 'dashboard': 'https://ceph.dev:11000/'
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) ' \
141 progress
.get_progress_tasks
= mock
.MagicMock()
142 progress
.get_progress_tasks
.return_value
= ([], [])
144 cls
.setup_controllers([RbdMirroringSummary
, Summary
], '/test')
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'
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'])
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'
166 has_perms_mock
.return_value
= True
167 self
._get
('/test/api/summary')
168 self
.assertStatus(200)
170 summary
= self
.json_body()['rbd_mirroring']
171 self
.assertEqual(summary
, {'errors': 0, 'warnings': 1})