148
147
self.patcher = mock.patch('eventlet.greenthread.sleep')
149
148
self.mock_sleep = self.patcher.start()
149
self.info = seamicro._parse_driver_info(self.node)
151
151
@mock.patch.object(seamicro_client, "Client")
152
152
def test__get_client(self, mock_client):
153
driver_info = seamicro._parse_driver_info(self.node)
154
args = {'username': driver_info['username'],
155
'password': driver_info['password'],
156
'auth_url': driver_info['api_endpoint']}
157
seamicro._get_client(**driver_info)
158
mock_client.assert_called_once_with(driver_info['api_version'], **args)
153
args = {'username': self.info['username'],
154
'password': self.info['password'],
155
'auth_url': self.info['api_endpoint']}
156
seamicro._get_client(**self.info)
157
mock_client.assert_called_once_with(self.info['api_version'], **args)
160
159
@mock.patch.object(seamicro_client, "Client")
161
160
def test__get_client_fail(self, mock_client):
162
driver_info = seamicro._parse_driver_info(self.node)
163
args = {'username': driver_info['username'],
164
'password': driver_info['password'],
165
'auth_url': driver_info['api_endpoint']}
161
args = {'username': self.info['username'],
162
'password': self.info['password'],
163
'auth_url': self.info['api_endpoint']}
166
164
mock_client.side_effect = seamicro_client_exception.UnsupportedVersion
167
165
self.assertRaises(exception.InvalidParameterValue,
168
166
seamicro._get_client,
170
mock_client.assert_called_once_with(driver_info['api_version'], **args)
168
mock_client.assert_called_once_with(self.info['api_version'], **args)
172
170
@mock.patch.object(seamicro, "_get_server")
173
171
def test__get_power_status_on(self, mock_get_server):
239
237
@mock.patch.object(seamicro, "_get_volume")
240
238
def test__validate_fail(self, mock_get_volume):
241
info = seamicro._parse_driver_info(self.node)
242
239
volume_id = "0/p6-6/vol1"
243
240
volume = self.Volume()
244
241
volume.id = volume_id
245
242
mock_get_volume.return_value = volume
246
243
self.assertRaises(exception.InvalidParameterValue,
247
seamicro._validate_volume, info, volume_id)
244
seamicro._validate_volume, self.info, volume_id)
249
246
@mock.patch.object(seamicro, "_get_volume")
250
247
def test__validate_good(self, mock_get_volume):
251
info = seamicro._parse_driver_info(self.node)
252
248
volume = self.Volume()
253
249
mock_get_volume.return_value = volume
254
valid = seamicro._validate_volume(info, volume.id)
250
valid = seamicro._validate_volume(self.info, volume.id)
255
251
self.assertEqual(valid, True)
257
253
@mock.patch.object(seamicro, "_get_pools")
258
254
def test__create_volume_fail(self, mock_get_pools):
259
info = seamicro._parse_driver_info(self.node)
260
255
mock_get_pools.return_value = None
261
256
self.assertRaises(exception.IronicException,
262
257
seamicro._create_volume,
265
260
@mock.patch.object(seamicro, "_get_pools")
266
261
@mock.patch.object(seamicro, "_get_client")
267
262
def test__create_volume_good(self, mock_get_client, mock_get_pools):
268
info = seamicro._parse_driver_info(self.node)
269
263
pools = [self.Pool(1), self.Pool(6), self.Pool(5)]
270
264
get_pools_patcher = mock.patch.object(mock_get_client, "volume.create")
271
265
get_pools_patcher.start()
272
266
mock_get_pools.return_value = pools
273
seamicro._create_volume(info, 2)
267
seamicro._create_volume(self.info, 2)
274
268
get_pools_patcher.stop()
283
277
self.node = obj_utils.create_test_node(self.context,
284
278
driver='fake_seamicro',
285
279
driver_info=INFO_DICT)
286
self.dbapi = dbapi.get_instance()
287
280
self.get_server_patcher = mock.patch.object(seamicro, '_get_server')
289
282
self.get_server_mock = None
290
283
self.Server = Fake_Server
291
284
self.Volume = Fake_Volume
285
self.info = seamicro._parse_driver_info(self.node)
293
287
def test_get_properties(self):
294
288
expected = seamicro.COMMON_PROPERTIES
295
289
with task_manager.acquire(self.context, self.node['uuid'],
296
290
shared=True) as task:
297
self.assertEqual(expected, task.driver.get_properties())
291
self.assertEqual(expected, task.driver.power.get_properties())
293
expected = (list(seamicro.COMMON_PROPERTIES) +
294
list(seamicro.CONSOLE_PROPERTIES))
295
console_properties = task.driver.console.get_properties().keys()
296
self.assertEqual(sorted(expected), sorted(console_properties))
297
self.assertEqual(sorted(expected),
298
sorted(task.driver.get_properties().keys()))
300
def test_vendor_routes(self):
301
expected = ['set_node_vlan_id', 'attach_volume']
302
with task_manager.acquire(self.context, self.node.uuid,
303
shared=True) as task:
304
vendor_routes = task.driver.vendor.vendor_routes
305
self.assertIsInstance(vendor_routes, dict)
306
self.assertEqual(sorted(expected), sorted(vendor_routes))
308
def test_driver_routes(self):
309
with task_manager.acquire(self.context, self.node.uuid,
310
shared=True) as task:
311
driver_routes = task.driver.vendor.driver_routes
312
self.assertIsInstance(driver_routes, dict)
313
self.assertEqual({}, driver_routes)
299
315
@mock.patch.object(seamicro, '_parse_driver_info')
300
316
def test_power_interface_validate_good(self, parse_drv_info_mock):
316
332
@mock.patch.object(seamicro, '_reboot')
317
333
def test_reboot(self, mock_reboot):
318
info = seamicro._parse_driver_info(self.node)
320
334
mock_reboot.return_value = states.POWER_ON
322
with task_manager.acquire(self.context, info['uuid'],
336
with task_manager.acquire(self.context, self.info['uuid'],
323
337
shared=False) as task:
324
338
task.driver.power.reboot(task)
326
340
mock_reboot.assert_called_once_with(task.node)
328
342
def test_set_power_state_bad_state(self):
329
info = seamicro ._parse_driver_info(self.node)
330
343
self.get_server_mock = self.get_server_patcher.start()
331
344
self.get_server_mock.return_value = self.Server()
333
with task_manager.acquire(self.context, info['uuid'],
346
with task_manager.acquire(self.context, self.info['uuid'],
334
347
shared=False) as task:
335
348
self.assertRaises(exception.IronicException,
336
349
task.driver.power.set_power_state,
393
398
def test_vendor_passthru_validate_good(self, mock_info):
394
399
with task_manager.acquire(self.context, self.node['uuid'],
395
400
shared=True) as task:
396
for method in seamicro.VENDOR_PASSTHRU_METHODS:
401
for method in task.driver.vendor.vendor_routes:
397
402
task.driver.vendor.validate(task, **{'method': method})
398
self.assertEqual(len(seamicro.VENDOR_PASSTHRU_METHODS),
403
self.assertEqual(len(task.driver.vendor.vendor_routes),
399
404
mock_info.call_count)
401
406
@mock.patch.object(seamicro, '_parse_driver_info')
402
def test_vendor_passthru_validate_fail(self, mock_info):
403
with task_manager.acquire(self.context, self.node['uuid'],
404
shared=True) as task:
405
self.assertRaises(exception.InvalidParameterValue,
406
task.driver.vendor.validate,
407
task, **{'method': 'invalid_method'})
408
self.assertFalse(mock_info.called)
410
@mock.patch.object(seamicro, '_parse_driver_info')
411
407
def test_vendor_passthru_validate_parse_driver_info_fail(self, mock_info):
412
408
mock_info.side_effect = exception.InvalidParameterValue("bad")
413
409
with task_manager.acquire(self.context, self.node['uuid'],
414
410
shared=True) as task:
415
method = seamicro.VENDOR_PASSTHRU_METHODS[0]
411
method = list(task.driver.vendor.vendor_routes)[0]
416
412
self.assertRaises(exception.InvalidParameterValue,
417
413
task.driver.vendor.validate,
418
414
task, **{'method': method})
421
417
@mock.patch.object(seamicro, '_get_server')
422
418
def test_set_node_vlan_id_good(self, mock_get_server):
423
info = seamicro._parse_driver_info(self.node)
425
420
mock_get_server.return_value = self.Server(active="true")
426
with task_manager.acquire(self.context, info['uuid'],
421
with task_manager.acquire(self.context, self.info['uuid'],
427
422
shared=False) as task:
428
kwargs = {'vlan_id': vlan_id, 'method': 'set_node_vlan_id'}
429
task.driver.vendor.vendor_passthru(task, **kwargs)
430
mock_get_server.assert_called_once_with(info)
423
kwargs = {'vlan_id': vlan_id}
424
task.driver.vendor.set_node_vlan_id(task, **kwargs)
425
mock_get_server.assert_called_once_with(self.info)
432
427
def test_set_node_vlan_id_no_input(self):
433
info = seamicro._parse_driver_info(self.node)
434
with task_manager.acquire(self.context, info['uuid'],
428
with task_manager.acquire(self.context, self.info['uuid'],
435
429
shared=False) as task:
436
430
self.assertRaises(exception.InvalidParameterValue,
437
task.driver.vendor.vendor_passthru,
439
**{'method': 'set_node_vlan_id'})
431
task.driver.vendor.set_node_vlan_id,
441
434
@mock.patch.object(seamicro, '_get_server')
442
435
def test_set_node_vlan_id_fail(self, mock_get_server):
443
436
def fake_set_untagged_vlan(self, **kwargs):
444
437
raise seamicro_client_exception.ClientException(500)
446
info = seamicro._parse_driver_info(self.node)
448
440
server = self.Server(active="true")
449
441
server.set_untagged_vlan = fake_set_untagged_vlan
450
442
mock_get_server.return_value = server
451
with task_manager.acquire(self.context, info['uuid'],
443
with task_manager.acquire(self.context, self.info['uuid'],
452
444
shared=False) as task:
453
kwargs = {'vlan_id': vlan_id, 'method': 'set_node_vlan_id'}
445
kwargs = {'vlan_id': vlan_id}
454
446
self.assertRaises(exception.IronicException,
455
task.driver.vendor.vendor_passthru,
447
task.driver.vendor.set_node_vlan_id,
459
mock_get_server.assert_called_once_with(info)
450
mock_get_server.assert_called_once_with(self.info)
461
452
@mock.patch.object(seamicro, '_get_server')
462
453
@mock.patch.object(seamicro, '_validate_volume')
463
454
def test_attach_volume_with_volume_id_good(self, mock_validate_volume,
464
455
mock_get_server):
465
info = seamicro._parse_driver_info(self.node)
466
456
volume_id = '0/ironic-p6-1/vol1'
467
457
mock_validate_volume.return_value = True
468
458
mock_get_server.return_value = self.Server(active="true")
469
with task_manager.acquire(self.context, info['uuid'],
459
with task_manager.acquire(self.context, self.info['uuid'],
470
460
shared=False) as task:
471
kwargs = {'volume_id': volume_id, 'method': 'attach_volume'}
472
task.driver.vendor.vendor_passthru(task, **kwargs)
473
mock_get_server.assert_called_once_with(info)
461
kwargs = {'volume_id': volume_id}
462
task.driver.vendor.attach_volume(task, **kwargs)
463
mock_get_server.assert_called_once_with(self.info)
475
465
@mock.patch.object(seamicro, '_get_server')
476
466
@mock.patch.object(seamicro, '_get_volume')
477
467
def test_attach_volume_with_invalid_volume_id_fail(self,
479
469
mock_get_server):
480
info = seamicro._parse_driver_info(self.node)
481
470
volume_id = '0/p6-1/vol1'
482
471
mock_get_volume.return_value = self.Volume(volume_id)
483
472
mock_get_server.return_value = self.Server(active="true")
484
with task_manager.acquire(self.context, info['uuid'],
473
with task_manager.acquire(self.context, self.info['uuid'],
485
474
shared=False) as task:
486
kwargs = {'volume_id': volume_id, 'method': 'attach_volume'}
475
kwargs = {'volume_id': volume_id}
487
476
self.assertRaises(exception.InvalidParameterValue,
488
task.driver.vendor.vendor_passthru,
477
task.driver.vendor.attach_volume,
492
480
@mock.patch.object(seamicro, '_get_server')
493
481
@mock.patch.object(seamicro, '_validate_volume')
496
484
def fake_attach_volume(self, **kwargs):
497
485
raise seamicro_client_exception.ClientException(500)
499
info = seamicro._parse_driver_info(self.node)
500
487
volume_id = '0/p6-1/vol1'
501
488
mock_validate_volume.return_value = True
502
489
server = self.Server(active="true")
503
490
server.attach_volume = fake_attach_volume
504
491
mock_get_server.return_value = server
505
with task_manager.acquire(self.context, info['uuid'],
492
with task_manager.acquire(self.context, self.info['uuid'],
506
493
shared=False) as task:
507
kwargs = {'volume_id': volume_id, 'method': 'attach_volume'}
494
kwargs = {'volume_id': volume_id}
508
495
self.assertRaises(exception.IronicException,
509
task.driver.vendor.vendor_passthru,
496
task.driver.vendor.attach_volume,
513
mock_get_server.assert_called_once_with(info)
499
mock_get_server.assert_called_once_with(self.info)
515
501
@mock.patch.object(seamicro, '_get_server')
516
502
@mock.patch.object(seamicro, '_validate_volume')
518
504
def test_attach_volume_with_volume_size_good(self, mock_create_volume,
519
505
mock_validate_volume,
520
506
mock_get_server):
521
info = seamicro._parse_driver_info(self.node)
522
507
volume_id = '0/ironic-p6-1/vol1'
524
509
mock_create_volume.return_value = volume_id
525
510
mock_validate_volume.return_value = True
526
511
mock_get_server.return_value = self.Server(active="true")
527
with task_manager.acquire(self.context, info['uuid'],
512
with task_manager.acquire(self.context, self.info['uuid'],
528
513
shared=False) as task:
529
kwargs = {'volume_size': volume_size, 'method': "attach_volume"}
530
task.driver.vendor.vendor_passthru(task, **kwargs)
531
mock_get_server.assert_called_once_with(info)
532
mock_create_volume.assert_called_once_with(info, volume_size)
514
kwargs = {'volume_size': volume_size}
515
task.driver.vendor.attach_volume(task, **kwargs)
516
mock_get_server.assert_called_once_with(self.info)
517
mock_create_volume.assert_called_once_with(self.info, volume_size)
534
519
def test_attach_volume_with_no_input_fail(self):
535
info = seamicro._parse_driver_info(self.node)
536
with task_manager.acquire(self.context, info['uuid'],
520
with task_manager.acquire(self.context, self.info['uuid'],
537
521
shared=False) as task:
538
522
self.assertRaises(exception.InvalidParameterValue,
539
task.driver.vendor.vendor_passthru, task,
540
**{'method': 'attach_volume'})
523
task.driver.vendor.attach_volume, task,
542
526
@mock.patch.object(seamicro, '_get_server')
543
527
def test_set_boot_device_good(self, mock_get_server):
544
info = seamicro._parse_driver_info(self.node)
545
528
boot_device = "disk"
546
529
mock_get_server.return_value = self.Server(active="true")
547
with task_manager.acquire(self.context, info['uuid'],
530
with task_manager.acquire(self.context, self.info['uuid'],
548
531
shared=False) as task:
549
532
task.driver.management.set_boot_device(task, boot_device)
550
mock_get_server.assert_called_once_with(info)
533
mock_get_server.assert_called_once_with(self.info)
552
535
@mock.patch.object(seamicro, '_get_server')
553
536
def test_set_boot_device_invalid_device_fail(self, mock_get_server):
554
info = seamicro._parse_driver_info(self.node)
555
537
boot_device = "invalid_device"
556
538
mock_get_server.return_value = self.Server(active="true")
557
with task_manager.acquire(self.context, info['uuid'],
539
with task_manager.acquire(self.context, self.info['uuid'],
558
540
shared=False) as task:
559
541
self.assertRaises(exception.InvalidParameterValue,
560
542
task.driver.management.set_boot_device,
565
547
def fake_set_boot_order(self, **kwargs):
566
548
raise seamicro_client_exception.ClientException(500)
568
info = seamicro._parse_driver_info(self.node)
569
550
boot_device = "pxe"
570
551
server = self.Server(active="true")
571
552
server.set_boot_order = fake_set_boot_order
572
553
mock_get_server.return_value = server
573
with task_manager.acquire(self.context, info['uuid'],
554
with task_manager.acquire(self.context, self.info['uuid'],
574
555
shared=False) as task:
575
556
self.assertRaises(exception.IronicException,
576
557
task.driver.management.set_boot_device,
577
558
task, boot_device)
579
mock_get_server.assert_called_once_with(info)
560
mock_get_server.assert_called_once_with(self.info)
581
562
def test_management_interface_get_supported_boot_devices(self):
582
563
with task_manager.acquire(self.context, self.node.uuid) as task:
597
578
def test_management_interface_validate_fail(self):
598
579
# Missing SEAMICRO driver_info information
599
node = obj_utils.create_test_node(self.context, id=2,
580
node = obj_utils.create_test_node(self.context,
600
581
uuid=utils.generate_uuid(),
601
582
driver='fake_seamicro')
602
583
with task_manager.acquire(self.context, node.uuid) as task:
603
584
self.assertRaises(exception.MissingParameterValue,
604
585
task.driver.management.validate, task)
588
class SeaMicroDriverTestCase(db_base.DbTestCase):
591
super(SeaMicroDriverTestCase, self).setUp()
592
mgr_utils.mock_the_extension_manager(driver='fake_seamicro')
593
self.driver = driver_factory.get_driver('fake_seamicro')
594
self.node = obj_utils.create_test_node(self.context,
595
driver='fake_seamicro',
596
driver_info=INFO_DICT)
597
self.get_server_patcher = mock.patch.object(seamicro, '_get_server')
599
self.get_server_mock = None
600
self.Server = Fake_Server
601
self.Volume = Fake_Volume
602
self.info = seamicro._parse_driver_info(self.node)
604
@mock.patch.object(console_utils, 'start_shellinabox_console')
605
def test_start_console(self, mock_exec):
606
mock_exec.return_value = None
607
with task_manager.acquire(self.context,
608
self.node.uuid) as task:
609
self.driver.console.start_console(task)
611
mock_exec.assert_called_once_with(self.info['uuid'],
615
@mock.patch.object(console_utils, 'start_shellinabox_console')
616
def test_start_console_fail(self, mock_exec):
617
mock_exec.side_effect = exception.ConsoleSubprocessFailed(
620
with task_manager.acquire(self.context,
621
self.node.uuid) as task:
622
self.assertRaises(exception.ConsoleSubprocessFailed,
623
self.driver.console.start_console,
626
@mock.patch.object(console_utils, 'stop_shellinabox_console')
627
def test_stop_console(self, mock_exec):
628
mock_exec.return_value = None
629
with task_manager.acquire(self.context,
630
self.node.uuid) as task:
631
self.driver.console.stop_console(task)
633
mock_exec.assert_called_once_with(self.info['uuid'])
635
@mock.patch.object(console_utils, 'stop_shellinabox_console')
636
def test_stop_console_fail(self, mock_stop):
637
mock_stop.side_effect = exception.ConsoleError()
639
with task_manager.acquire(self.context,
640
self.node.uuid) as task:
641
self.assertRaises(exception.ConsoleError,
642
self.driver.console.stop_console,
645
mock_stop.assert_called_once_with(self.node.uuid)
647
@mock.patch.object(console_utils, 'start_shellinabox_console')
648
def test_start_console_fail_nodir(self, mock_exec):
649
mock_exec.side_effect = exception.ConsoleError()
651
with task_manager.acquire(self.context,
652
self.node.uuid) as task:
653
self.assertRaises(exception.ConsoleError,
654
self.driver.console.start_console,
656
mock_exec.assert_called_once_with(self.node.uuid, mock.ANY, mock.ANY)
658
@mock.patch.object(console_utils, 'get_shellinabox_console_url')
659
def test_get_console(self, mock_exec):
660
url = 'http://localhost:4201'
661
mock_exec.return_value = url
662
expected = {'type': 'shellinabox', 'url': url}
664
with task_manager.acquire(self.context,
665
self.node.uuid) as task:
666
console_info = self.driver.console.get_console(task)
668
self.assertEqual(expected, console_info)
669
mock_exec.assert_called_once_with(self.info['port'])