From aacea29de0c7cd2af25c0ca6da797ebd73719051 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Tue, 21 May 2013 17:05:47 +0000 Subject: vmwareapi: Move tests under tests/virt/vmwareapi/ Change-Id: I9665c650cc41c8dc1f3983ad85fdac9ebddc52d0 --- nova/tests/test_vmwareapi.py | 430 --------------------- nova/tests/test_vmwareapi_vif.py | 87 ----- nova/tests/test_vmwareapi_vm_util.py | 55 --- nova/tests/test_vmwareapi_vmops.py | 61 --- nova/tests/virt/vmwareapi/__init__.py | 16 + nova/tests/virt/vmwareapi/db_fakes.py | 92 +++++ nova/tests/virt/vmwareapi/stubs.py | 51 +++ nova/tests/virt/vmwareapi/test_vmwareapi.py | 430 +++++++++++++++++++++ nova/tests/virt/vmwareapi/test_vmwareapi_vif.py | 87 +++++ .../tests/virt/vmwareapi/test_vmwareapi_vm_util.py | 55 +++ nova/tests/virt/vmwareapi/test_vmwareapi_vmops.py | 61 +++ nova/tests/vmwareapi/__init__.py | 21 - nova/tests/vmwareapi/db_fakes.py | 92 ----- nova/tests/vmwareapi/stubs.py | 51 --- 14 files changed, 792 insertions(+), 797 deletions(-) delete mode 100644 nova/tests/test_vmwareapi.py delete mode 100644 nova/tests/test_vmwareapi_vif.py delete mode 100644 nova/tests/test_vmwareapi_vm_util.py delete mode 100644 nova/tests/test_vmwareapi_vmops.py create mode 100644 nova/tests/virt/vmwareapi/__init__.py create mode 100644 nova/tests/virt/vmwareapi/db_fakes.py create mode 100644 nova/tests/virt/vmwareapi/stubs.py create mode 100644 nova/tests/virt/vmwareapi/test_vmwareapi.py create mode 100644 nova/tests/virt/vmwareapi/test_vmwareapi_vif.py create mode 100644 nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py create mode 100644 nova/tests/virt/vmwareapi/test_vmwareapi_vmops.py delete mode 100644 nova/tests/vmwareapi/__init__.py delete mode 100644 nova/tests/vmwareapi/db_fakes.py delete mode 100644 nova/tests/vmwareapi/stubs.py diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py deleted file mode 100644 index f63e403d6..000000000 --- a/nova/tests/test_vmwareapi.py +++ /dev/null @@ -1,430 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2012 VMware, Inc. -# Copyright (c) 2011 Citrix Systems, Inc. -# Copyright 2011 OpenStack Foundation -# -# 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 urllib2 - -import mox -from oslo.config import cfg - -from nova.compute import power_state -from nova.compute import task_states -from nova import context -from nova import db -from nova import exception -from nova import test -import nova.tests.image.fake -from nova.tests import matchers -from nova.tests import utils -from nova.tests.vmwareapi import db_fakes -from nova.tests.vmwareapi import stubs -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import fake as vmwareapi_fake -from nova.virt.vmwareapi import vim -from nova.virt.vmwareapi import vm_util - - -class fake_vm_ref(object): - def __init__(self): - self.value = 4 - self._type = 'VirtualMachine' - - -class fake_http_resp(object): - def __init__(self): - self.code = 200 - - def read(self): - return "console log" - - -class VMwareAPIConfTestCase(test.TestCase): - """Unit tests for VMWare API configurations.""" - def setUp(self): - super(VMwareAPIConfTestCase, self).setUp() - - def tearDown(self): - super(VMwareAPIConfTestCase, self).tearDown() - - def test_configure_without_wsdl_loc_override(self): - # Test the default configuration behavior. By default, - # use the WSDL sitting on the host we are talking to in - # order to bind the SOAP client. - wsdl_loc = cfg.CONF.vmwareapi_wsdl_loc - self.assertIsNone(wsdl_loc) - wsdl_url = vim.Vim.get_wsdl_url("https", "www.example.com") - url = vim.Vim.get_soap_url("https", "www.example.com") - self.assertEqual("https://www.example.com/sdk/vimService.wsdl", - wsdl_url) - self.assertEqual("https://www.example.com/sdk", url) - - def test_configure_with_wsdl_loc_override(self): - # Use the setting vmwareapi_wsdl_loc to override the - # default path to the WSDL. - # - # This is useful as a work-around for XML parsing issues - # found when using some WSDL in combination with some XML - # parsers. - # - # The wsdl_url should point to a different host than the one we - # are actually going to send commands to. - fake_wsdl = "https://www.test.com/sdk/foo.wsdl" - self.flags(vmwareapi_wsdl_loc=fake_wsdl) - wsdl_loc = cfg.CONF.vmwareapi_wsdl_loc - self.assertIsNotNone(wsdl_loc) - self.assertEqual(fake_wsdl, wsdl_loc) - wsdl_url = vim.Vim.get_wsdl_url("https", "www.example.com") - url = vim.Vim.get_soap_url("https", "www.example.com") - self.assertEqual(fake_wsdl, wsdl_url) - self.assertEqual("https://www.example.com/sdk", url) - - -class VMwareAPIVMTestCase(test.TestCase): - """Unit tests for Vmware API connection calls.""" - - def setUp(self): - super(VMwareAPIVMTestCase, self).setUp() - self.context = context.RequestContext('fake', 'fake', is_admin=False) - self.flags(vmwareapi_host_ip='test_url', - vmwareapi_host_username='test_username', - vmwareapi_host_password='test_pass', - vnc_enabled=False, - use_linked_clone=False) - self.user_id = 'fake' - self.project_id = 'fake' - self.context = context.RequestContext(self.user_id, self.project_id) - vmwareapi_fake.reset() - db_fakes.stub_out_db_instance_api(self.stubs) - stubs.set_stubs(self.stubs) - self.conn = driver.VMwareESXDriver(None, False) - # NOTE(vish): none of the network plugging code is actually - # being tested - self.network_info = utils.get_test_network_info(legacy_model=False) - - self.image = { - 'id': 'c1c8ce3d-c2e0-4247-890c-ccf5cc1c004c', - 'disk_format': 'vhd', - 'size': 512, - } - nova.tests.image.fake.stub_out_image_service(self.stubs) - - def tearDown(self): - super(VMwareAPIVMTestCase, self).tearDown() - vmwareapi_fake.cleanup() - nova.tests.image.fake.FakeImageService_reset() - - def _create_instance_in_the_db(self): - values = {'name': 1, - 'id': 1, - 'project_id': self.project_id, - 'user_id': self.user_id, - 'image_ref': "1", - 'kernel_id': "1", - 'ramdisk_id': "1", - 'mac_address': "de:ad:be:ef:be:ef", - 'instance_type': 'm1.large', - } - self.instance = db.instance_create(None, values) - - def _create_vm(self): - """Create and spawn the VM.""" - self._create_instance_in_the_db() - self.type_data = db.instance_type_get_by_name(None, 'm1.large') - self.conn.spawn(self.context, self.instance, self.image, - injected_files=[], admin_password=None, - network_info=self.network_info, - block_device_info=None) - self._check_vm_record() - - def _check_vm_record(self): - """ - Check if the spawned VM's properties correspond 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({'name': 1}) - - # Get 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 vSphere API. - 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_list_interfaces(self): - self._create_vm() - interfaces = self.conn.list_interfaces(1) - self.assertEquals(len(interfaces), 1) - self.assertEquals(interfaces[0], 4000) - - def test_spawn(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - - def test_snapshot(self): - expected_calls = [ - {'args': (), - 'kwargs': - {'task_state': task_states.IMAGE_PENDING_UPLOAD}}, - {'args': (), - 'kwargs': - {'task_state': task_states.IMAGE_UPLOADING, - 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}] - func_call_matcher = matchers.FunctionCallMatcher(expected_calls) - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.snapshot(self.context, self.instance, "Test-Snapshot", - func_call_matcher.call) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.assertIsNone(func_call_matcher.match()) - - def test_snapshot_non_existent(self): - self._create_instance_in_the_db() - self.assertRaises(exception.InstanceNotFound, self.conn.snapshot, - self.context, self.instance, "Test-Snapshot", - lambda *args, **kwargs: None) - - def test_reboot(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - reboot_type = "SOFT" - self.conn.reboot(self.context, self.instance, self.network_info, - reboot_type) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - - def test_reboot_non_existent(self): - self._create_instance_in_the_db() - self.assertRaises(exception.InstanceNotFound, self.conn.reboot, - self.context, self.instance, self.network_info, - 'SOFT') - - def test_reboot_not_poweredon(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.suspend(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.SUSPENDED) - self.assertRaises(exception.InstanceRebootFailure, self.conn.reboot, - self.context, self.instance, self.network_info, - 'SOFT') - - def test_suspend(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.suspend(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.SUSPENDED) - - def test_suspend_non_existent(self): - self._create_instance_in_the_db() - self.assertRaises(exception.InstanceNotFound, self.conn.suspend, - self.instance) - - def test_resume(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.suspend(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.SUSPENDED) - self.conn.resume(self.instance, self.network_info) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - - def test_resume_non_existent(self): - self._create_instance_in_the_db() - self.assertRaises(exception.InstanceNotFound, self.conn.resume, - self.instance, self.network_info) - - def test_resume_not_suspended(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.assertRaises(exception.InstanceResumeFailure, self.conn.resume, - self.instance, self.network_info) - - def test_power_on(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.power_off(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.SHUTDOWN) - self.conn.power_on(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - - def test_power_on_non_existent(self): - self._create_instance_in_the_db() - self.assertRaises(exception.InstanceNotFound, self.conn.power_on, - self.instance) - - def test_power_off(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.power_off(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.SHUTDOWN) - - def test_power_off_non_existent(self): - self._create_instance_in_the_db() - self.assertRaises(exception.InstanceNotFound, self.conn.power_off, - self.instance) - - def test_power_off_suspended(self): - self._create_vm() - self.conn.suspend(self.instance) - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.SUSPENDED) - self.assertRaises(exception.InstancePowerOffFailure, - self.conn.power_off, self.instance) - - def test_get_info(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - - def test_destroy(self): - self._create_vm() - info = self.conn.get_info({'name': 1}) - self._check_vm_info(info, power_state.RUNNING) - instances = self.conn.list_instances() - self.assertEquals(len(instances), 1) - self.conn.destroy(self.instance, self.network_info) - instances = self.conn.list_instances() - self.assertEquals(len(instances), 0) - - def test_destroy_non_existent(self): - self._create_instance_in_the_db() - self.assertEquals(self.conn.destroy(self.instance, self.network_info), - None) - - def test_pause(self): - pass - - def test_unpause(self): - pass - - def test_diagnostics(self): - pass - - def test_get_console_output(self): - vm_ref = fake_vm_ref() - result = fake_http_resp() - self._create_instance_in_the_db() - self.mox.StubOutWithMock(vm_util, 'get_vm_ref_from_name') - self.mox.StubOutWithMock(urllib2, 'urlopen') - vm_util.get_vm_ref_from_name(mox.IgnoreArg(), self.instance['name']).\ - AndReturn(vm_ref) - urllib2.urlopen(mox.IgnoreArg()).AndReturn(result) - - self.mox.ReplayAll() - self.conn.get_console_output(self.instance) - - -class VMwareAPIHostTestCase(test.TestCase): - """Unit tests for Vmware API host calls.""" - - def setUp(self): - super(VMwareAPIHostTestCase, self).setUp() - self.flags(vmwareapi_host_ip='test_url', - vmwareapi_host_username='test_username', - vmwareapi_host_password='test_pass') - vmwareapi_fake.reset() - stubs.set_stubs(self.stubs) - self.conn = driver.VMwareESXDriver(False) - - def tearDown(self): - super(VMwareAPIHostTestCase, self).tearDown() - vmwareapi_fake.cleanup() - - def test_host_state(self): - stats = self.conn.get_host_stats() - self.assertEquals(stats['vcpus'], 16) - self.assertEquals(stats['disk_total'], 1024) - self.assertEquals(stats['disk_available'], 500) - self.assertEquals(stats['disk_used'], 1024 - 500) - self.assertEquals(stats['host_memory_total'], 1024) - self.assertEquals(stats['host_memory_free'], 1024 - 500) - supported_instances = [('i686', 'vmware', 'hvm'), - ('x86_64', 'vmware', 'hvm')] - self.assertEquals(stats['supported_instances'], supported_instances) - - def _test_host_action(self, method, action, expected=None): - result = method('host', action) - self.assertEqual(result, expected) - - def test_host_reboot(self): - self._test_host_action(self.conn.host_power_action, 'reboot') - - def test_host_shutdown(self): - self._test_host_action(self.conn.host_power_action, 'shutdown') - - def test_host_startup(self): - self._test_host_action(self.conn.host_power_action, 'startup') - - def test_host_maintenance_on(self): - self._test_host_action(self.conn.host_maintenance_mode, True) - - def test_host_maintenance_off(self): - self._test_host_action(self.conn.host_maintenance_mode, False) diff --git a/nova/tests/test_vmwareapi_vif.py b/nova/tests/test_vmwareapi_vif.py deleted file mode 100644 index 043885543..000000000 --- a/nova/tests/test_vmwareapi_vif.py +++ /dev/null @@ -1,87 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Canonical Corp. -# All Rights Reserved. -# -# 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. - -from nova.network import model as network_model -from nova import test -from nova.virt.vmwareapi import network_util -from nova.virt.vmwareapi import vif - - -class VMwareVifTestCase(test.TestCase): - def setUp(self): - super(VMwareVifTestCase, self).setUp() - self.flags(vmwareapi_vlan_interface='vmnet0') - network = network_model.Network(id=0, - bridge='fa0', - label='fake', - vlan=3, - bridge_interface='eth0', - injected=True) - - self.vif = network_model.NetworkInfo([ - network_model.VIF(id=None, - address='DE:AD:BE:EF:00:00', - network=network, - type=None, - devname=None, - ovs_interfaceid=None, - rxtx_cap=3) - ])[0] - self.session = "fake" - self.cluster = None - - def tearDown(self): - super(VMwareVifTestCase, self).tearDown() - - def test_ensure_vlan_bridge(self): - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - self.mox.StubOutWithMock(network_util, - 'get_vswitch_for_vlan_interface') - self.mox.StubOutWithMock(network_util, - 'check_if_vlan_interface_exists') - self.mox.StubOutWithMock(network_util, 'create_port_group') - network_util.get_network_with_the_name(self.session, 'fa0', - self.cluster).AndReturn(None) - network_util.get_vswitch_for_vlan_interface(self.session, 'vmnet0', - self.cluster).AndReturn('vmnet0') - network_util.check_if_vlan_interface_exists(self.session, 'vmnet0', - self.cluster).AndReturn(True) - network_util.create_port_group(self.session, 'fa0', 'vmnet0', 3, - self.cluster) - - self.mox.ReplayAll() - vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=True) - - # FlatDHCP network mode without vlan - def test_ensure_vlan_bridge_without_vlan(self): - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - self.mox.StubOutWithMock(network_util, - 'get_vswitch_for_vlan_interface') - self.mox.StubOutWithMock(network_util, - 'check_if_vlan_interface_exists') - self.mox.StubOutWithMock(network_util, 'create_port_group') - - network_util.get_network_with_the_name(self.session, 'fa0', - self.cluster).AndReturn(None) - network_util.get_vswitch_for_vlan_interface(self.session, 'vmnet0', - self.cluster).AndReturn('vmnet0') - network_util.check_if_vlan_interface_exists(self.session, 'vmnet0', - self.cluster).AndReturn(True) - network_util.create_port_group(self.session, 'fa0', 'vmnet0', 0, - self.cluster) - self.mox.ReplayAll() - vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=False) diff --git a/nova/tests/test_vmwareapi_vm_util.py b/nova/tests/test_vmwareapi_vm_util.py deleted file mode 100644 index eda2c25f9..000000000 --- a/nova/tests/test_vmwareapi_vm_util.py +++ /dev/null @@ -1,55 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 Canonical Corp. -# All Rights Reserved. -# -# 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. - -from nova import exception -from nova import test -from nova.virt.vmwareapi import fake -from nova.virt.vmwareapi import vm_util - - -class fake_session(object): - def __init__(self, ret=None): - self.ret = ret - - def _call_method(self, *args): - return self.ret - - -class VMwareVMUtilTestCase(test.TestCase): - def setUp(self): - super(VMwareVMUtilTestCase, self).setUp() - - def tearDown(self): - super(VMwareVMUtilTestCase, self).tearDown() - - def test_get_datastore_ref_and_name(self): - result = vm_util.get_datastore_ref_and_name( - fake_session([fake.Datastore()])) - - self.assertEquals(result[1], "fake-ds") - self.assertEquals(result[2], 1024 * 1024 * 1024) - self.assertEquals(result[3], 1024 * 1024 * 500) - - def test_get_datastore_ref_and_name_without_datastore(self): - - self.assertRaises(exception.DatastoreNotFound, - vm_util.get_datastore_ref_and_name, - fake_session(), host="fake-host") - - self.assertRaises(exception.DatastoreNotFound, - vm_util.get_datastore_ref_and_name, - fake_session(), cluster="fake-cluster") diff --git a/nova/tests/test_vmwareapi_vmops.py b/nova/tests/test_vmwareapi_vmops.py deleted file mode 100644 index 92bca8ae7..000000000 --- a/nova/tests/test_vmwareapi_vmops.py +++ /dev/null @@ -1,61 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# -# Copyright 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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. - -from nova.network import model as network_model -from nova import test -from nova.virt.vmwareapi import vmops - - -class VMwareVMOpsTestCase(test.TestCase): - def setUp(self): - super(VMwareVMOpsTestCase, self).setUp() - subnet_4 = network_model.Subnet(cidr='192.168.0.1/24', - dns=[network_model.IP('192.168.0.1')], - gateway= - network_model.IP('192.168.0.1'), - ips=[ - network_model.IP('192.168.0.100')], - routes=None) - subnet_6 = network_model.Subnet(cidr='dead:beef::1/64', - dns=None, - gateway= - network_model.IP('dead:beef::1'), - ips=[network_model.IP( - 'dead:beef::dcad:beff:feef:0')], - routes=None) - network = network_model.Network(id=0, - bridge='fa0', - label='fake', - subnets=[subnet_4, subnet_6], - vlan=None, - bridge_interface=None, - injected=True) - self.network_info = network_model.NetworkInfo([ - network_model.VIF(id=None, - address='DE:AD:BE:EF:00:00', - network=network, - type=None, - devname=None, - ovs_interfaceid=None, - rxtx_cap=3) - ]) - - def test_get_machine_id_str(self): - result = vmops.VMwareVMOps._get_machine_id_str(self.network_info) - self.assertEqual(result, - 'DE:AD:BE:EF:00:00;192.168.0.100;255.255.255.0;' - '192.168.0.1;192.168.0.255;192.168.0.1#') diff --git a/nova/tests/virt/vmwareapi/__init__.py b/nova/tests/virt/vmwareapi/__init__.py new file mode 100644 index 000000000..fcf71c88d --- /dev/null +++ b/nova/tests/virt/vmwareapi/__init__.py @@ -0,0 +1,16 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# +# 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. diff --git a/nova/tests/virt/vmwareapi/db_fakes.py b/nova/tests/virt/vmwareapi/db_fakes.py new file mode 100644 index 000000000..54e3cf43b --- /dev/null +++ b/nova/tests/virt/vmwareapi/db_fakes.py @@ -0,0 +1,92 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# +# 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 +import uuid + +from nova.compute import task_states +from nova.compute import vm_states +from nova import db +from nova import utils + + +def stub_out_db_instance_api(stubs): + """Stubs out the db API for creating Instances.""" + + INSTANCE_TYPES = { + 'm1.tiny': dict(memory_mb=512, vcpus=1, root_gb=0, flavorid=1), + 'm1.small': dict(memory_mb=2048, vcpus=1, root_gb=20, flavorid=2), + 'm1.medium': + dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3), + 'm1.large': dict(memory_mb=8192, vcpus=4, root_gb=80, flavorid=4), + 'm1.xlarge': + dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5)} + + 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(context, values): + """Stubs out the db.instance_create method.""" + + type_data = INSTANCE_TYPES[values['instance_type']] + + base_options = { + 'name': values['name'], + 'id': values['id'], + 'uuid': uuid.uuid4(), + 'reservation_id': utils.generate_uid('r'), + 'image_ref': values['image_ref'], + 'kernel_id': values['kernel_id'], + 'ramdisk_id': values['ramdisk_id'], + 'vm_state': vm_states.BUILDING, + 'task_state': task_states.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'], + 'vcpus': type_data['vcpus'], + 'mac_addresses': [{'address': values['mac_address']}], + 'root_gb': type_data['root_gb'], + } + return FakeModel(base_options) + + def fake_instance_type_get_all(context, inactive=0, filters=None): + return INSTANCE_TYPES.values() + + def fake_instance_type_get_by_name(context, name): + return INSTANCE_TYPES[name] + + stubs.Set(db, 'instance_create', fake_instance_create) + stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all) + stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name) diff --git a/nova/tests/virt/vmwareapi/stubs.py b/nova/tests/virt/vmwareapi/stubs.py new file mode 100644 index 000000000..dc87b2355 --- /dev/null +++ b/nova/tests/virt/vmwareapi/stubs.py @@ -0,0 +1,51 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# +# 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.vmwareapi import driver +from nova.virt.vmwareapi import fake +from nova.virt.vmwareapi import network_util +from nova.virt.vmwareapi import vmops +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(vmops.VMwareVMOps, 'plug_vifs', fake.fake_plug_vifs) + stubs.Set(network_util, 'get_network_with_the_name', + fake.fake_get_network) + 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(driver.VMwareAPISession, "_get_vim_object", + fake_get_vim_object) + stubs.Set(driver.VMwareAPISession, "_is_vim_object", + fake_is_vim_object) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py new file mode 100644 index 000000000..9508a5805 --- /dev/null +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -0,0 +1,430 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2012 VMware, Inc. +# Copyright (c) 2011 Citrix Systems, Inc. +# Copyright 2011 OpenStack Foundation +# +# 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 urllib2 + +import mox +from oslo.config import cfg + +from nova.compute import power_state +from nova.compute import task_states +from nova import context +from nova import db +from nova import exception +from nova import test +import nova.tests.image.fake +from nova.tests import matchers +from nova.tests import utils +from nova.tests.virt.vmwareapi import db_fakes +from nova.tests.virt.vmwareapi import stubs +from nova.virt.vmwareapi import driver +from nova.virt.vmwareapi import fake as vmwareapi_fake +from nova.virt.vmwareapi import vim +from nova.virt.vmwareapi import vm_util + + +class fake_vm_ref(object): + def __init__(self): + self.value = 4 + self._type = 'VirtualMachine' + + +class fake_http_resp(object): + def __init__(self): + self.code = 200 + + def read(self): + return "console log" + + +class VMwareAPIConfTestCase(test.TestCase): + """Unit tests for VMWare API configurations.""" + def setUp(self): + super(VMwareAPIConfTestCase, self).setUp() + + def tearDown(self): + super(VMwareAPIConfTestCase, self).tearDown() + + def test_configure_without_wsdl_loc_override(self): + # Test the default configuration behavior. By default, + # use the WSDL sitting on the host we are talking to in + # order to bind the SOAP client. + wsdl_loc = cfg.CONF.vmwareapi_wsdl_loc + self.assertIsNone(wsdl_loc) + wsdl_url = vim.Vim.get_wsdl_url("https", "www.example.com") + url = vim.Vim.get_soap_url("https", "www.example.com") + self.assertEqual("https://www.example.com/sdk/vimService.wsdl", + wsdl_url) + self.assertEqual("https://www.example.com/sdk", url) + + def test_configure_with_wsdl_loc_override(self): + # Use the setting vmwareapi_wsdl_loc to override the + # default path to the WSDL. + # + # This is useful as a work-around for XML parsing issues + # found when using some WSDL in combination with some XML + # parsers. + # + # The wsdl_url should point to a different host than the one we + # are actually going to send commands to. + fake_wsdl = "https://www.test.com/sdk/foo.wsdl" + self.flags(vmwareapi_wsdl_loc=fake_wsdl) + wsdl_loc = cfg.CONF.vmwareapi_wsdl_loc + self.assertIsNotNone(wsdl_loc) + self.assertEqual(fake_wsdl, wsdl_loc) + wsdl_url = vim.Vim.get_wsdl_url("https", "www.example.com") + url = vim.Vim.get_soap_url("https", "www.example.com") + self.assertEqual(fake_wsdl, wsdl_url) + self.assertEqual("https://www.example.com/sdk", url) + + +class VMwareAPIVMTestCase(test.TestCase): + """Unit tests for Vmware API connection calls.""" + + def setUp(self): + super(VMwareAPIVMTestCase, self).setUp() + self.context = context.RequestContext('fake', 'fake', is_admin=False) + self.flags(vmwareapi_host_ip='test_url', + vmwareapi_host_username='test_username', + vmwareapi_host_password='test_pass', + vnc_enabled=False, + use_linked_clone=False) + self.user_id = 'fake' + self.project_id = 'fake' + self.context = context.RequestContext(self.user_id, self.project_id) + vmwareapi_fake.reset() + db_fakes.stub_out_db_instance_api(self.stubs) + stubs.set_stubs(self.stubs) + self.conn = driver.VMwareESXDriver(None, False) + # NOTE(vish): none of the network plugging code is actually + # being tested + self.network_info = utils.get_test_network_info(legacy_model=False) + + self.image = { + 'id': 'c1c8ce3d-c2e0-4247-890c-ccf5cc1c004c', + 'disk_format': 'vhd', + 'size': 512, + } + nova.tests.image.fake.stub_out_image_service(self.stubs) + + def tearDown(self): + super(VMwareAPIVMTestCase, self).tearDown() + vmwareapi_fake.cleanup() + nova.tests.image.fake.FakeImageService_reset() + + def _create_instance_in_the_db(self): + values = {'name': 1, + 'id': 1, + 'project_id': self.project_id, + 'user_id': self.user_id, + 'image_ref': "1", + 'kernel_id': "1", + 'ramdisk_id': "1", + 'mac_address': "de:ad:be:ef:be:ef", + 'instance_type': 'm1.large', + } + self.instance = db.instance_create(None, values) + + def _create_vm(self): + """Create and spawn the VM.""" + self._create_instance_in_the_db() + self.type_data = db.instance_type_get_by_name(None, 'm1.large') + self.conn.spawn(self.context, self.instance, self.image, + injected_files=[], admin_password=None, + network_info=self.network_info, + block_device_info=None) + self._check_vm_record() + + def _check_vm_record(self): + """ + Check if the spawned VM's properties correspond 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({'name': 1}) + + # Get 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 vSphere API. + 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_list_interfaces(self): + self._create_vm() + interfaces = self.conn.list_interfaces(1) + self.assertEquals(len(interfaces), 1) + self.assertEquals(interfaces[0], 4000) + + def test_spawn(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + + def test_snapshot(self): + expected_calls = [ + {'args': (), + 'kwargs': + {'task_state': task_states.IMAGE_PENDING_UPLOAD}}, + {'args': (), + 'kwargs': + {'task_state': task_states.IMAGE_UPLOADING, + 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}] + func_call_matcher = matchers.FunctionCallMatcher(expected_calls) + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.conn.snapshot(self.context, self.instance, "Test-Snapshot", + func_call_matcher.call) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.assertIsNone(func_call_matcher.match()) + + def test_snapshot_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, self.conn.snapshot, + self.context, self.instance, "Test-Snapshot", + lambda *args, **kwargs: None) + + def test_reboot(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + reboot_type = "SOFT" + self.conn.reboot(self.context, self.instance, self.network_info, + reboot_type) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + + def test_reboot_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, self.conn.reboot, + self.context, self.instance, self.network_info, + 'SOFT') + + def test_reboot_not_poweredon(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.conn.suspend(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.SUSPENDED) + self.assertRaises(exception.InstanceRebootFailure, self.conn.reboot, + self.context, self.instance, self.network_info, + 'SOFT') + + def test_suspend(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.conn.suspend(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.SUSPENDED) + + def test_suspend_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, self.conn.suspend, + self.instance) + + def test_resume(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.conn.suspend(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.SUSPENDED) + self.conn.resume(self.instance, self.network_info) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + + def test_resume_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, self.conn.resume, + self.instance, self.network_info) + + def test_resume_not_suspended(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.assertRaises(exception.InstanceResumeFailure, self.conn.resume, + self.instance, self.network_info) + + def test_power_on(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.conn.power_off(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.SHUTDOWN) + self.conn.power_on(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + + def test_power_on_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, self.conn.power_on, + self.instance) + + def test_power_off(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + self.conn.power_off(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.SHUTDOWN) + + def test_power_off_non_existent(self): + self._create_instance_in_the_db() + self.assertRaises(exception.InstanceNotFound, self.conn.power_off, + self.instance) + + def test_power_off_suspended(self): + self._create_vm() + self.conn.suspend(self.instance) + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.SUSPENDED) + self.assertRaises(exception.InstancePowerOffFailure, + self.conn.power_off, self.instance) + + def test_get_info(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + + def test_destroy(self): + self._create_vm() + info = self.conn.get_info({'name': 1}) + self._check_vm_info(info, power_state.RUNNING) + instances = self.conn.list_instances() + self.assertEquals(len(instances), 1) + self.conn.destroy(self.instance, self.network_info) + instances = self.conn.list_instances() + self.assertEquals(len(instances), 0) + + def test_destroy_non_existent(self): + self._create_instance_in_the_db() + self.assertEquals(self.conn.destroy(self.instance, self.network_info), + None) + + def test_pause(self): + pass + + def test_unpause(self): + pass + + def test_diagnostics(self): + pass + + def test_get_console_output(self): + vm_ref = fake_vm_ref() + result = fake_http_resp() + self._create_instance_in_the_db() + self.mox.StubOutWithMock(vm_util, 'get_vm_ref_from_name') + self.mox.StubOutWithMock(urllib2, 'urlopen') + vm_util.get_vm_ref_from_name(mox.IgnoreArg(), self.instance['name']).\ + AndReturn(vm_ref) + urllib2.urlopen(mox.IgnoreArg()).AndReturn(result) + + self.mox.ReplayAll() + self.conn.get_console_output(self.instance) + + +class VMwareAPIHostTestCase(test.TestCase): + """Unit tests for Vmware API host calls.""" + + def setUp(self): + super(VMwareAPIHostTestCase, self).setUp() + self.flags(vmwareapi_host_ip='test_url', + vmwareapi_host_username='test_username', + vmwareapi_host_password='test_pass') + vmwareapi_fake.reset() + stubs.set_stubs(self.stubs) + self.conn = driver.VMwareESXDriver(False) + + def tearDown(self): + super(VMwareAPIHostTestCase, self).tearDown() + vmwareapi_fake.cleanup() + + def test_host_state(self): + stats = self.conn.get_host_stats() + self.assertEquals(stats['vcpus'], 16) + self.assertEquals(stats['disk_total'], 1024) + self.assertEquals(stats['disk_available'], 500) + self.assertEquals(stats['disk_used'], 1024 - 500) + self.assertEquals(stats['host_memory_total'], 1024) + self.assertEquals(stats['host_memory_free'], 1024 - 500) + supported_instances = [('i686', 'vmware', 'hvm'), + ('x86_64', 'vmware', 'hvm')] + self.assertEquals(stats['supported_instances'], supported_instances) + + def _test_host_action(self, method, action, expected=None): + result = method('host', action) + self.assertEqual(result, expected) + + def test_host_reboot(self): + self._test_host_action(self.conn.host_power_action, 'reboot') + + def test_host_shutdown(self): + self._test_host_action(self.conn.host_power_action, 'shutdown') + + def test_host_startup(self): + self._test_host_action(self.conn.host_power_action, 'startup') + + def test_host_maintenance_on(self): + self._test_host_action(self.conn.host_maintenance_mode, True) + + def test_host_maintenance_off(self): + self._test_host_action(self.conn.host_maintenance_mode, False) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vif.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vif.py new file mode 100644 index 000000000..043885543 --- /dev/null +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vif.py @@ -0,0 +1,87 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2013 Canonical Corp. +# All Rights Reserved. +# +# 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. + +from nova.network import model as network_model +from nova import test +from nova.virt.vmwareapi import network_util +from nova.virt.vmwareapi import vif + + +class VMwareVifTestCase(test.TestCase): + def setUp(self): + super(VMwareVifTestCase, self).setUp() + self.flags(vmwareapi_vlan_interface='vmnet0') + network = network_model.Network(id=0, + bridge='fa0', + label='fake', + vlan=3, + bridge_interface='eth0', + injected=True) + + self.vif = network_model.NetworkInfo([ + network_model.VIF(id=None, + address='DE:AD:BE:EF:00:00', + network=network, + type=None, + devname=None, + ovs_interfaceid=None, + rxtx_cap=3) + ])[0] + self.session = "fake" + self.cluster = None + + def tearDown(self): + super(VMwareVifTestCase, self).tearDown() + + def test_ensure_vlan_bridge(self): + self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') + self.mox.StubOutWithMock(network_util, + 'get_vswitch_for_vlan_interface') + self.mox.StubOutWithMock(network_util, + 'check_if_vlan_interface_exists') + self.mox.StubOutWithMock(network_util, 'create_port_group') + network_util.get_network_with_the_name(self.session, 'fa0', + self.cluster).AndReturn(None) + network_util.get_vswitch_for_vlan_interface(self.session, 'vmnet0', + self.cluster).AndReturn('vmnet0') + network_util.check_if_vlan_interface_exists(self.session, 'vmnet0', + self.cluster).AndReturn(True) + network_util.create_port_group(self.session, 'fa0', 'vmnet0', 3, + self.cluster) + + self.mox.ReplayAll() + vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=True) + + # FlatDHCP network mode without vlan + def test_ensure_vlan_bridge_without_vlan(self): + self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') + self.mox.StubOutWithMock(network_util, + 'get_vswitch_for_vlan_interface') + self.mox.StubOutWithMock(network_util, + 'check_if_vlan_interface_exists') + self.mox.StubOutWithMock(network_util, 'create_port_group') + + network_util.get_network_with_the_name(self.session, 'fa0', + self.cluster).AndReturn(None) + network_util.get_vswitch_for_vlan_interface(self.session, 'vmnet0', + self.cluster).AndReturn('vmnet0') + network_util.check_if_vlan_interface_exists(self.session, 'vmnet0', + self.cluster).AndReturn(True) + network_util.create_port_group(self.session, 'fa0', 'vmnet0', 0, + self.cluster) + self.mox.ReplayAll() + vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=False) diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py new file mode 100644 index 000000000..eda2c25f9 --- /dev/null +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py @@ -0,0 +1,55 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2013 Canonical Corp. +# All Rights Reserved. +# +# 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. + +from nova import exception +from nova import test +from nova.virt.vmwareapi import fake +from nova.virt.vmwareapi import vm_util + + +class fake_session(object): + def __init__(self, ret=None): + self.ret = ret + + def _call_method(self, *args): + return self.ret + + +class VMwareVMUtilTestCase(test.TestCase): + def setUp(self): + super(VMwareVMUtilTestCase, self).setUp() + + def tearDown(self): + super(VMwareVMUtilTestCase, self).tearDown() + + def test_get_datastore_ref_and_name(self): + result = vm_util.get_datastore_ref_and_name( + fake_session([fake.Datastore()])) + + self.assertEquals(result[1], "fake-ds") + self.assertEquals(result[2], 1024 * 1024 * 1024) + self.assertEquals(result[3], 1024 * 1024 * 500) + + def test_get_datastore_ref_and_name_without_datastore(self): + + self.assertRaises(exception.DatastoreNotFound, + vm_util.get_datastore_ref_and_name, + fake_session(), host="fake-host") + + self.assertRaises(exception.DatastoreNotFound, + vm_util.get_datastore_ref_and_name, + fake_session(), cluster="fake-cluster") diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vmops.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vmops.py new file mode 100644 index 000000000..92bca8ae7 --- /dev/null +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vmops.py @@ -0,0 +1,61 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2013 OpenStack Foundation +# All Rights Reserved. +# +# 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. + +from nova.network import model as network_model +from nova import test +from nova.virt.vmwareapi import vmops + + +class VMwareVMOpsTestCase(test.TestCase): + def setUp(self): + super(VMwareVMOpsTestCase, self).setUp() + subnet_4 = network_model.Subnet(cidr='192.168.0.1/24', + dns=[network_model.IP('192.168.0.1')], + gateway= + network_model.IP('192.168.0.1'), + ips=[ + network_model.IP('192.168.0.100')], + routes=None) + subnet_6 = network_model.Subnet(cidr='dead:beef::1/64', + dns=None, + gateway= + network_model.IP('dead:beef::1'), + ips=[network_model.IP( + 'dead:beef::dcad:beff:feef:0')], + routes=None) + network = network_model.Network(id=0, + bridge='fa0', + label='fake', + subnets=[subnet_4, subnet_6], + vlan=None, + bridge_interface=None, + injected=True) + self.network_info = network_model.NetworkInfo([ + network_model.VIF(id=None, + address='DE:AD:BE:EF:00:00', + network=network, + type=None, + devname=None, + ovs_interfaceid=None, + rxtx_cap=3) + ]) + + def test_get_machine_id_str(self): + result = vmops.VMwareVMOps._get_machine_id_str(self.network_info) + self.assertEqual(result, + 'DE:AD:BE:EF:00:00;192.168.0.100;255.255.255.0;' + '192.168.0.1;192.168.0.255;192.168.0.1#') diff --git a/nova/tests/vmwareapi/__init__.py b/nova/tests/vmwareapi/__init__.py deleted file mode 100644 index d22b919f3..000000000 --- a/nova/tests/vmwareapi/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Citrix Systems, Inc. -# Copyright 2011 OpenStack Foundation -# -# 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. - -""" -:mod:`vmwareapi` -- Stubs for VMware API -======================================= -""" diff --git a/nova/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py deleted file mode 100644 index 54e3cf43b..000000000 --- a/nova/tests/vmwareapi/db_fakes.py +++ /dev/null @@ -1,92 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Citrix Systems, Inc. -# Copyright 2011 OpenStack Foundation -# -# 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 -import uuid - -from nova.compute import task_states -from nova.compute import vm_states -from nova import db -from nova import utils - - -def stub_out_db_instance_api(stubs): - """Stubs out the db API for creating Instances.""" - - INSTANCE_TYPES = { - 'm1.tiny': dict(memory_mb=512, vcpus=1, root_gb=0, flavorid=1), - 'm1.small': dict(memory_mb=2048, vcpus=1, root_gb=20, flavorid=2), - 'm1.medium': - dict(memory_mb=4096, vcpus=2, root_gb=40, flavorid=3), - 'm1.large': dict(memory_mb=8192, vcpus=4, root_gb=80, flavorid=4), - 'm1.xlarge': - dict(memory_mb=16384, vcpus=8, root_gb=160, flavorid=5)} - - 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(context, values): - """Stubs out the db.instance_create method.""" - - type_data = INSTANCE_TYPES[values['instance_type']] - - base_options = { - 'name': values['name'], - 'id': values['id'], - 'uuid': uuid.uuid4(), - 'reservation_id': utils.generate_uid('r'), - 'image_ref': values['image_ref'], - 'kernel_id': values['kernel_id'], - 'ramdisk_id': values['ramdisk_id'], - 'vm_state': vm_states.BUILDING, - 'task_state': task_states.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'], - 'vcpus': type_data['vcpus'], - 'mac_addresses': [{'address': values['mac_address']}], - 'root_gb': type_data['root_gb'], - } - return FakeModel(base_options) - - def fake_instance_type_get_all(context, inactive=0, filters=None): - return INSTANCE_TYPES.values() - - def fake_instance_type_get_by_name(context, name): - return INSTANCE_TYPES[name] - - stubs.Set(db, 'instance_create', fake_instance_create) - stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all) - stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name) diff --git a/nova/tests/vmwareapi/stubs.py b/nova/tests/vmwareapi/stubs.py deleted file mode 100644 index dc87b2355..000000000 --- a/nova/tests/vmwareapi/stubs.py +++ /dev/null @@ -1,51 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2011 Citrix Systems, Inc. -# Copyright 2011 OpenStack Foundation -# -# 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.vmwareapi import driver -from nova.virt.vmwareapi import fake -from nova.virt.vmwareapi import network_util -from nova.virt.vmwareapi import vmops -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(vmops.VMwareVMOps, 'plug_vifs', fake.fake_plug_vifs) - stubs.Set(network_util, 'get_network_with_the_name', - fake.fake_get_network) - 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(driver.VMwareAPISession, "_get_vim_object", - fake_get_vim_object) - stubs.Set(driver.VMwareAPISession, "_is_vim_object", - fake_is_vim_object) -- cgit