diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index 02f331a6c2f1..83d3f40c4c92 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -590,11 +590,13 @@ class VMwareAPIVMTestCase(test.TestCase): self.instance) def test_get_vnc_console(self): - self._create_instance_in_the_db() self._create_vm() + fake_vm = vmwareapi_fake._get_objects("VirtualMachine").objects[0] + fake_vm_id = int(fake_vm.obj.value.replace('vm-', '')) vnc_dict = self.conn.get_vnc_console(self.instance) self.assertEquals(vnc_dict['host'], "ha-host") - self.assertEquals(vnc_dict['port'], 5910) + self.assertEquals(vnc_dict['port'], cfg.CONF.vmware.vnc_port + + fake_vm_id % cfg.CONF.vmware.vnc_port_total) def test_host_ip_addr(self): self.assertEquals(self.conn.get_host_ip_addr(), "test_url") diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py index 18037b2317b5..2ab3fddec36a 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi_vm_util.py @@ -107,12 +107,9 @@ class VMwareVMUtilTestCase(test.TestCase): fake_session(), cluster="fake-cluster") def test_get_host_ref_from_id(self): - - fake_host_sys = fake.HostSystem( - fake.ManagedObjectReference("HostSystem", "host-123")) - - fake_host_id = fake_host_sys.obj.value fake_host_name = "ha-host" + fake_host_sys = fake.HostSystem(fake_host_name) + fake_host_id = fake_host_sys.obj.value fake_objects = fake.FakeRetrieveResult() fake_objects.add_object(fake_host_sys) ref = vm_util.get_host_ref_from_id( @@ -126,12 +123,10 @@ class VMwareVMUtilTestCase(test.TestCase): self.assertEquals(fake_host_name, host_name) def test_get_host_name_for_vm(self): - - fake_vm = fake.ManagedObject( - "VirtualMachine", fake.ManagedObjectReference( - "vm-123", "VirtualMachine")) - fake_vm.propSet.append( - fake.Property('name', 'vm-123')) + fake_host = fake.HostSystem() + fake_host_id = fake_host.obj.value + fake_vm = fake.VirtualMachine(name='vm-123', + runtime_host=fake_host.obj) fake_objects = fake.FakeRetrieveResult() fake_objects.add_object(fake_vm) @@ -140,22 +135,10 @@ class VMwareVMUtilTestCase(test.TestCase): self.assertIsNotNone(vm_ref) - fake_results = [ - fake.ObjectContent( - None, [ - fake.Property('runtime.host', - fake.ManagedObjectReference( - 'host-123', 'HostSystem')) - ])] - - fake_objects = fake.FakeRetrieveResult() - for results in fake_results: - fake_objects.add_object(results) - host_id = vm_util.get_host_id_from_vm_ref( fake_session(fake_objects), vm_ref) - self.assertEqual('host-123', host_id) + self.assertEqual(fake_host_id, host_id) def test_property_from_property_set(self): diff --git a/nova/virt/vmwareapi/fake.py b/nova/virt/vmwareapi/fake.py index 7d01037315e4..465ccaf0df53 100644 --- a/nova/virt/vmwareapi/fake.py +++ b/nova/virt/vmwareapi/fake.py @@ -76,6 +76,11 @@ def _create_object(table, table_obj): _db_content[table][table_obj.obj] = table_obj +def _get_object(obj_ref): + """Get object for the give reference.""" + return _db_content[obj_ref.type][obj_ref] + + def _get_objects(obj_type): """Get objects of the type.""" lst_objs = FakeRetrieveResult() @@ -84,6 +89,13 @@ def _get_objects(obj_type): return lst_objs +def _convert_to_array_of_mor(mors): + """Wraps the given array into a DataObject.""" + array_of_mors = DataObject() + array_of_mors.ManagedObjectReference = mors + return array_of_mors + + class FakeRetrieveResult(object): """Object to retrieve a ObjectContent list.""" @@ -94,7 +106,20 @@ class FakeRetrieveResult(object): self.objects.append(object) -class Property(object): +def _get_object_refs(obj_type): + """Get object References of the type.""" + lst_objs = [] + for key in _db_content[obj_type]: + lst_objs.append(key) + return lst_objs + + +def _update_object(table, table_obj): + """Update objects of the type.""" + _db_content[table][table_obj.obj] = table_obj + + +class Prop(object): """Property Object base class.""" def __init__(self, name=None, val=None): @@ -105,17 +130,18 @@ class Property(object): class ManagedObjectReference(object): """A managed object reference is a remote identifier.""" - def __init__(self, value="object-123", _type="ManagedObject"): + def __init__(self, name="ManagedObject", value=None): super(ManagedObjectReference, self) # Managed Object Reference value attributes # typically have values like vm-123 or # host-232 and not UUID. self.value = value - # Managed Object Reference _type + # Managed Object Reference type # attributes hold the name of the type # of the vCenter object the value # attribute is the identifier for - self._type = _type + self.type = name + self._type = name class ObjectContent(object): @@ -145,23 +171,15 @@ class ObjectContent(object): class ManagedObject(object): """Managed Object base class.""" + _counter = 0 - def __init__(self, name="ManagedObject", obj_ref=None, value=None): + def __init__(self, mo_id_prefix="obj"): """Sets the obj property which acts as a reference to the object.""" - super(ManagedObject, self).__setattr__('objName', name) - - # A managed object is a local representation of a - # remote object that you can reference using the - # object reference. - if obj_ref is None: - if value is None: - value = 'obj-123' - obj_ref = ManagedObjectReference(value, name) - - # we use __setattr__ here because below the - # default setter has been altered for this class. - object.__setattr__(self, 'obj', obj_ref) + object.__setattr__(self, 'mo_id', self._generate_moid(mo_id_prefix)) object.__setattr__(self, 'propSet', []) + object.__setattr__(self, 'obj', + ManagedObjectReference(self.__class__.__name__, + self.mo_id)) def set(self, attr, val): """ @@ -184,7 +202,7 @@ class ManagedObject(object): if prop.name == attr: prop.val = val return - elem = Property() + elem = Prop() elem.name = attr elem.val = val self.propSet.append(elem) @@ -198,11 +216,17 @@ class ManagedObject(object): return elem.val msg = _("Property %(attr)s not set for the managed object %(name)s") raise exception.NovaException(msg % {'attr': attr, - 'name': self.objName}) + 'name': self.__class__.__name__}) + + def _generate_moid(self, prefix): + """Generates a new Managed Object ID.""" + self.__class__._counter += 1 + return prefix + "-" + str(self.__class__._counter) class DataObject(object): """Data object base class.""" + def __init__(self, obj_name=None): self.obj_name = obj_name @@ -256,14 +280,13 @@ class VirtualMachine(ManagedObject): """Virtual Machine class.""" def __init__(self, **kwargs): - super(VirtualMachine, self).__init__("VirtualMachine", value='vm-10') - self.set("name", kwargs.get("name")) + super(VirtualMachine, self).__init__("vm") + self.set("name", kwargs.get("name", 'test-vm')) self.set("runtime.connectionState", kwargs.get("conn_state", "connected")) self.set("summary.config.guestId", kwargs.get("guest", "otherGuest")) - ds_do = DataObject() - ds_do.ManagedObjectReference = [kwargs.get("ds").obj] - self.set("datastore", ds_do) + ds_do = kwargs.get("ds", None) + self.set("datastore", _convert_to_array_of_mor(ds_do)) self.set("summary.guest.toolsStatus", kwargs.get("toolsstatus", "toolsOk")) self.set("summary.guest.toolsRunningStatus", kwargs.get( @@ -274,8 +297,7 @@ class VirtualMachine(ManagedObject): self.set("summary.config.memorySizeMB", kwargs.get("mem", 1)) self.set("config.hardware.device", kwargs.get("virtual_device", None)) self.set("config.extraConfig", kwargs.get("extra_config", None)) - self.set('runtime.host', - ManagedObjectReference(value='host-123', _type="HostSystem")) + self.set('runtime.host', kwargs.get("runtime_host", None)) self.device = kwargs.get("virtual_device") def reconfig(self, factory, val): @@ -310,45 +332,98 @@ class Network(ManagedObject): """Network class.""" def __init__(self): - super(Network, self).__init__("Network") + super(Network, self).__init__("network") self.set("summary.name", "vmnet0") class ResourcePool(ManagedObject): """Resource Pool class.""" - def __init__(self): - super(ResourcePool, self).__init__("ResourcePool") - self.set("name", "ResPool") + def __init__(self, name="test-rpool"): + super(ResourcePool, self).__init__("rp") + self.set("name", name) class ClusterComputeResource(ManagedObject): """Cluster class.""" - def __init__(self, **kwargs): - super(ClusterComputeResource, self).__init__("ClusterComputeResource", - value="domain-test") - r_pool = DataObject() - obj = _get_objects("ResourcePool").objects[0].obj - r_pool.ManagedObjectReference = [obj] - self.set("resourcePool", r_pool) - host_sys = DataObject() - obj = _get_objects("HostSystem").objects[0].obj - host_sys.ManagedObjectReference = [obj] - self.set("host", host_sys) - self.set("name", "test_cluster") + def __init__(self, name="test_cluster"): + super(ClusterComputeResource, self).__init__("domain") + self.set("name", name) + self.set("host", None) + self.set("datastore", None) + self.set("resourcePool", None) - datastore = DataObject() - obj = _get_objects("Datastore").objects[0].obj - datastore.ManagedObjectReference = [obj] - self.set("datastore", datastore) + summary = DataObject() + summary.numHosts = 0 + summary.numCpuCores = 0 + summary.numCpuThreads = 0 + summary.numEffectiveHosts = 0 + summary.totalMemory = 0 + summary.effectiveMemory = 0 + self.set("summary", summary) + + def _add_resource_pool(self, r_pool): + if r_pool: + r_pools = self.get("resourcePool") + if r_pools is None: + r_pools = DataObject() + r_pools.ManagedObjectReference = [] + self.set("resourcePool", r_pools) + r_pools.ManagedObjectReference.append(r_pool) + + def _add_host(self, host_sys): + if host_sys: + hosts = self.get("host") + if hosts is None: + hosts = DataObject() + hosts.ManagedObjectReference = [] + self.set("host", hosts) + hosts.ManagedObjectReference.append(host_sys) + # Update summary every time a new host is added + self._update_summary() + + def _add_datastore(self, datastore): + if datastore: + datastores = self.get("datastore") + if datastores is None: + datastores = DataObject() + datastores.ManagedObjectReference = [] + self.set("datastore", datastores) + datastores.ManagedObjectReference.append(datastore) + + # Method to update summary of a cluster upon host addition + def _update_summary(self): + summary = self.get("summary") + summary.numHosts = 0 + summary.numCpuCores = 0 + summary.numCpuThreads = 0 + summary.numEffectiveHosts = 0 + summary.totalMemory = 0 + summary.effectiveMemory = 0 + + hosts = self.get("host") + # Compute the aggregate stats + summary.numHosts = len(hosts.ManagedObjectReference) + for host_ref in hosts.ManagedObjectReference: + host_sys = _get_object(host_ref) + connected = host_sys.get("connected") + host_summary = host_sys.get("summary") + summary.numCpuCores += host_summary.hardware.numCpuCores + summary.numCpuThreads += host_summary.hardware.numCpuThreads + summary.totalMemory += host_summary.hardware.memorySize + free_memory = (host_summary.hardware.memorySize / (1024 * 1024) + - host_summary.quickStats.overallMemoryUsage) + summary.effectiveMemory += free_memory if connected else 0 + summary.numEffectiveHosts += 1 if connected else 0 + self.set("summary", summary) class Datastore(ManagedObject): """Datastore class.""" def __init__(self, name="fake-ds"): - super(Datastore, self).__init__("Datastore") + super(Datastore, self).__init__("ds") self.set("summary.type", "VMFS") self.set("summary.name", name) self.set("summary.capacity", 1024 * 1024 * 1024 * 1024) @@ -359,9 +434,9 @@ class Datastore(ManagedObject): class HostNetworkSystem(ManagedObject): """HostNetworkSystem class.""" - def __init__(self): - super(HostNetworkSystem, self).__init__("HostNetworkSystem") - self.set("name", "networkSystem") + def __init__(self, name="networkSystem"): + super(HostNetworkSystem, self).__init__("ns") + self.set("name", name) pnic_do = DataObject() pnic_do.device = "vmnic0" @@ -375,9 +450,9 @@ class HostNetworkSystem(ManagedObject): class HostSystem(ManagedObject): """Host System class.""" - def __init__(self, obj_ref=None, value='host-123'): - super(HostSystem, self).__init__("HostSystem", obj_ref, value) - self.set("name", "ha-host") + def __init__(self, name="ha-host", connected=True): + super(HostSystem, self).__init__("host") + self.set("name", name) if _db_content.get("HostNetworkSystem", None) is None: create_host_network_system() host_net_key = _db_content["HostNetworkSystem"].keys()[0] @@ -411,7 +486,9 @@ class HostSystem(ManagedObject): net_info_pnic.PhysicalNic = [pnic_do] self.set("summary", summary) + self.set("summary.hardware", hardware) self.set("config.network.pnic", net_info_pnic) + self.set("connected", connected) if _db_content.get("Network", None) is None: create_network() @@ -482,9 +559,9 @@ class HostSystem(ManagedObject): class Datacenter(ManagedObject): """Datacenter class.""" - def __init__(self): - super(Datacenter, self).__init__("Datacenter") - self.set("name", "ha-datacenter") + def __init__(self, name="ha-datacenter"): + super(Datacenter, self).__init__("dc") + self.set("name", name) self.set("vmFolder", "vm_folder_ref") if _db_content.get("Network", None) is None: create_network() @@ -537,6 +614,8 @@ def create_network(): def create_cluster(): cluster = ClusterComputeResource() + cluster._add_host(_get_object_refs("HostSystem")[0]) + cluster._add_datastore(_get_object_refs("Datastore")[0]) _create_object('ClusterComputeResource', cluster) @@ -642,6 +721,12 @@ class FakeVim(object): service_content.fileManager = "FileManager" service_content.rootFolder = "RootFolder" service_content.sessionManager = "SessionManager" + + about_info = DataObject() + about_info.name = "VMware vCenter Server" + about_info.version = "5.1.0" + service_content.about = about_info + self._service_content = service_content def get_service_content(self): @@ -690,9 +775,11 @@ class FakeVim(object): def _create_vm(self, method, *args, **kwargs): """Creates and registers a VM object with the Host System.""" config_spec = kwargs.get("config") - ds = _db_content["Datastore"][_db_content["Datastore"].keys()[0]] + ds = _db_content["Datastore"].keys()[0] + host = _db_content["HostSystem"].keys()[0] vm_dict = {"name": config_spec.name, - "ds": ds, + "ds": [ds], + "runtime_host": host, "powerstate": "poweredOff", "vmPathName": config_spec.files.vmPathName, "numCpu": config_spec.numCPUs, @@ -809,25 +896,20 @@ class FakeVim(object): try: obj_ref = obj.obj # This means that we are doing a search for the managed - # dataobjects of the type in the inventory + # data objects of the type in the inventory if obj_ref == "RootFolder": - for mdo_ref in _db_content[type]: - mdo = _db_content[type][mdo_ref] - # Create a temp Managed object which has the same ref - # as the parent object and copies just the properties - # asked for. We need .obj along with the propSet of - # just the properties asked for - temp_mdo = ManagedObject(mdo.objName, mdo.obj) - for prop in properties: - temp_mdo.set(prop, mdo.get(prop)) - lst_ret_objs.add_object(temp_mdo) + mdo_refs = _db_content[type] else: - if obj_ref in _db_content[type]: - mdo = _db_content[type][obj_ref] - temp_mdo = ManagedObject(mdo.objName, obj_ref) - for prop in properties: - temp_mdo.set(prop, mdo.get(prop)) - lst_ret_objs.add_object(temp_mdo) + mdo_refs = [obj_ref] + + for mdo_ref in mdo_refs: + mdo = _db_content[type][mdo_ref] + prop_list = [] + for prop_name in properties: + prop = Prop(prop_name, mdo.get(prop_name)) + prop_list.append(prop) + obj_content = ObjectContent(mdo.obj, prop_list) + lst_ret_objs.add_object(obj_content) except Exception as exc: LOG.exception(exc) continue