Coverage for manila/tests/api/v2/test_share_servers.py: 100%
534 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright 2019 NetApp, Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
16from unittest import mock
18import ddt
19import webob
21from manila.api import common
22from manila.api.v2 import share_servers
23from manila.common import constants
24from manila import context as ctx_api
25from manila.db import api as db_api
26from manila import exception
27from manila import policy
28from manila.share import api as share_api
29from manila import test
30from manila.tests.api import fakes
31from manila.tests import db_utils
32from manila import utils
35@ddt.ddt
36class ShareServerControllerTest(test.TestCase):
37 """Share server api test"""
39 def setUp(self):
40 super(ShareServerControllerTest, self).setUp()
41 self.mock_policy_check = self.mock_object(
42 policy, 'check_policy', mock.Mock(return_value=True))
43 self.controller = share_servers.ShareServerController()
44 self.resource_name = self.controller.resource_name
46 @ddt.data(constants.STATUS_ACTIVE, constants.STATUS_ERROR,
47 constants.STATUS_DELETING, constants.STATUS_CREATING,
48 constants.STATUS_MANAGING, constants.STATUS_UNMANAGING,
49 constants.STATUS_UNMANAGE_ERROR, constants.STATUS_MANAGE_ERROR)
50 def test_share_server_reset_status(self, status):
51 req = fakes.HTTPRequest.blank('/v2/share-servers/fake-share-server/',
52 use_admin_context=True,
53 version="2.49")
54 body = {'reset_status': {'status': status}}
56 context = req.environ['manila.context']
57 self.mock_object(self.controller, '_get', mock.Mock(
58 return_value={'share_server': 'object'}))
59 mock_update = self.mock_object(db_api, 'share_server_update')
61 result = self.controller.share_server_reset_status(
62 req, 'fake_server_id', body)
64 self.assertEqual(202, result.status_int)
65 policy.check_policy.assert_has_calls([
66 mock.call(context, self.resource_name, 'reset_status'),
67 mock.call(context,
68 self.resource_name,
69 'reset_status',
70 target_obj={'share_server': 'object'}),
71 ])
73 mock_update.assert_called_once_with(
74 context, 'fake_server_id', {'status': status})
76 def test_share_reset_server_status_invalid(self):
77 req = fakes.HTTPRequest.blank('/reset_status', use_admin_context=True,
78 version="2.49")
79 body = {'reset_status': {'status': constants.STATUS_EXTENDING}}
80 context = req.environ['manila.context']
82 self.assertRaises(
83 webob.exc.HTTPBadRequest,
84 self.controller.share_server_reset_status,
85 req, id='fake_server_id', body=body)
86 policy.check_policy.assert_called_once_with(
87 context, self.resource_name, 'reset_status')
89 def test_share_server_reset_status_no_body(self):
90 req = fakes.HTTPRequest.blank('/reset_status', use_admin_context=True,
91 version="2.49")
92 context = req.environ['manila.context']
94 self.assertRaises(
95 webob.exc.HTTPBadRequest,
96 self.controller.share_server_reset_status,
97 req, id='fake_server_id', body={})
98 policy.check_policy.assert_called_once_with(
99 context, self.resource_name, 'reset_status')
101 def test_share_server_reset_status_no_status(self):
102 req = fakes.HTTPRequest.blank('/reset_status', use_admin_context=True,
103 version="2.49")
104 context = req.environ['manila.context']
106 self.assertRaises(
107 webob.exc.HTTPBadRequest,
108 self.controller.share_server_reset_status,
109 req, id='fake_server_id', body={'reset_status': {}})
110 policy.check_policy.assert_called_once_with(
111 context, self.resource_name, 'reset_status')
113 def _setup_manage_test_request_body(self):
114 body = {
115 'share_network_id': 'fake_net_id',
116 'share_network_subnet_id': 'fake_subnet_id',
117 'host': 'fake_host',
118 'identifier': 'fake_identifier',
119 'driver_options': {'opt1': 'fake_opt1', 'opt2': 'fake_opt2'},
120 }
121 return body
123 @ddt.data('fake_net_name', '')
124 def test_manage(self, share_net_name):
125 """Tests share server manage"""
126 req = fakes.HTTPRequest.blank('/v2/share-servers/',
127 use_admin_context=True,
128 version="2.49")
129 context = req.environ['manila.context']
130 share_network = db_utils.create_share_network(name=share_net_name)
131 share_net_subnet = [db_utils.create_share_network_subnet(
132 share_network_id=share_network['id'])]
133 share_server = db_utils.create_share_server(
134 share_network_subnet_id=share_net_subnet[0]['id'],
135 host='fake_host',
136 identifier='fake_identifier',
137 is_auto_deletable=False,
138 share_network_subnets=share_net_subnet)
140 self.mock_object(db_api, 'share_network_get', mock.Mock(
141 return_value=share_network))
142 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
143 mock.Mock(return_value=share_net_subnet))
144 self.mock_object(utils, 'validate_service_host')
146 body = {
147 'share_server': self._setup_manage_test_request_body()
148 }
150 manage_share_server_mock = self.mock_object(
151 share_api.API, 'manage_share_server',
152 mock.Mock(return_value=share_server))
154 result = self.controller.manage(req, body)
155 expected_result = {
156 'share_server': {
157 'id': share_server['id'],
158 'project_id': 'fake',
159 'updated_at': share_server['updated_at'],
160 'status': constants.STATUS_ACTIVE,
161 'host': 'fake_host',
162 'share_network_id':
163 (share_server['share_network_subnets'][0]
164 ['share_network_id']),
165 'created_at': share_server['created_at'],
166 'backend_details': {},
167 'identifier': share_server['identifier'],
168 'is_auto_deletable': share_server['is_auto_deletable'],
169 }
170 }
171 if share_net_name != '':
172 expected_result['share_server']['share_network_name'] = (
173 'fake_net_name')
174 else:
175 expected_result['share_server']['share_network_name'] = (
176 share_net_subnet[0]['share_network_id'])
178 req_params = body['share_server']
179 manage_share_server_mock.assert_called_once_with(
180 context, req_params['identifier'], req_params['host'],
181 share_net_subnet[0], req_params['driver_options'])
183 self.assertEqual(expected_result, result)
185 self.mock_policy_check.assert_called_once_with(
186 context, self.resource_name, 'manage_share_server')
188 def test_manage_invalid(self):
189 req = fakes.HTTPRequest.blank('/manage_share_server',
190 use_admin_context=True, version="2.49")
191 share_network = db_utils.create_share_network()
192 share_net_subnet = [db_utils.create_share_network_subnet(
193 share_network_id=share_network['id'])]
195 body = {
196 'share_server': self._setup_manage_test_request_body()
197 }
198 body['share_server']['driver_options'] = []
199 self.mock_object(utils, 'validate_service_host')
200 self.mock_object(db_api, 'share_network_get',
201 mock.Mock(return_value=share_network))
202 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
203 mock.Mock(return_value=share_net_subnet))
205 self.assertRaises(webob.exc.HTTPBadRequest,
206 self.controller.manage, req, body)
208 def test_manage_forbidden(self):
209 """Tests share server manage without admin privileges"""
210 req = fakes.HTTPRequest.blank('/manage_share_server', version="2.49")
211 error = mock.Mock(side_effect=exception.PolicyNotAuthorized(action=''))
212 self.mock_object(share_api.API, 'manage_share_server', error)
214 share_network = db_utils.create_share_network()
215 share_net_subnet = [db_utils.create_share_network_subnet(
216 share_network_id=share_network['id'])]
218 self.mock_object(db_api, 'share_network_get', mock.Mock(
219 return_value=share_network))
220 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
221 mock.Mock(return_value=share_net_subnet))
222 self.mock_object(utils, 'validate_service_host')
224 body = {
225 'share_server': self._setup_manage_test_request_body()
226 }
228 self.assertRaises(webob.exc.HTTPForbidden,
229 self.controller.manage,
230 req,
231 body)
233 def test__validate_manage_share_server_validate_no_body(self):
234 """Tests share server manage"""
235 req = fakes.HTTPRequest.blank('/manage', version="2.49")
236 body = {}
238 self.assertRaises(webob.exc.HTTPUnprocessableEntity,
239 self.controller.manage,
240 req,
241 body)
243 @ddt.data({'empty': False, 'key': 'host'},
244 {'empty': False, 'key': 'share_network_id'},
245 {'empty': False, 'key': 'identifier'},
246 {'empty': True, 'key': 'host'},
247 {'empty': True, 'key': 'share_network_id'},
248 {'empty': True, 'key': 'identifier'})
249 @ddt.unpack
250 def test__validate_manage_share_server_validate_without_parameters(
251 self, empty, key):
252 """Tests share server manage without some parameters"""
253 req = fakes.HTTPRequest.blank('/manage_share_server', version="2.49")
254 self.mock_object(share_api.API, 'manage_share_server', mock.Mock())
256 body = {
257 'share_server': self._setup_manage_test_request_body(),
258 }
260 if empty:
261 body['share_server'][key] = None
262 else:
263 body['share_server'].pop(key)
265 self.assertRaises(webob.exc.HTTPBadRequest,
266 self.controller.manage,
267 req,
268 body)
270 @ddt.data(
271 (webob.exc.HTTPBadRequest, exception.ServiceNotFound('foobar')),
272 (webob.exc.HTTPBadRequest, exception.ServiceIsDown('foobar')),
273 (webob.exc.HTTPForbidden, exception.PolicyNotAuthorized('foobar')),
274 (webob.exc.HTTPForbidden, exception.AdminRequired())
275 )
276 @ddt.unpack
277 def test__validate_manage_share_server_validate_service_host(
278 self, exception_to_raise, side_effect_exception):
279 req = fakes.HTTPRequest.blank('/manage', version="2.49")
280 context = req.environ['manila.context']
281 error = mock.Mock(side_effect=side_effect_exception)
282 self.mock_object(utils, 'validate_service_host', error)
284 share_network = db_utils.create_share_network()
285 share_net_subnet = [db_utils.create_share_network_subnet(
286 share_network_id=share_network['id'])]
288 self.mock_object(db_api, 'share_network_get', mock.Mock(
289 return_value=share_network))
290 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
291 mock.Mock(return_value=share_net_subnet))
292 self.mock_object(common, 'check_share_network_is_active',
293 mock.Mock(return_value=True))
295 self.assertRaises(
296 exception_to_raise, self.controller.manage, req,
297 {'share_server': self._setup_manage_test_request_body()})
299 common.check_share_network_is_active.assert_called_once_with(
300 share_net_subnet[0]['share_network'])
301 policy.check_policy.assert_called_once_with(
302 context, self.resource_name, 'manage_share_server')
304 def test__validate_manage_share_network_not_active(self):
305 req = fakes.HTTPRequest.blank('/manage', version="2.49")
306 context = req.environ['manila.context']
308 share_network = db_utils.create_share_network()
309 share_net_subnet = [db_utils.create_share_network_subnet(
310 share_network_id=share_network['id'])]
312 self.mock_object(db_api, 'share_network_get', mock.Mock(
313 return_value=share_network))
314 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
315 mock.Mock(return_value=share_net_subnet))
316 self.mock_object(utils, 'validate_service_host')
317 self.mock_object(common, 'check_share_network_is_active',
318 mock.Mock(side_effect=webob.exc.HTTPBadRequest()))
320 self.assertRaises(
321 webob.exc.HTTPBadRequest, self.controller.manage, req,
322 {'share_server': self._setup_manage_test_request_body()})
324 common.check_share_network_is_active.assert_called_once_with(
325 share_net_subnet[0]['share_network'])
326 policy.check_policy.assert_called_once_with(
327 context, self.resource_name, 'manage_share_server')
329 def test__validate_manage_share_server_share_network_not_found(self):
330 req = fakes.HTTPRequest.blank('/manage', version="2.49")
331 context = req.environ['manila.context']
332 self.mock_object(utils, 'validate_service_host')
333 error = mock.Mock(
334 side_effect=exception.ShareNetworkNotFound(share_network_id="foo"))
335 self.mock_object(db_api, 'share_network_get', error)
336 body = self._setup_manage_test_request_body()
338 self.assertRaises(webob.exc.HTTPBadRequest,
339 self.controller.manage,
340 req,
341 {'share_server': body})
343 policy.check_policy.assert_called_once_with(
344 context, self.resource_name, 'manage_share_server')
346 def test__validate_manage_share_server_driver_opts_not_instance_dict(self):
347 req = fakes.HTTPRequest.blank('/manage', version="2.49")
348 context = req.environ['manila.context']
349 self.mock_object(utils, 'validate_service_host')
350 self.mock_object(db_api, 'share_network_get')
351 body = self._setup_manage_test_request_body()
352 body['driver_options'] = 'incorrect'
353 self.assertRaises(webob.exc.HTTPBadRequest,
354 self.controller.manage,
355 req,
356 {'share_server': body})
358 policy.check_policy.assert_called_once_with(
359 context, self.resource_name, 'manage_share_server')
361 def test__validate_manage_share_server_error_extract_host(self):
362 req = fakes.HTTPRequest.blank('/manage', version="2.49")
363 context = req.environ['manila.context']
364 body = self._setup_manage_test_request_body()
365 body['host'] = 'fake@backend#pool'
366 self.assertRaises(webob.exc.HTTPBadRequest,
367 self.controller.manage,
368 req,
369 {'share_server': body})
371 policy.check_policy.assert_called_once_with(
372 context, self.resource_name, 'manage_share_server')
374 @ddt.data(True, False)
375 def test__validate_manage_share_server_error_subnet_not_found(
376 self, body_contains_subnet):
377 req = fakes.HTTPRequest.blank('/manage', version="2.51")
378 context = req.environ['manila.context']
379 share_network = db_utils.create_share_network()
380 body = {'share_server': self._setup_manage_test_request_body()}
381 share_net_subnet = [db_utils.create_share_network_subnet(
382 share_network_id=share_network['id'])]
383 body['share_server']['share_network_subnet_id'] = (
384 share_net_subnet[0]['id'] if body_contains_subnet else None)
386 self.mock_object(
387 db_api, 'share_network_subnet_get_all_with_same_az',
388 mock.Mock(side_effect=exception.ShareNetworkSubnetNotFound(
389 share_network_subnet_id='fake')))
390 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
391 mock.Mock(return_value=None))
393 self.assertRaises(webob.exc.HTTPBadRequest,
394 self.controller.manage,
395 req,
396 body)
398 policy.check_policy.assert_called_once_with(
399 context, self.resource_name, 'manage_share_server')
400 if body_contains_subnet:
401 (db_api.share_network_subnet_get_all_with_same_az.
402 assert_called_once_with(context, share_net_subnet[0]['id']))
403 else:
404 (db_api.share_network_subnet_get_default_subnets
405 .assert_called_once_with(
406 context, body['share_server']['share_network_id']))
408 @ddt.data(True, False)
409 def test__validate_manage_share_server_error_multiple_subnet(
410 self, body_contains_subnet):
411 req = fakes.HTTPRequest.blank('/manage', version="2.70")
412 context = req.environ['manila.context']
413 share_network = db_utils.create_share_network()
414 body = {'share_server': self._setup_manage_test_request_body()}
415 share_net_subnets = [
416 db_utils.create_share_network_subnet(
417 share_network_id=share_network['id']),
418 db_utils.create_share_network_subnet(
419 share_network_id=share_network['id'], id='fake_sns_id_2'),
420 ]
421 body['share_server']['share_network_subnet_id'] = (
422 share_net_subnets[0]['id'] if body_contains_subnet else None)
424 self.mock_object(
425 db_api, 'share_network_subnet_get_all_with_same_az',
426 mock.Mock(return_value=share_net_subnets))
427 self.mock_object(db_api, 'share_network_subnet_get_default_subnets',
428 mock.Mock(return_value=share_net_subnets))
430 self.assertRaises(webob.exc.HTTPBadRequest,
431 self.controller.manage,
432 req,
433 body)
435 policy.check_policy.assert_called_once_with(
436 context, self.resource_name, 'manage_share_server')
437 if body_contains_subnet:
438 (db_api.share_network_subnet_get_all_with_same_az.
439 assert_called_once_with(context, share_net_subnets[0]['id']))
440 else:
441 (db_api.share_network_subnet_get_default_subnets
442 .assert_called_once_with(
443 context, body['share_server']['share_network_id']))
445 @ddt.data(True, False)
446 def test_unmanage(self, force):
447 server = self._setup_unmanage_tests()
448 req = fakes.HTTPRequest.blank('/unmanage', version="2.49")
449 context = req.environ['manila.context']
450 mock_get = self.mock_object(
451 db_api, 'share_server_get', mock.Mock(return_value=server))
452 mock_unmanage = self.mock_object(
453 share_api.API, 'unmanage_share_server',
454 mock.Mock(return_value=202))
455 body = {'unmanage': {'force': force}}
456 resp = self.controller.unmanage(req, server['id'], body)
458 self.assertEqual(202, resp.status_int)
460 mock_get.assert_called_once_with(context, server['id'])
461 mock_unmanage.assert_called_once_with(context, server, force=force)
463 def test_unmanage_share_server_not_found(self):
464 """Tests unmanaging share servers"""
465 req = fakes.HTTPRequest.blank('/v2/share-servers/fake_server_id/',
466 version="2.49")
467 context = req.environ['manila.context']
468 share_server_error = mock.Mock(
469 side_effect=exception.ShareServerNotFound(
470 share_server_id='fake_server_id'))
471 get_mock = self.mock_object(
472 db_api, 'share_server_get', share_server_error)
473 body = {'unmanage': {'force': True}}
475 self.assertRaises(webob.exc.HTTPNotFound,
476 self.controller.unmanage,
477 req,
478 'fake_server_id',
479 body)
481 get_mock.assert_called_once_with(context, 'fake_server_id')
483 def test_unmanage_share_server_multiple_subnets_fail(self):
484 """Tests unmanaging share servers"""
485 server = self._setup_unmanage_tests(multiple_subnets=True)
486 get_mock = self.mock_object(db_api, 'share_server_get',
487 mock.Mock(return_value=server))
488 req = fakes.HTTPRequest.blank('/unmanage_share_server', version="2.70")
489 context = req.environ['manila.context']
490 body = {'unmanage': {'force': True}}
492 self.assertRaises(webob.exc.HTTPBadRequest,
493 self.controller.unmanage,
494 req,
495 server['id'],
496 body)
498 get_mock.assert_called_once_with(context, server['id'])
500 @ddt.data(constants.STATUS_MANAGING, constants.STATUS_DELETING,
501 constants.STATUS_CREATING, constants.STATUS_UNMANAGING)
502 def test_unmanage_share_server_invalid_statuses(self, status):
503 """Tests unmanaging share servers"""
504 server = self._setup_unmanage_tests(status=status)
505 get_mock = self.mock_object(db_api, 'share_server_get',
506 mock.Mock(return_value=server))
507 req = fakes.HTTPRequest.blank('/unmanage_share_server', version="2.49")
508 context = req.environ['manila.context']
509 body = {'unmanage': {'force': True}}
511 self.assertRaises(webob.exc.HTTPBadRequest,
512 self.controller.unmanage,
513 req,
514 server['id'],
515 body)
517 get_mock.assert_called_once_with(context, server['id'])
519 def _setup_unmanage_tests(self, status=constants.STATUS_ACTIVE,
520 multiple_subnets=False):
521 share_network = db_utils.create_share_network()
522 network_subnets = [db_utils.create_share_network_subnet(
523 id='fake_sns_id', share_network_id=share_network['id'])]
524 if multiple_subnets:
525 share_network1 = db_utils.create_share_network()
526 network_subnets.append(db_utils.create_share_network_subnet(
527 share_network_id=share_network1['id'], id='fake_sns_id_2'))
528 server = db_utils.create_share_server(
529 id='fake_server_id', status=status,
530 share_network_subnets=network_subnets)
531 self.mock_object(db_api, 'share_server_get',
532 mock.Mock(return_value=server))
533 self.mock_object(db_api, 'share_network_get',
534 mock.Mock(return_value=share_network))
535 self.mock_object(db_api, 'share_network_subnet_get',
536 mock.Mock(return_value=network_subnets))
537 return server
539 @ddt.data(exception.ShareServerInUse, exception.PolicyNotAuthorized)
540 def test_unmanage_share_server_badrequest(self, exc):
541 req = fakes.HTTPRequest.blank('/unmanage', version="2.49")
542 server = self._setup_unmanage_tests()
543 context = req.environ['manila.context']
544 error = mock.Mock(side_effect=exc('foobar'))
545 mock_unmanage = self.mock_object(
546 share_api.API, 'unmanage_share_server', error)
547 self.mock_object(common, 'check_share_network_is_active',
548 mock.Mock(return_value=True))
549 body = {'unmanage': {'force': True}}
551 self.assertRaises(webob.exc.HTTPBadRequest,
552 self.controller.unmanage,
553 req,
554 'fake_server_id',
555 body)
557 mock_unmanage.assert_called_once_with(context, server, force=True)
558 db_api.share_network_get.assert_called()
559 common.check_share_network_is_active.assert_called()
560 policy.check_policy.assert_called_once_with(
561 context, self.resource_name, 'unmanage_share_server')
563 def test_unmanage_share_server_network_not_active(self):
564 """Tests unmanaging share servers"""
565 req = fakes.HTTPRequest.blank(
566 '/v2/share-servers/fake_server_id/', version="2.63")
567 context = req.environ['manila.context']
568 share_server = db_utils.create_share_server()
569 network_subnets = [db_utils.create_share_network_subnet()]
570 share_server['share_network_subnets'] = network_subnets
571 share_network = db_utils.create_share_network()
572 get_mock = self.mock_object(
573 db_api, 'share_server_get', mock.Mock(return_value=share_server))
574 get_network_mock = self.mock_object(
575 db_api, 'share_network_get',
576 mock.Mock(return_value=share_network))
577 is_active_mock = self.mock_object(
578 common, 'check_share_network_is_active',
579 mock.Mock(side_effect=webob.exc.HTTPBadRequest()))
580 body = {'unmanage': {'force': True}}
582 self.assertRaises(webob.exc.HTTPBadRequest,
583 self.controller.unmanage,
584 req,
585 'fake_server_id',
586 body)
587 get_mock.assert_called_once_with(context, 'fake_server_id')
588 get_network_mock.assert_called_once_with(
589 context,
590 share_server['share_network_subnets'][0]['share_network_id'])
591 is_active_mock.assert_called_once_with(share_network)
593 def _get_server_migration_request(self, server_id, version='2.57'):
594 req = fakes.HTTPRequest.blank(
595 '/share-servers/%s/action' % server_id,
596 use_admin_context=True, version=version)
597 req.method = 'POST'
598 req.headers['content-type'] = 'application/json'
599 req.api_version_request.experimental = True
600 return req
602 def test__share_server_migration_start(self):
603 server = db_utils.create_share_server(id='fake_server_id',
604 status=constants.STATUS_ACTIVE)
605 share_network = db_utils.create_share_network()
606 req = self._get_server_migration_request(server['id'])
607 context = req.environ['manila.context']
609 self.mock_object(db_api, 'share_network_get', mock.Mock(
610 return_value=share_network))
611 self.mock_object(db_api, 'share_server_get',
612 mock.Mock(return_value=server))
613 self.mock_object(common, 'check_share_network_is_active',
614 mock.Mock(return_value=True))
615 self.mock_object(share_api.API, 'share_server_migration_start')
617 body = {
618 'migration_start': {
619 'host': 'fake_host',
620 'preserve_snapshots': True,
621 'writable': True,
622 'nondisruptive': True,
623 'new_share_network_id': 'fake_net_id',
624 }
625 }
627 self.controller.share_server_migration_start(
628 req, server['id'], body)
630 db_api.share_server_get.assert_called_once_with(
631 context, server['id'])
632 share_api.API.share_server_migration_start.assert_called_once_with(
633 context, server, 'fake_host', True, True, True,
634 new_share_network=share_network)
635 db_api.share_network_get.assert_called_once_with(
636 context, 'fake_net_id')
637 common.check_share_network_is_active.assert_called_once_with(
638 share_network)
640 @ddt.data({'api_exception': exception.ServiceIsDown(service='fake_srv'),
641 'expected_exception': webob.exc.HTTPBadRequest},
642 {'api_exception': exception.InvalidShareServer(
643 reason='fake_reason'),
644 'expected_exception': webob.exc.HTTPConflict},
645 {'api_exception': exception.InvalidInput(reason='fake_reason'),
646 'expected_exception': webob.exc.HTTPBadRequest})
647 @ddt.unpack
648 def test__share_server_migration_start_conflict(self, api_exception,
649 expected_exception):
650 share_network = db_utils.create_share_network()
651 share_network_subnet = [db_utils.create_share_network_subnet(
652 share_network_id=share_network['id'])]
653 server = db_utils.create_share_server(
654 id='fake_server_id', status=constants.STATUS_ACTIVE,
655 share_network_subnet_id=share_network_subnet[0]['id'])
656 server['share_network_subnets'] = share_network_subnet
657 req = self._get_server_migration_request(server['id'])
658 context = req.environ['manila.context']
659 body = {
660 'migration_start': {
661 'host': 'fake_host',
662 'preserve_snapshots': True,
663 'writable': True,
664 'nondisruptive': True
665 }
666 }
667 self.mock_object(share_api.API, 'share_server_migration_start',
668 mock.Mock(side_effect=api_exception))
669 self.mock_object(db_api, 'share_server_get',
670 mock.Mock(return_value=server))
671 self.mock_object(common, 'check_share_network_is_active',
672 mock.Mock(return_value=True))
673 self.mock_object(db_api, 'share_network_get',
674 mock.Mock(return_value=share_network))
676 self.assertRaises(expected_exception,
677 self.controller.share_server_migration_start,
678 req, server['id'], body)
680 db_api.share_server_get.assert_called_once_with(context,
681 server['id'])
682 migration_start_params = body['migration_start']
683 common.check_share_network_is_active.assert_called_once_with(
684 share_network)
685 db_api.share_network_get.assert_called_once_with(
686 context, share_network['id'])
687 share_api.API.share_server_migration_start.assert_called_once_with(
688 context, server, migration_start_params['host'],
689 migration_start_params['writable'],
690 migration_start_params['nondisruptive'],
691 migration_start_params['preserve_snapshots'],
692 new_share_network=None)
694 @ddt.data('host', 'body')
695 def test__share_server_migration_start_missing_mandatory(self, param):
696 server = db_utils.create_share_server(
697 id='fake_server_id', status=constants.STATUS_ACTIVE)
698 req = self._get_server_migration_request(server['id'])
699 context = req.environ['manila.context']
701 body = {
702 'migration_start': {
703 'host': 'fake_host',
704 'preserve_metadata': True,
705 'preserve_snapshots': True,
706 'writable': True,
707 'nondisruptive': True
708 }
709 }
711 if param == 'body':
712 body.pop('migration_start')
713 else:
714 body['migration_start'].pop(param)
716 self.mock_object(share_api.API, 'share_server_migration_start')
717 self.mock_object(db_api, 'share_server_get',
718 mock.Mock(return_value=server))
720 self.assertRaises(
721 webob.exc.HTTPBadRequest,
722 getattr(self.controller, 'share_server_migration_start'),
723 req, server['id'], body)
725 db_api.share_server_get.assert_called_once_with(context,
726 server['id'])
728 @ddt.data('nondisruptive', 'writable', 'preserve_snapshots')
729 def test__share_server_migration_start_non_boolean(self, param):
730 server = db_utils.create_share_server(
731 id='fake_server_id', status=constants.STATUS_ACTIVE)
732 req = self._get_server_migration_request(server['id'])
733 context = req.environ['manila.context']
735 body = {
736 'migration_start': {
737 'host': 'fake_host',
738 'preserve_snapshots': True,
739 'writable': True,
740 'nondisruptive': True
741 }
742 }
744 body['migration_start'][param] = None
746 self.mock_object(share_api.API, 'share_server_migration_start')
747 self.mock_object(db_api, 'share_server_get',
748 mock.Mock(return_value=server))
750 self.assertRaises(
751 webob.exc.HTTPBadRequest,
752 getattr(self.controller, 'share_server_migration_start'),
753 req, server['id'], body)
755 db_api.share_server_get.assert_called_once_with(context,
756 server['id'])
758 def test__share_server_migration_start_share_server_not_found(self):
759 fake_id = 'fake_server_id'
760 req = self._get_server_migration_request(fake_id)
761 context = req.environ['manila.context']
763 body = {'migration_start': {'host': 'fake_host'}}
765 self.mock_object(db_api, 'share_server_get',
766 mock.Mock(side_effect=exception.ShareServerNotFound(
767 share_server_id=fake_id)))
769 self.assertRaises(webob.exc.HTTPNotFound,
770 self.controller.share_server_migration_start,
771 req, fake_id, body)
772 db_api.share_server_get.assert_called_once_with(context,
773 fake_id)
775 def test__share_server_migration_start_new_share_network_not_found(self):
776 server = db_utils.create_share_server(
777 id='fake_server_id', status=constants.STATUS_ACTIVE)
778 req = self._get_server_migration_request(server['id'])
779 context = req.environ['manila.context']
781 body = {
782 'migration_start': {
783 'host': 'fake_host',
784 'preserve_metadata': True,
785 'preserve_snapshots': True,
786 'writable': True,
787 'nondisruptive': True,
788 'new_share_network_id': 'nonexistent'}}
790 self.mock_object(db_api, 'share_network_get',
791 mock.Mock(side_effect=exception.NotFound()))
792 self.mock_object(db_api, 'share_server_get',
793 mock.Mock(return_value=server))
795 self.assertRaises(webob.exc.HTTPBadRequest,
796 self.controller.share_server_migration_start,
797 req, server['id'], body)
798 db_api.share_network_get.assert_called_once_with(context,
799 'nonexistent')
800 db_api.share_server_get.assert_called_once_with(context,
801 server['id'])
803 def test__share_server_migration_start_host_with_pool(self):
804 server = db_utils.create_share_server(id='fake_server_id',
805 status=constants.STATUS_ACTIVE)
806 req = self._get_server_migration_request(server['id'])
808 body = {
809 'migration_start': {
810 'host': 'fake_host@fakebackend#pool',
811 'preserve_snapshots': True,
812 'writable': True,
813 'nondisruptive': True,
814 'new_share_network_id': 'fake_net_id',
815 }
816 }
818 self.assertRaises(webob.exc.HTTPBadRequest,
819 self.controller.share_server_migration_start,
820 req, server['id'], body)
822 def test_share_server_migration_check_host_with_pool(self):
823 server = db_utils.create_share_server(id='fake_server_id',
824 status=constants.STATUS_ACTIVE)
825 req = self._get_server_migration_request(server['id'])
827 body = {
828 'migration_start': {
829 'host': 'fake_host@fakebackend#pool',
830 'preserve_snapshots': True,
831 'writable': True,
832 'nondisruptive': True,
833 'new_share_network_id': 'fake_net_id',
834 }
835 }
837 self.assertRaises(webob.exc.HTTPBadRequest,
838 self.controller.share_server_migration_check,
839 req, server['id'], body)
841 @ddt.data(constants.TASK_STATE_MIGRATION_ERROR, None)
842 def test_reset_task_state(self, task_state):
843 server = db_utils.create_share_server(
844 id='fake_server_id', status=constants.STATUS_ACTIVE)
845 req = self._get_server_migration_request(server['id'])
847 update = {'task_state': task_state}
848 body = {'reset_task_state': update}
850 self.mock_object(db_api, 'share_server_update')
852 response = self.controller.share_server_reset_task_state(
853 req, server['id'], body)
855 self.assertEqual(202, response.status_int)
857 db_api.share_server_update.assert_called_once_with(utils.IsAMatcher(
858 ctx_api.RequestContext), server['id'], update)
860 def test_reset_task_state_error_body(self):
861 server = db_utils.create_share_server(
862 id='fake_server_id', status=constants.STATUS_ACTIVE)
863 req = self._get_server_migration_request(server['id'])
865 update = {'error': 'error'}
866 body = {'reset_task_state': update}
868 self.assertRaises(webob.exc.HTTPBadRequest,
869 self.controller.share_server_reset_task_state,
870 req, server['id'], body)
872 def test_reset_task_state_error_invalid(self):
873 server = db_utils.create_share_server(
874 id='fake_server_id', status=constants.STATUS_ACTIVE)
875 req = self._get_server_migration_request(server['id'])
877 update = {'task_state': 'error'}
878 body = {'reset_task_state': update}
880 self.assertRaises(webob.exc.HTTPBadRequest,
881 self.controller.share_server_reset_task_state,
882 req, server['id'], body)
884 def test_reset_task_state_not_found(self):
885 server = db_utils.create_share_server(
886 id='fake_server_id', status=constants.STATUS_ACTIVE)
887 req = self._get_server_migration_request(server['id'])
889 update = {'task_state': constants.TASK_STATE_MIGRATION_ERROR}
890 body = {'reset_task_state': update}
892 self.mock_object(db_api, 'share_server_get',
893 mock.Mock(side_effect=exception.ShareServerNotFound(
894 share_server_id='fake_server_id')))
895 self.mock_object(db_api, 'share_server_update')
897 self.assertRaises(webob.exc.HTTPNotFound,
898 self.controller.share_server_reset_task_state,
899 req, server['id'], body)
901 db_api.share_server_get.assert_called_once_with(utils.IsAMatcher(
902 ctx_api.RequestContext), server['id'])
903 db_api.share_server_update.assert_not_called()
905 def test_share_server_migration_complete(self):
906 server = db_utils.create_share_server(
907 id='fake_server_id', status=constants.STATUS_ACTIVE)
908 req = self._get_server_migration_request(server['id'])
909 context = req.environ['manila.context']
911 body = {'migration_complete': None}
912 api_return = {
913 'destination_share_server_id': 'fake_destination_id'
914 }
916 self.mock_object(share_api.API, 'share_server_migration_complete',
917 mock.Mock(return_value=api_return))
918 self.mock_object(db_api, 'share_server_get',
919 mock.Mock(return_value=server))
921 result = self.controller.share_server_migration_complete(
922 req, server['id'], body)
924 self.assertEqual(api_return, result)
925 share_api.API.share_server_migration_complete.assert_called_once_with(
926 utils.IsAMatcher(ctx_api.RequestContext), server)
927 db_api.share_server_get.assert_called_once_with(context,
928 server['id'])
930 def test_share_server_migration_complete_not_found(self):
931 fake_id = 'fake_server_id'
932 req = self._get_server_migration_request(fake_id)
933 context = req.environ['manila.context']
935 body = {'migration_complete': None}
937 self.mock_object(db_api, 'share_server_get',
938 mock.Mock(side_effect=exception.ShareServerNotFound(
939 share_server_id=fake_id)))
940 self.mock_object(share_api.API, 'share_server_migration_complete')
942 self.assertRaises(webob.exc.HTTPNotFound,
943 self.controller.share_server_migration_complete,
944 req, fake_id, body)
945 db_api.share_server_get.assert_called_once_with(context,
946 fake_id)
948 @ddt.data({'api_exception': exception.ServiceIsDown(service='fake_srv'),
949 'expected_exception': webob.exc.HTTPBadRequest},
950 {'api_exception': exception.InvalidShareServer(reason=""),
951 'expected_exception': webob.exc.HTTPBadRequest})
952 @ddt.unpack
953 def test_share_server_migration_complete_exceptions(self, api_exception,
954 expected_exception):
955 fake_id = 'fake_server_id'
956 req = self._get_server_migration_request(fake_id)
957 context = req.environ['manila.context']
958 body = {'migration_complete': None}
959 self.mock_object(db_api, 'share_server_get',
960 mock.Mock(return_value='fake_share_server'))
961 self.mock_object(share_api.API, 'share_server_migration_complete',
962 mock.Mock(side_effect=api_exception))
964 self.assertRaises(expected_exception,
965 self.controller.share_server_migration_complete,
966 req, fake_id, body)
968 db_api.share_server_get.assert_called_once_with(context,
969 fake_id)
970 share_api.API.share_server_migration_complete.assert_called_once_with(
971 context, 'fake_share_server')
973 def test_share_server_migration_cancel(self):
974 server = db_utils.create_share_server(
975 id='fake_server_id', status=constants.STATUS_ACTIVE)
976 req = self._get_server_migration_request(server['id'])
977 context = req.environ['manila.context']
979 body = {'migration_cancel': None}
981 self.mock_object(db_api, 'share_server_get',
982 mock.Mock(return_value=server))
983 self.mock_object(share_api.API, 'share_server_migration_cancel')
985 self.controller.share_server_migration_cancel(
986 req, server['id'], body)
988 share_api.API.share_server_migration_cancel.assert_called_once_with(
989 utils.IsAMatcher(ctx_api.RequestContext), server)
990 db_api.share_server_get.assert_called_once_with(context,
991 server['id'])
993 def test_share_server_migration_cancel_not_found(self):
994 fake_id = 'fake_server_id'
995 req = self._get_server_migration_request(fake_id)
996 context = req.environ['manila.context']
998 body = {'migration_cancel': None}
1000 self.mock_object(db_api, 'share_server_get',
1001 mock.Mock(side_effect=exception.ShareServerNotFound(
1002 share_server_id=fake_id)))
1003 self.mock_object(share_api.API, 'share_server_migration_cancel')
1005 self.assertRaises(webob.exc.HTTPNotFound,
1006 self.controller.share_server_migration_cancel,
1007 req, fake_id, body)
1008 db_api.share_server_get.assert_called_once_with(context,
1009 fake_id)
1011 @ddt.data({'api_exception': exception.ServiceIsDown(service='fake_srv'),
1012 'expected_exception': webob.exc.HTTPBadRequest},
1013 {'api_exception': exception.InvalidShareServer(reason=""),
1014 'expected_exception': webob.exc.HTTPBadRequest})
1015 @ddt.unpack
1016 def test_share_server_migration_cancel_exceptions(self, api_exception,
1017 expected_exception):
1018 fake_id = 'fake_server_id'
1019 req = self._get_server_migration_request(fake_id)
1020 context = req.environ['manila.context']
1021 body = {'migration_complete': None}
1022 self.mock_object(db_api, 'share_server_get',
1023 mock.Mock(return_value='fake_share_server'))
1024 self.mock_object(share_api.API, 'share_server_migration_cancel',
1025 mock.Mock(side_effect=api_exception))
1027 self.assertRaises(expected_exception,
1028 self.controller.share_server_migration_cancel,
1029 req, fake_id, body)
1031 db_api.share_server_get.assert_called_once_with(context,
1032 fake_id)
1033 share_api.API.share_server_migration_cancel.assert_called_once_with(
1034 context, 'fake_share_server')
1036 def test_share_server_migration_get_progress(self):
1037 server = db_utils.create_share_server(
1038 id='fake_server_id',
1039 status=constants.STATUS_ACTIVE,
1040 task_state=constants.TASK_STATE_MIGRATION_SUCCESS)
1041 req = self._get_server_migration_request(server['id'])
1043 body = {'migration_get_progress': None}
1044 expected = {
1045 'total_progress': 'fake',
1046 'task_state': constants.TASK_STATE_MIGRATION_SUCCESS,
1047 'destination_share_server_id': 'fake_destination_server_id'
1048 }
1050 self.mock_object(share_api.API, 'share_server_migration_get_progress',
1051 mock.Mock(return_value=expected))
1053 response = self.controller.share_server_migration_get_progress(
1054 req, server['id'], body)
1055 self.assertEqual(expected, response)
1056 (share_api.API.share_server_migration_get_progress.
1057 assert_called_once_with(utils.IsAMatcher(ctx_api.RequestContext),
1058 server['id']))
1060 @ddt.data({'api_exception': exception.ServiceIsDown(service='fake_srv'),
1061 'expected_exception': webob.exc.HTTPConflict},
1062 {'api_exception': exception.InvalidShareServer(reason=""),
1063 'expected_exception': webob.exc.HTTPBadRequest})
1064 @ddt.unpack
1065 def test_share_server_migration_get_progress_exceptions(
1066 self, api_exception, expected_exception):
1067 fake_id = 'fake_server_id'
1068 req = self._get_server_migration_request(fake_id)
1069 context = req.environ['manila.context']
1070 body = {'migration_complete': None}
1071 self.mock_object(db_api, 'share_server_get',
1072 mock.Mock(return_value='fake_share_server'))
1073 mock_get_progress = self.mock_object(
1074 share_api.API, 'share_server_migration_get_progress',
1075 mock.Mock(side_effect=api_exception))
1077 self.assertRaises(expected_exception,
1078 self.controller.share_server_migration_get_progress,
1079 req, fake_id, body)
1081 mock_get_progress.assert_called_once_with(context, fake_id)
1083 def test_share_server_migration_check(self):
1084 fake_id = 'fake_server_id'
1085 fake_share_server = db_utils.create_share_server(id=fake_id)
1086 fake_share_network = db_utils.create_share_network()
1087 req = self._get_server_migration_request(fake_id)
1088 context = req.environ['manila.context']
1089 requested_writable = False
1090 requested_nondisruptive = False
1091 requested_preserve_snapshots = False
1092 fake_host = 'fakehost@fakebackend'
1093 body = {
1094 'migration_check': {
1095 'writable': requested_writable,
1096 'nondisruptive': requested_nondisruptive,
1097 'preserve_snapshots': requested_preserve_snapshots,
1098 'new_share_network_id': fake_share_network['id'],
1099 'host': fake_host
1100 }
1101 }
1102 driver_result = {
1103 'compatible': False,
1104 'writable': False,
1105 'nondisruptive': True,
1106 'preserve_snapshots': False,
1107 'share_network_id': 'fake_network_uuid',
1108 'migration_cancel': False,
1109 'migration_get_progress': False,
1110 }
1112 mock_server_get = self.mock_object(
1113 db_api, 'share_server_get',
1114 mock.Mock(return_value=fake_share_server))
1115 mock_network_get = self.mock_object(
1116 db_api, 'share_network_get',
1117 mock.Mock(return_value=fake_share_network))
1118 self.mock_object(common, 'check_share_network_is_active',
1119 mock.Mock(return_value=True))
1120 mock_migration_check = self.mock_object(
1121 share_api.API, 'share_server_migration_check',
1122 mock.Mock(return_value=driver_result))
1124 result = self.controller.share_server_migration_check(
1125 req, fake_id, body)
1127 expected_result_keys = ['compatible', 'requested_capabilities',
1128 'supported_capabilities']
1129 [self.assertIn(key, result) for key in expected_result_keys]
1130 mock_server_get.assert_called_once_with(
1131 context, fake_share_server['id'])
1132 mock_network_get.assert_called_once_with(
1133 context, fake_share_network['id'])
1134 common.check_share_network_is_active.assert_called_once_with(
1135 fake_share_network)
1136 mock_migration_check.assert_called_once_with(
1137 context, fake_share_server, fake_host, requested_writable,
1138 requested_nondisruptive, requested_preserve_snapshots,
1139 new_share_network=fake_share_network)
1141 @ddt.data(
1142 (webob.exc.HTTPNotFound, True, False, {'migration_check': {}}),
1143 (webob.exc.HTTPBadRequest, False, True,
1144 {'migration_check': {'new_share_network_id': 'fake_id'}}),
1145 (webob.exc.HTTPBadRequest, False, False, None)
1146 )
1147 @ddt.unpack
1148 def test_share_server_migration_check_exception(
1149 self, exception_to_raise, raise_server_get_exception,
1150 raise_network_get_action, body):
1151 req = self._get_server_migration_request('fake_id')
1152 context = req.environ['manila.context']
1153 if body:
1154 body['migration_check']['writable'] = False
1155 body['migration_check']['nondisruptive'] = False
1156 body['migration_check']['preserve_snapshots'] = False
1157 body['migration_check']['host'] = 'fakehost@fakebackend'
1158 else:
1159 body = {}
1161 server = db_utils.create_share_server(
1162 id='fake_server_id', status=constants.STATUS_ACTIVE)
1164 server_get = mock.Mock(return_value=server)
1165 network_get = mock.Mock()
1166 if raise_server_get_exception:
1167 server_get = mock.Mock(
1168 side_effect=exception.ShareServerNotFound(
1169 share_server_id='fake'))
1170 if raise_network_get_action:
1171 network_get = mock.Mock(
1172 side_effect=exception.ShareNetworkNotFound(
1173 share_network_id='fake'))
1175 mock_server_get = self.mock_object(
1176 db_api, 'share_server_get', server_get)
1178 mock_network_get = self.mock_object(
1179 db_api, 'share_network_get', network_get)
1181 self.assertRaises(
1182 exception_to_raise,
1183 self.controller.share_server_migration_check,
1184 req, 'fake_id', body
1185 )
1186 mock_server_get.assert_called_once_with(
1187 context, 'fake_id')
1188 if raise_network_get_action:
1189 mock_network_get.assert_called_once_with(context, 'fake_id')
1191 @ddt.data(
1192 {'api_exception': exception.ServiceIsDown(service='fake_srv'),
1193 'expected_exception': webob.exc.HTTPBadRequest},
1194 {'api_exception': exception.InvalidShareServer(reason=""),
1195 'expected_exception': webob.exc.HTTPBadRequest})
1196 @ddt.unpack
1197 def test_share_server_migration_complete_exceptions_from_api(
1198 self, api_exception, expected_exception):
1199 req = self._get_server_migration_request('fake_id')
1200 context = req.environ['manila.context']
1201 body = {
1202 'migration_check': {
1203 'writable': False,
1204 'nondisruptive': False,
1205 'preserve_snapshots': True,
1206 'host': 'fakehost@fakebackend',
1207 }
1208 }
1210 self.mock_object(db_api, 'share_server_get',
1211 mock.Mock(return_value='fake_share_server'))
1213 self.mock_object(share_api.API, 'share_server_migration_complete',
1214 mock.Mock(side_effect=api_exception))
1216 self.assertRaises(
1217 expected_exception,
1218 self.controller.share_server_migration_complete,
1219 req, 'fake_id', body
1220 )
1222 db_api.share_server_get.assert_called_once_with(context,
1223 'fake_id')
1224 share_api.API.share_server_migration_complete.assert_called_once_with(
1225 context, 'fake_share_server', )