Fake database module for vmware vi api. Includes false injection layer at the level of API calls.
This module is base for unit tests for vmwareapi module. The unit tests runs regardless of presence of ESX/ESXi server as computer provider in OpenStack.
This commit is contained in:
207
nova/tests/test_vmwareapi.py
Normal file
207
nova/tests/test_vmwareapi.py
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2011 Citrix Systems, Inc.
|
||||||
|
# Copyright 2011 OpenStack LLC.
|
||||||
|
#
|
||||||
|
# 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 VMWareAPI
|
||||||
|
"""
|
||||||
|
import stubout
|
||||||
|
|
||||||
|
from nova import context
|
||||||
|
from nova import db
|
||||||
|
from nova import flags
|
||||||
|
from nova import test
|
||||||
|
from nova import utils
|
||||||
|
from nova.auth import manager
|
||||||
|
from nova.compute import instance_types
|
||||||
|
from nova.compute import power_state
|
||||||
|
from nova.tests.glance import stubs as glance_stubs
|
||||||
|
from nova.tests.vmwareapi import db_fakes
|
||||||
|
from nova.tests.vmwareapi import stubs
|
||||||
|
from nova.virt import vmwareapi_conn
|
||||||
|
from nova.virt.vmwareapi import fake as vmwareapi_fake
|
||||||
|
|
||||||
|
|
||||||
|
FLAGS = flags.FLAGS
|
||||||
|
|
||||||
|
|
||||||
|
class VMWareAPIVMTestCase(test.TestCase):
|
||||||
|
"""
|
||||||
|
Unit tests for Vmware API connection calls
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(VMWareAPIVMTestCase, self).setUp()
|
||||||
|
self.manager = manager.AuthManager()
|
||||||
|
self.user = self.manager.create_user('fake', 'fake', 'fake',
|
||||||
|
admin=True)
|
||||||
|
self.project = self.manager.create_project('fake', 'fake', 'fake')
|
||||||
|
self.network = utils.import_object(FLAGS.network_manager)
|
||||||
|
self.stubs = stubout.StubOutForTesting()
|
||||||
|
FLAGS.vmwareapi_host_ip = 'test_url'
|
||||||
|
FLAGS.vmwareapi_host_username = 'test_username'
|
||||||
|
FLAGS.vmwareapi_host_password = 'test_pass'
|
||||||
|
vmwareapi_fake.reset()
|
||||||
|
db_fakes.stub_out_db_instance_api(self.stubs)
|
||||||
|
stubs.set_stubs(self.stubs)
|
||||||
|
glance_stubs.stubout_glance_client(self.stubs,
|
||||||
|
glance_stubs.FakeGlance)
|
||||||
|
self.conn = vmwareapi_conn.get_connection(False)
|
||||||
|
|
||||||
|
def _create_vm(self):
|
||||||
|
""" Create and spawn the VM """
|
||||||
|
values = {'name': 1,
|
||||||
|
'id': 1,
|
||||||
|
'project_id': self.project.id,
|
||||||
|
'user_id': self.user.id,
|
||||||
|
'image_id': "1",
|
||||||
|
'kernel_id': "1",
|
||||||
|
'ramdisk_id': "1",
|
||||||
|
'instance_type': 'm1.large',
|
||||||
|
'mac_address': 'aa:bb:cc:dd:ee:ff',
|
||||||
|
}
|
||||||
|
self.instance = db.instance_create(values)
|
||||||
|
self.type_data = instance_types.INSTANCE_TYPES[values['instance_type']]
|
||||||
|
self.conn.spawn(self.instance)
|
||||||
|
self._check_vm_record()
|
||||||
|
|
||||||
|
def _check_vm_record(self):
|
||||||
|
""" Check if the spawned VM's properties corresponds to the instance in
|
||||||
|
the db """
|
||||||
|
instances = self.conn.list_instances()
|
||||||
|
self.assertEquals(len(instances), 1)
|
||||||
|
|
||||||
|
# Get Nova record for VM
|
||||||
|
vm_info = self.conn.get_info(1)
|
||||||
|
|
||||||
|
# Get XenAPI record for VM
|
||||||
|
vms = vmwareapi_fake._get_objects("VirtualMachine")
|
||||||
|
vm = vms[0]
|
||||||
|
|
||||||
|
# Check that m1.large above turned into the right thing.
|
||||||
|
mem_kib = long(self.type_data['memory_mb']) << 10
|
||||||
|
vcpus = self.type_data['vcpus']
|
||||||
|
self.assertEquals(vm_info['max_mem'], mem_kib)
|
||||||
|
self.assertEquals(vm_info['mem'], mem_kib)
|
||||||
|
self.assertEquals(vm.get("summary.config.numCpu"), vcpus)
|
||||||
|
self.assertEquals(vm.get("summary.config.memorySizeMB"),
|
||||||
|
self.type_data['memory_mb'])
|
||||||
|
|
||||||
|
# Check that the VM is running according to Nova
|
||||||
|
self.assertEquals(vm_info['state'], power_state.RUNNING)
|
||||||
|
|
||||||
|
# Check that the VM is running according to XenAPI.
|
||||||
|
self.assertEquals(vm.get("runtime.powerState"), 'poweredOn')
|
||||||
|
|
||||||
|
def _check_vm_info(self, info, pwr_state=power_state.RUNNING):
|
||||||
|
""" Check if the get_info returned values correspond to the instance
|
||||||
|
object in the db """
|
||||||
|
mem_kib = long(self.type_data['memory_mb']) << 10
|
||||||
|
self.assertEquals(info["state"], pwr_state)
|
||||||
|
self.assertEquals(info["max_mem"], mem_kib)
|
||||||
|
self.assertEquals(info["mem"], mem_kib)
|
||||||
|
self.assertEquals(info["num_cpu"], self.type_data['vcpus'])
|
||||||
|
|
||||||
|
def test_list_instances(self):
|
||||||
|
instances = self.conn.list_instances()
|
||||||
|
self.assertEquals(len(instances), 0)
|
||||||
|
|
||||||
|
def test_list_instances_1(self):
|
||||||
|
self._create_vm()
|
||||||
|
instances = self.conn.list_instances()
|
||||||
|
self.assertEquals(len(instances), 1)
|
||||||
|
|
||||||
|
def test_spawn(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
|
||||||
|
def test_snapshot(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
self.conn.snapshot(self.instance, "Test-Snapshot")
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
|
||||||
|
def test_reboot(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
self.conn.reboot(self.instance)
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
|
||||||
|
def test_suspend(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
self.conn.suspend(self.instance, self.dummy_callback_handler)
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.PAUSED)
|
||||||
|
|
||||||
|
def test_resume(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
self.conn.suspend(self.instance, self.dummy_callback_handler)
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.PAUSED)
|
||||||
|
self.conn.resume(self.instance, self.dummy_callback_handler)
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
|
||||||
|
def test_get_info(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
|
||||||
|
def test_destroy(self):
|
||||||
|
self._create_vm()
|
||||||
|
info = self.conn.get_info(1)
|
||||||
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
instances = self.conn.list_instances()
|
||||||
|
self.assertTrue(len(instances) == 1)
|
||||||
|
self.conn.destroy(self.instance)
|
||||||
|
instances = self.conn.list_instances()
|
||||||
|
self.assertTrue(len(instances) == 0)
|
||||||
|
|
||||||
|
def test_pause(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_unpause(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_diagnostics(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_get_console_output(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_get_ajax_console(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dummy_callback_handler(self, ret):
|
||||||
|
""" Dummy callback function to be passed to suspend, resume, etc.
|
||||||
|
calls """
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(VMWareAPIVMTestCase, self).tearDown()
|
||||||
|
vmwareapi_fake.cleanup()
|
||||||
|
self.manager.delete_project(self.project)
|
||||||
|
self.manager.delete_user(self.user)
|
||||||
|
self.stubs.UnsetAll()
|
16
nova/tests/vmwareapi/__init__.py
Normal file
16
nova/tests/vmwareapi/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2011 Citrix Systems, Inc.
|
||||||
|
# Copyright 2011 OpenStack LLC.
|
||||||
|
#
|
||||||
|
# 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.
|
93
nova/tests/vmwareapi/db_fakes.py
Normal file
93
nova/tests/vmwareapi/db_fakes.py
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2011 Citrix Systems, Inc.
|
||||||
|
# Copyright 2011 OpenStack LLC.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Stubouts, mocks and fixtures for the test suite
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
from nova import db
|
||||||
|
from nova import utils
|
||||||
|
from nova.compute import instance_types
|
||||||
|
|
||||||
|
|
||||||
|
def stub_out_db_instance_api(stubs):
|
||||||
|
""" Stubs out the db API for creating Instances """
|
||||||
|
|
||||||
|
class FakeModel(object):
|
||||||
|
""" Stubs out for model """
|
||||||
|
|
||||||
|
def __init__(self, values):
|
||||||
|
self.values = values
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return self.values[name]
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key in self.values:
|
||||||
|
return self.values[key]
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def fake_instance_create(values):
|
||||||
|
""" Stubs out the db.instance_create method """
|
||||||
|
|
||||||
|
type_data = instance_types.INSTANCE_TYPES[values['instance_type']]
|
||||||
|
|
||||||
|
base_options = {
|
||||||
|
'name': values['name'],
|
||||||
|
'id': values['id'],
|
||||||
|
'reservation_id': utils.generate_uid('r'),
|
||||||
|
'image_id': values['image_id'],
|
||||||
|
'kernel_id': values['kernel_id'],
|
||||||
|
'ramdisk_id': values['ramdisk_id'],
|
||||||
|
'state_description': 'scheduling',
|
||||||
|
'user_id': values['user_id'],
|
||||||
|
'project_id': values['project_id'],
|
||||||
|
'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
|
||||||
|
'instance_type': values['instance_type'],
|
||||||
|
'memory_mb': type_data['memory_mb'],
|
||||||
|
'mac_address': values['mac_address'],
|
||||||
|
'vcpus': type_data['vcpus'],
|
||||||
|
'local_gb': type_data['local_gb'],
|
||||||
|
}
|
||||||
|
return FakeModel(base_options)
|
||||||
|
|
||||||
|
def fake_network_get_by_instance(context, instance_id):
|
||||||
|
""" Stubs out the db.network_get_by_instance method """
|
||||||
|
|
||||||
|
fields = {
|
||||||
|
'bridge': 'vmnet0',
|
||||||
|
'netmask': '255.255.255.0',
|
||||||
|
'gateway': '10.10.10.1',
|
||||||
|
'vlan': 100}
|
||||||
|
return FakeModel(fields)
|
||||||
|
|
||||||
|
def fake_instance_action_create(context, action):
|
||||||
|
""" Stubs out the db.instance_action_create method """
|
||||||
|
pass
|
||||||
|
|
||||||
|
def fake_instance_get_fixed_address(context, instance_id):
|
||||||
|
""" Stubs out the db.instance_get_fixed_address method """
|
||||||
|
return '10.10.10.10'
|
||||||
|
|
||||||
|
stubs.Set(db, 'instance_create', fake_instance_create)
|
||||||
|
stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance)
|
||||||
|
stubs.Set(db, 'instance_action_create', fake_instance_action_create)
|
||||||
|
stubs.Set(db, 'instance_get_fixed_address',
|
||||||
|
fake_instance_get_fixed_address)
|
46
nova/tests/vmwareapi/stubs.py
Normal file
46
nova/tests/vmwareapi/stubs.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2011 Citrix Systems, Inc.
|
||||||
|
# Copyright 2011 OpenStack LLC.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Stubouts for the test suite
|
||||||
|
"""
|
||||||
|
|
||||||
|
from nova.virt import vmwareapi_conn
|
||||||
|
from nova.virt.vmwareapi import fake
|
||||||
|
from nova.virt.vmwareapi import vmware_images
|
||||||
|
|
||||||
|
|
||||||
|
def fake_get_vim_object(arg):
|
||||||
|
""" Stubs out the VMWareAPISession's get_vim_object method """
|
||||||
|
return fake.FakeVim()
|
||||||
|
|
||||||
|
|
||||||
|
def fake_is_vim_object(arg, module):
|
||||||
|
""" Stubs out the VMWareAPISession's is_vim_object method """
|
||||||
|
return isinstance(module, fake.FakeVim)
|
||||||
|
|
||||||
|
|
||||||
|
def set_stubs(stubs):
|
||||||
|
""" Set the stubs """
|
||||||
|
stubs.Set(vmware_images, 'fetch_image', fake.fake_fetch_image)
|
||||||
|
stubs.Set(vmware_images, 'get_vmdk_size_and_properties',
|
||||||
|
fake.fake_get_vmdk_size_and_properties)
|
||||||
|
stubs.Set(vmware_images, 'upload_image', fake.fake_upload_image)
|
||||||
|
stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
|
||||||
|
fake_get_vim_object)
|
||||||
|
stubs.Set(vmwareapi_conn.VMWareAPISession, "_is_vim_object",
|
||||||
|
fake_is_vim_object)
|
Reference in New Issue
Block a user