
Remove a lot of getLogger lines and imports of logging in modules which never use that functionality. Change-Id: Icdaee2c540980412b000d02ebf1ec568dcf5b38a
491 lines
19 KiB
Python
491 lines
19 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2012 IBM Corp.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
"""
|
|
Test suite for PowerVMDriver.
|
|
"""
|
|
|
|
import contextlib
|
|
|
|
from nova import context
|
|
from nova import db
|
|
from nova import test
|
|
|
|
from nova.compute import instance_types
|
|
from nova.compute import power_state
|
|
from nova.compute import task_states
|
|
from nova.network import model as network_model
|
|
from nova.tests import fake_network_cache_model
|
|
from nova.tests.image import fake
|
|
from nova.virt import images
|
|
from nova.virt.powervm import blockdev as powervm_blockdev
|
|
from nova.virt.powervm import common
|
|
from nova.virt.powervm import driver as powervm_driver
|
|
from nova.virt.powervm import exception
|
|
from nova.virt.powervm import lpar
|
|
from nova.virt.powervm import operator
|
|
|
|
|
|
def fake_lpar(instance_name):
|
|
return lpar.LPAR(name=instance_name,
|
|
lpar_id=1, desired_mem=1024,
|
|
max_mem=2048, max_procs=2,
|
|
uptime=939395, state='Running')
|
|
|
|
|
|
class FakeIVMOperator(object):
|
|
|
|
def get_lpar(self, instance_name, resource_type='lpar'):
|
|
return fake_lpar(instance_name)
|
|
|
|
def list_lpar_instances(self):
|
|
return ['instance-00000001', 'instance-00000002']
|
|
|
|
def create_lpar(self, lpar):
|
|
pass
|
|
|
|
def start_lpar(self, instance_name):
|
|
pass
|
|
|
|
def stop_lpar(self, instance_name, time_out=30):
|
|
pass
|
|
|
|
def remove_lpar(self, instance_name):
|
|
pass
|
|
|
|
def get_vhost_by_instance_id(self, instance_id):
|
|
return 'vhostfake'
|
|
|
|
def get_virtual_eth_adapter_id(self):
|
|
return 1
|
|
|
|
def get_disk_name_by_vhost(self, vhost):
|
|
return 'lvfake01'
|
|
|
|
def remove_disk(self, disk_name):
|
|
pass
|
|
|
|
def run_cfg_dev(self, device_name):
|
|
pass
|
|
|
|
def attach_disk_to_vhost(self, disk, vhost):
|
|
pass
|
|
|
|
def get_memory_info(self):
|
|
return {'total_mem': 65536, 'avail_mem': 46336}
|
|
|
|
def get_cpu_info(self):
|
|
return {'total_procs': 8.0, 'avail_procs': 6.3}
|
|
|
|
def get_disk_info(self):
|
|
return {'disk_total': 10168,
|
|
'disk_used': 0,
|
|
'disk_avail': 10168}
|
|
|
|
def get_hostname(self):
|
|
return 'fake-powervm'
|
|
|
|
def rename_lpar(self, old, new):
|
|
pass
|
|
|
|
def set_lpar_mac_base_value(self, instance_name, mac):
|
|
pass
|
|
|
|
def get_logical_vol_size(self, diskname):
|
|
pass
|
|
|
|
def macs_for_instance(self, instance):
|
|
return set(['FA:98:64:2B:29:39'])
|
|
|
|
def run_vios_command(self, cmd):
|
|
pass
|
|
|
|
|
|
class FakeBlockAdapter(powervm_blockdev.PowerVMLocalVolumeAdapter):
|
|
|
|
def __init__(self):
|
|
self.connection_data = common.Connection(host='fake_compute_1',
|
|
username='fake_user',
|
|
password='fake_pass')
|
|
pass
|
|
|
|
def _create_logical_volume(self, size):
|
|
return 'lvfake01'
|
|
|
|
def _remove_logical_volume(self, lv_name):
|
|
pass
|
|
|
|
def _copy_file_to_device(self, sourcePath, device, decrompress=True):
|
|
pass
|
|
|
|
def _copy_image_file(self, sourcePath, remotePath, decompress=False):
|
|
finalPath = '/tmp/rhel62.raw.7e358754160433febd6f3318b7c9e335'
|
|
size = 4294967296
|
|
return finalPath, size
|
|
|
|
def _copy_device_to_file(self, device_name, file_path):
|
|
pass
|
|
|
|
def _copy_image_file_from_host(self, remote_source_path, local_dest_dir,
|
|
compress=False):
|
|
snapshot_file = '/tmp/rhel62.raw.7e358754160433febd6f3318b7c9e335'
|
|
snap_ref = open(snapshot_file, 'w+')
|
|
snap_ref.close()
|
|
return snapshot_file
|
|
|
|
|
|
def fake_get_powervm_operator():
|
|
return FakeIVMOperator()
|
|
|
|
|
|
class PowerVMDriverTestCase(test.TestCase):
|
|
"""Unit tests for PowerVM connection calls."""
|
|
|
|
def setUp(self):
|
|
super(PowerVMDriverTestCase, self).setUp()
|
|
self.stubs.Set(operator, 'get_powervm_operator',
|
|
fake_get_powervm_operator)
|
|
self.stubs.Set(operator, 'get_powervm_disk_adapter',
|
|
lambda: FakeBlockAdapter())
|
|
self.powervm_connection = powervm_driver.PowerVMDriver(None)
|
|
self.instance = self._create_instance()
|
|
|
|
def _create_instance(self):
|
|
fake.stub_out_image_service(self.stubs)
|
|
ctxt = context.get_admin_context()
|
|
instance_type = db.instance_type_get(ctxt, 1)
|
|
sys_meta = instance_types.save_instance_type_info({}, instance_type)
|
|
return db.instance_create(ctxt,
|
|
{'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'instance_type_id': 1,
|
|
'memory_mb': 1024,
|
|
'vcpus': 2,
|
|
'image_ref': '155d900f-4e14-4e4c-a73d-069cbf4541e6',
|
|
'system_metadata': sys_meta})
|
|
|
|
def test_list_instances(self):
|
|
instances = self.powervm_connection.list_instances()
|
|
self.assertTrue('instance-00000001' in instances)
|
|
self.assertTrue('instance-00000002' in instances)
|
|
|
|
def test_instance_exists(self):
|
|
name = self.instance['name']
|
|
self.assertTrue(self.powervm_connection.instance_exists(name))
|
|
|
|
def test_spawn(self):
|
|
def fake_image_fetch(context, image_id, file_path,
|
|
user_id, project_id):
|
|
pass
|
|
self.flags(powervm_img_local_path='/images/')
|
|
self.stubs.Set(images, 'fetch', fake_image_fetch)
|
|
image_meta = {}
|
|
image_meta['id'] = '666'
|
|
fake_net_info = network_model.NetworkInfo([
|
|
fake_network_cache_model.new_vif()])
|
|
self.powervm_connection.spawn(context.get_admin_context(),
|
|
self.instance, image_meta, [], 's3cr3t',
|
|
fake_net_info)
|
|
state = self.powervm_connection.get_info(self.instance)['state']
|
|
self.assertEqual(state, power_state.RUNNING)
|
|
|
|
def test_spawn_cleanup_on_fail(self):
|
|
# Verify on a failed spawn, we get the original exception raised.
|
|
# helper function
|
|
def raise_(ex):
|
|
raise ex
|
|
|
|
self.flags(powervm_img_local_path='/images/')
|
|
self.stubs.Set(images, 'fetch', lambda *x, **y: None)
|
|
self.stubs.Set(
|
|
self.powervm_connection._powervm._disk_adapter,
|
|
'create_volume_from_image',
|
|
lambda *x, **y: raise_(exception.PowerVMImageCreationFailed()))
|
|
self.stubs.Set(
|
|
self.powervm_connection._powervm, '_cleanup',
|
|
lambda *x, **y: raise_(Exception('This should be logged.')))
|
|
fake_net_info = network_model.NetworkInfo([
|
|
fake_network_cache_model.new_vif()])
|
|
self.assertRaises(exception.PowerVMImageCreationFailed,
|
|
self.powervm_connection.spawn,
|
|
context.get_admin_context(),
|
|
self.instance,
|
|
{'id': 'ANY_ID'}, [], 's3cr3t', fake_net_info)
|
|
|
|
def test_snapshot(self):
|
|
|
|
def update_task_state(task_state, expected_state=None):
|
|
self._loc_task_state = task_state
|
|
self._loc_expected_task_state = expected_state
|
|
|
|
loc_context = context.get_admin_context()
|
|
properties = {'instance_id': self.instance['id'],
|
|
'user_id': str(loc_context.user_id)}
|
|
sent_meta = {'name': 'fake_snap', 'is_public': False,
|
|
'status': 'creating', 'properties': properties}
|
|
image_service = fake.FakeImageService()
|
|
recv_meta = image_service.create(loc_context, sent_meta)
|
|
|
|
self.powervm_connection.snapshot(loc_context,
|
|
self.instance, recv_meta['id'],
|
|
update_task_state)
|
|
|
|
self.assertTrue(self._loc_task_state == task_states.IMAGE_UPLOADING and
|
|
self._loc_expected_task_state == task_states.IMAGE_PENDING_UPLOAD)
|
|
|
|
def test_destroy(self):
|
|
self.powervm_connection.destroy(self.instance, None)
|
|
self.stubs.Set(FakeIVMOperator, 'get_lpar', lambda x, y: None)
|
|
name = self.instance['name']
|
|
self.assertFalse(self.powervm_connection.instance_exists(name))
|
|
|
|
def test_get_info(self):
|
|
info = self.powervm_connection.get_info(self.instance)
|
|
self.assertEqual(info['state'], power_state.RUNNING)
|
|
self.assertEqual(info['max_mem'], 2048)
|
|
self.assertEqual(info['mem'], 1024)
|
|
self.assertEqual(info['num_cpu'], 2)
|
|
self.assertEqual(info['cpu_time'], 939395)
|
|
|
|
def test_remote_utility_1(self):
|
|
path_one = '/some/file/'
|
|
path_two = '/path/filename'
|
|
joined_path = common.aix_path_join(path_one, path_two)
|
|
expected_path = '/some/file/path/filename'
|
|
self.assertEqual(joined_path, expected_path)
|
|
|
|
def test_remote_utility_2(self):
|
|
path_one = '/some/file/'
|
|
path_two = 'path/filename'
|
|
joined_path = common.aix_path_join(path_one, path_two)
|
|
expected_path = '/some/file/path/filename'
|
|
self.assertEqual(joined_path, expected_path)
|
|
|
|
def test_remote_utility_3(self):
|
|
path_one = '/some/file'
|
|
path_two = '/path/filename'
|
|
joined_path = common.aix_path_join(path_one, path_two)
|
|
expected_path = '/some/file/path/filename'
|
|
self.assertEqual(joined_path, expected_path)
|
|
|
|
def test_remote_utility_4(self):
|
|
path_one = '/some/file'
|
|
path_two = 'path/filename'
|
|
joined_path = common.aix_path_join(path_one, path_two)
|
|
expected_path = '/some/file/path/filename'
|
|
self.assertEqual(joined_path, expected_path)
|
|
|
|
def _test_finish_revert_migration_after_crash(self, backup_made, new_made):
|
|
inst = {'name': 'foo'}
|
|
network_info = []
|
|
network_info.append({'address': 'fa:89:f0:8b:9b:39'})
|
|
|
|
self.mox.StubOutWithMock(self.powervm_connection, 'instance_exists')
|
|
self.mox.StubOutWithMock(self.powervm_connection._powervm, 'destroy')
|
|
self.mox.StubOutWithMock(self.powervm_connection._powervm._operator,
|
|
'rename_lpar')
|
|
self.mox.StubOutWithMock(self.powervm_connection._powervm, 'power_on')
|
|
self.mox.StubOutWithMock(self.powervm_connection._powervm._operator,
|
|
'set_lpar_mac_base_value')
|
|
|
|
self.powervm_connection.instance_exists('rsz_foo').AndReturn(
|
|
backup_made)
|
|
|
|
if backup_made:
|
|
self.powervm_connection.instance_exists('foo').AndReturn(new_made)
|
|
if new_made:
|
|
self.powervm_connection._powervm.destroy('foo')
|
|
self.powervm_connection._powervm._operator.rename_lpar('rsz_foo',
|
|
'foo')
|
|
self.powervm_connection._powervm._operator.set_lpar_mac_base_value(
|
|
'foo', 'fa:89:f0:8b:9b:39')
|
|
self.powervm_connection._powervm.power_on('foo')
|
|
|
|
self.mox.ReplayAll()
|
|
|
|
self.powervm_connection.finish_revert_migration(inst, network_info,
|
|
block_device_info=None)
|
|
|
|
def test_finish_revert_migration_after_crash(self):
|
|
self._test_finish_revert_migration_after_crash(True, True)
|
|
|
|
def test_finish_revert_migration_after_crash_before_new(self):
|
|
self._test_finish_revert_migration_after_crash(True, False)
|
|
|
|
def test_finish_revert_migration_after_crash_before_backup(self):
|
|
self._test_finish_revert_migration_after_crash(False, False)
|
|
|
|
def test_migrate_volume_use_instance_name(self):
|
|
inst_name = 'instance-00000000'
|
|
lv_name = 'logical-vol-name'
|
|
src_host = 'compute_host_1'
|
|
dest = 'compute_host_1'
|
|
image_path = 'some/image/path'
|
|
fake_noop = lambda *args, **kwargs: None
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._disk_adapter,
|
|
'_copy_device_to_file', fake_noop)
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._disk_adapter,
|
|
'run_vios_command_as_root', fake_noop)
|
|
blockdev_op = self.powervm_connection._powervm._disk_adapter
|
|
file_path = blockdev_op.migrate_volume(lv_name, src_host, dest,
|
|
image_path, inst_name)
|
|
expected_path = 'some/image/path/instance-00000000_rsz.gz'
|
|
self.assertEqual(file_path, expected_path)
|
|
|
|
def test_migrate_volume_use_lv_name(self):
|
|
lv_name = 'logical-vol-name'
|
|
src_host = 'compute_host_1'
|
|
dest = 'compute_host_1'
|
|
image_path = 'some/image/path'
|
|
fake_noop = lambda *args, **kwargs: None
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._disk_adapter,
|
|
'_copy_device_to_file', fake_noop)
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._disk_adapter,
|
|
'run_vios_command_as_root', fake_noop)
|
|
blockdev_op = self.powervm_connection._powervm._disk_adapter
|
|
file_path = blockdev_op.migrate_volume(lv_name, src_host, dest,
|
|
image_path)
|
|
expected_path = 'some/image/path/logical-vol-name_rsz.gz'
|
|
self.assertEqual(file_path, expected_path)
|
|
|
|
def test_set_lpar_mac_base_value(self):
|
|
instance = self.instance
|
|
context = 'fake_context'
|
|
dest = '10.8.46.20' # Some fake dest IP
|
|
instance_type = 'fake_instance_type'
|
|
network_info = []
|
|
network_info.append({'address': 'fa:89:f0:8b:9b:39'})
|
|
block_device_info = None
|
|
self.flags(powervm_mgr=dest)
|
|
fake_noop = lambda *args, **kwargs: None
|
|
fake_op = self.powervm_connection._powervm._operator
|
|
self.stubs.Set(fake_op, 'get_vhost_by_instance_id', fake_noop)
|
|
self.stubs.Set(fake_op, 'get_disk_name_by_vhost', fake_noop)
|
|
self.stubs.Set(self.powervm_connection._powervm, 'power_off',
|
|
fake_noop)
|
|
self.stubs.Set(fake_op, 'get_logical_vol_size',
|
|
lambda *args, **kwargs: '20')
|
|
self.stubs.Set(self.powervm_connection, '_get_resize_name', fake_noop)
|
|
self.stubs.Set(fake_op, 'rename_lpar', fake_noop)
|
|
|
|
def fake_migrate_disk(*args, **kwargs):
|
|
disk_info = {}
|
|
disk_info['fake_dict'] = 'some/file/path.gz'
|
|
return disk_info
|
|
|
|
def fake_set_lpar_mac_base_value(inst_name, mac, *args, **kwargs):
|
|
# get expected mac address from FakeIVM set
|
|
fake_ivm = FakeIVMOperator()
|
|
exp_mac = fake_ivm.macs_for_instance(inst_name).pop()
|
|
self.assertEqual(exp_mac, mac)
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm, 'migrate_disk',
|
|
fake_migrate_disk)
|
|
self.stubs.Set(fake_op, 'set_lpar_mac_base_value',
|
|
fake_set_lpar_mac_base_value)
|
|
disk_info = self.powervm_connection.migrate_disk_and_power_off(
|
|
context, instance,
|
|
dest, instance_type, network_info, block_device_info)
|
|
|
|
def test_set_lpar_mac_base_value_command(self):
|
|
inst_name = 'some_instance'
|
|
mac = 'FA:98:64:2B:29:39'
|
|
exp_mac_str = mac[:-2].replace(':', '').lower()
|
|
|
|
def fake_run_vios_command(cmd, *args, **kwargs):
|
|
exp_cmd = ('chsyscfg -r lpar -i "name=%(inst_name)s, ',
|
|
'virtual_eth_mac_base_value=%(exp_mac_str)s"' %
|
|
locals())
|
|
assertEqual(exp_cmd, cmd)
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._operator,
|
|
'run_vios_command', fake_run_vios_command)
|
|
|
|
fake_op = self.powervm_connection._powervm
|
|
fake_op._operator.set_lpar_mac_base_value(inst_name, mac)
|
|
|
|
def test_migrate_build_scp_command(self):
|
|
lv_name = 'logical-vol-name'
|
|
src_host = 'compute_host_1'
|
|
dest = 'compute_host_2'
|
|
image_path = 'some/image/path'
|
|
fake_noop = lambda *args, **kwargs: None
|
|
|
|
@contextlib.contextmanager
|
|
def fake_vios_to_vios_auth(*args, **kwargs):
|
|
key_name = 'some_key'
|
|
yield key_name
|
|
self.stubs.Set(common, 'vios_to_vios_auth',
|
|
fake_vios_to_vios_auth)
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._disk_adapter,
|
|
'run_vios_command_as_root', fake_noop)
|
|
|
|
def fake_run_vios_command(*args, **kwargs):
|
|
cmd = args[0]
|
|
exp_cmd = ' '.join(['scp -o "StrictHostKeyChecking no" -i',
|
|
'some_key',
|
|
'some/image/path/logical-vol-name_rsz.gz',
|
|
'fake_user@compute_host_2:some/image/path'])
|
|
self.assertEqual(exp_cmd, cmd)
|
|
|
|
self.stubs.Set(self.powervm_connection._powervm._disk_adapter,
|
|
'run_vios_command',
|
|
fake_run_vios_command)
|
|
|
|
blockdev_op = self.powervm_connection._powervm._disk_adapter
|
|
file_path = blockdev_op.migrate_volume(lv_name, src_host, dest,
|
|
image_path)
|
|
|
|
def test_get_resize_name(self):
|
|
inst_name = 'instance-00000001'
|
|
expected_name = 'rsz_instance-00000001'
|
|
result = self.powervm_connection._get_resize_name(inst_name)
|
|
self.assertEqual(expected_name, result)
|
|
|
|
def test_get_long_resize_name(self):
|
|
inst_name = 'some_really_long_instance_name_00000001'
|
|
expected_name = 'rsz__really_long_instance_name_00000001'
|
|
result = self.powervm_connection._get_resize_name(inst_name)
|
|
self.assertEqual(expected_name, result)
|
|
|
|
def test_get_host_stats(self):
|
|
host_stats = self.powervm_connection.get_host_stats(True)
|
|
self.assertIsNotNone(host_stats)
|
|
self.assertEquals(host_stats['vcpus'], 8.0)
|
|
self.assertEquals(round(host_stats['vcpus_used'], 1), 1.7)
|
|
self.assertEquals(host_stats['host_memory_total'], 65536)
|
|
self.assertEquals(host_stats['host_memory_free'], 46336)
|
|
self.assertEquals(host_stats['disk_total'], 10168)
|
|
self.assertEquals(host_stats['disk_used'], 0)
|
|
self.assertEquals(host_stats['disk_available'], 10168)
|
|
self.assertEquals(host_stats['disk_total'],
|
|
host_stats['disk_used'] +
|
|
host_stats['disk_available'])
|
|
|
|
self.assertEquals(host_stats['cpu_info'], ('ppc64', 'powervm', '3940'))
|
|
self.assertEquals(host_stats['hypervisor_type'], 'powervm')
|
|
self.assertEquals(host_stats['hypervisor_version'], '7.1')
|
|
|
|
self.assertEquals(host_stats['hypervisor_hostname'], "fake-powervm")
|
|
self.assertEquals(host_stats['supported_instances'][0][0], "ppc64")
|
|
self.assertEquals(host_stats['supported_instances'][0][1], "powervm")
|
|
self.assertEquals(host_stats['supported_instances'][0][2], "hvm")
|