From 9f65cd9ec7a236f9c567a6b6991efcc11e41e094 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Wed, 31 Jul 2013 14:24:09 +0200 Subject: [PATCH] [vsphere] Make mock data consistent across operations Use the the same list of vms for all calls, mimic other providers mocks rbvmomi returns hashes with string keys, not symbols Match instance_uuid with id in list_virtual_machines as Real does Better mock for vm_clone, returns a vm with new id and adds it to the list of running vms Test new_vm option --- lib/fog/vsphere/compute.rb | 131 ++++++++++++++++++ .../requests/compute/get_datacenter.rb | 4 +- .../requests/compute/get_virtual_machine.rb | 35 ++--- .../requests/compute/list_virtual_machines.rb | 120 +--------------- lib/fog/vsphere/requests/compute/vm_clone.rb | 27 ++-- .../vsphere/requests/compute/vm_power_off.rb | 2 + tests/vsphere/models/compute/server_tests.rb | 2 +- .../compute/list_virtual_machines_tests.rb | 4 +- .../requests/compute/vm_clone_tests.rb | 22 +-- 9 files changed, 186 insertions(+), 161 deletions(-) diff --git a/lib/fog/vsphere/compute.rb b/lib/fog/vsphere/compute.rb index 0dd8fce57..607d7fe7f 100644 --- a/lib/fog/vsphere/compute.rb +++ b/lib/fog/vsphere/compute.rb @@ -169,12 +169,136 @@ module Fog obj.to_s.match(/\("([^"]+)"\)/)[1] end + def is_uuid?(id) + !(id =~ /[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/).nil? + end + end class Mock include Shared + def self.data + @data ||= Hash.new do |hash, key| + hash[key] = { + :servers => { + "5032c8a5-9c5e-ba7a-3804-832a03e16381" => { + "resource_pool" => "Resources", + "memory_mb" => 2196, + "mac_addresses" => { "Network adapter 1" => "00:50:56:a9:00:28" }, + "power_state" => "poweredOn", + "cpus" => 1, + "hostname" => "dhcp75-197.virt.bos.redhat.com", + "mo_ref" => "vm-562", + "connection_state" => "connected", + "overall_status" => "green", + "datacenter" => "Solutions", + "volumes" => + [{ + "id" => "6000C29c-a47d-4cd9-5249-c371de775f06", + "datastore" => "Storage1", + "mode" => "persistent", + "size" => 8388608, + "thin" => true, + "name" => "Hard disk 1", + "filename" => "[Storage1] rhel6-mfojtik/rhel6-mfojtik.vmdk", + "size_gb" => 8 + }], + "interfaces" => + [{"mac" => "00:50:56:a9:00:28", + "network" => "VM Network", + "name" => "Network adapter 1", + "status" => "ok", + "summary" => "VM Network", + }], + "hypervisor" => "gunab.puppetlabs.lan", + "guest_id" => "rhel6_64Guest", + "tools_state" => "toolsOk", + "cluster" => "Solutionscluster", + "name" => "rhel64", + "operatingsystem" => "Red Hat Enterprise Linux 6 (64-bit)", + "path" => "/Datacenters/Solutions/vm", + "uuid" => "4229f0e9-bfdc-d9a7-7bac-12070772e6dc", + "instance_uuid" => "5032c8a5-9c5e-ba7a-3804-832a03e16381", + "id" => "5032c8a5-9c5e-ba7a-3804-832a03e16381", + "tools_version" => "guestToolsUnmanaged", + "ipaddress" => "192.168.100.184", + "template" => false + }, + "502916a3-b42e-17c7-43ce-b3206e9524dc" => { + "resource_pool" => "Resources", + "memory_mb" => 512, + "power_state" => "poweredOn", + "mac_addresses" => { "Network adapter 1" => "00:50:56:a9:00:00" }, + "hostname" => nil, + "cpus" => 1, + "connection_state" => "connected", + "mo_ref" => "vm-621", + "overall_status" => "green", + "datacenter" => "Solutions", + "volumes" => + [{"thin" => false, + "size_gb" => 10, + "datastore" => "datastore1", + "filename" => "[datastore1] i-1342439683/i-1342439683.vmdk", + "size" => 10485762, + "name" => "Hard disk 1", + "mode" => "persistent", + "id" => "6000C29b-f364-d073-8316-8e98ac0a0eae" }], + "interfaces" => + [{ "summary" => "VM Network", + "mac" => "00:50:56:a9:00:00", + "status" => "ok", + "network" => "VM Network", + "name" => "Network adapter 1" }], + "hypervisor" => "gunab.puppetlabs.lan", + "guest_id" => nil, + "cluster" => "Solutionscluster", + "tools_state" => "toolsNotInstalled", + "name" => "i-1342439683", + "operatingsystem" => nil, + "path" => "/", + "tools_version" => "guestToolsNotInstalled", + "uuid" => "4229e0de-30cb-ceb2-21f9-4d8d8beabb52", + "instance_uuid" => "502916a3-b42e-17c7-43ce-b3206e9524dc", + "id" => "502916a3-b42e-17c7-43ce-b3206e9524dc", + "ipaddress" => nil, + "template" => false + }, + "5029c440-85ee-c2a1-e9dd-b63e39364603" => { + "resource_pool" => "Resources", + "memory_mb" => 2196, + "power_state" => "poweredOn", + "mac_addresses" => { "Network adapter 1" => "00:50:56:b2:00:af" }, + "hostname" => "centos56gm.localdomain", + "cpus" => 1, + "connection_state" => "connected", + "mo_ref" => "vm-715", + "overall_status" => "green", + "datacenter" => "Solutions", + "hypervisor" => "gunab.puppetlabs.lan", + "guest_id" => "rhel6_64Guest", + "cluster" => "Solutionscluster", + "tools_state" => "toolsOk", + "name" => "jefftest", + "operatingsystem" => "Red Hat Enterprise Linux 6 (64-bit)", + "path" => "/", + "tools_version" => "guestToolsUnmanaged", + "ipaddress" => "192.168.100.187", + "uuid" => "42329da7-e8ab-29ec-1892-d6a4a964912a", + "instance_uuid" => "5029c440-85ee-c2a1-e9dd-b63e39364603", + "id" => "5029c440-85ee-c2a1-e9dd-b63e39364603", + "template" => false + } + }, + :datacenters => { + "Solutions" => {:name => "Solutions", :status => "grey"} + } + } + end + end + def initialize(options={}) require 'rbvmomi' @vsphere_username = options[:vsphere_username] @@ -185,6 +309,13 @@ module Fog @vsphere_rev = '4.0' end + def data + self.class.data[@vsphere_username] + end + + def reset_data + self.class.data.delete(@vsphere_username) + end end class Real diff --git a/lib/fog/vsphere/requests/compute/get_datacenter.rb b/lib/fog/vsphere/requests/compute/get_datacenter.rb index cc3faa2d9..9d58589ea 100644 --- a/lib/fog/vsphere/requests/compute/get_datacenter.rb +++ b/lib/fog/vsphere/requests/compute/get_datacenter.rb @@ -21,7 +21,9 @@ module Fog class Mock def get_datacenter name - {:name => "Solutions", :status => "grey"} + dc = self.data[:datacenters][name] + raise(Fog::Compute::Vsphere::NotFound) unless dc + dc end end end diff --git a/lib/fog/vsphere/requests/compute/get_virtual_machine.rb b/lib/fog/vsphere/requests/compute/get_virtual_machine.rb index 63578b19c..cd0c5e07e 100644 --- a/lib/fog/vsphere/requests/compute/get_virtual_machine.rb +++ b/lib/fog/vsphere/requests/compute/get_virtual_machine.rb @@ -9,9 +9,9 @@ module Fog protected def get_vm_ref(id, dc = nil) - vm = case id + vm = case is_uuid?(id) # UUID based - when /[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/ + when true @connection.searchIndex.FindByUuid :uuid => id, :vmSearch => true, :instanceUuid => true, :datacenter => dc else # try to find based on VM name @@ -27,32 +27,13 @@ module Fog class Mock def get_virtual_machine(id, datacenter_name = nil) - case id - when "5032c8a5-9c5e-ba7a-3804-832a03e16381", 'vm-715' - { :resource_pool => "Resources", - :memory_mb => 2196, - :power_state => "poweredOn", - :mac_addresses => { "Network adapter 1" => "00:50:56:b2:00:af" }, - :hostname => "centos56gm.localdomain", - :cpus => 1, - :connection_state => "connected", - :mo_ref => "vm-715", - :overall_status => "green", - :datacenter => "Solutions", - :instance_uuid => "5029c440-85ee-c2a1-e9dd-b63e39364603", - :hypervisor => "gunab.puppetlabs.lan", - :guest_id => "rhel6_64Guest", - :cluster => "virtlabcluster", - :tools_state => "toolsOk", - :name => "jefftest", - :operatingsystem => "Red Hat Enterprise Linux 6 (64-bit)", - :path => "/", - :tools_version => "guestToolsUnmanaged", - :ipaddress => "192.168.100.187", - :id => "5032c8a5-9c5e-ba7a-3804-832a03e16381", - :uuid => "42329da7-e8ab-29ec-1892-d6a4a964912a" - } + if is_uuid?(id) + vm = list_virtual_machines({ 'instance_uuid' => id, 'datacenter' => datacenter_name }).first + else + # try to find based on VM name. May need to handle the path of the VM + vm = list_virtual_machines({ 'name' => id, 'datacenter' => datacenter_name }).first end + vm ? vm : raise(Fog::Compute::Vsphere::NotFound, "#{id} was not found") end end diff --git a/lib/fog/vsphere/requests/compute/list_virtual_machines.rb b/lib/fog/vsphere/requests/compute/list_virtual_machines.rb index a07fd52cf..5ac27a483 100644 --- a/lib/fog/vsphere/requests/compute/list_virtual_machines.rb +++ b/lib/fog/vsphere/requests/compute/list_virtual_machines.rb @@ -61,119 +61,13 @@ module Fog end def list_virtual_machines(options = { }) - case options['instance_uuid'] - when nil - - [ - { :resource_pool => "Resources", - :memory_mb => 2196, - :mac_addresses => { "Network adapter 1" => "00:50:56:a9:00:28" }, - :power_state => "poweredOn", - :cpus => 1, - :hostname => "dhcp75-197.virt.bos.redhat.com", - :mo_ref => "vm-562", - :connection_state => "connected", - :overall_status => "green", - :datacenter => "Solutions", - :volumes => - [{ - :id => "6000C29c-a47d-4cd9-5249-c371de775f06", - :datastore => "Storage1", - :mode => "persistent", - :size => 8388608, - :thin => true, - :name => "Hard disk 1", - :filename => "[Storage1] rhel6-mfojtik/rhel6-mfojtik.vmdk", - :size_gb => 8 - }], - :interfaces => - [{ :mac => "00:50:56:a9:00:28", - :network => "VM Network", - :name => "Network adapter 1", - :status => "ok", - :summary => "VM Network", - }], - :hypervisor => "gunab.puppetlabs.lan", - :guest_id => "rhel6_64Guest", - :tools_state => "toolsOk", - :cluster => "Solutionscluster", - :name => "rhel64", - :operatingsystem => "Red Hat Enterprise Linux 6 (64-bit)", - :uuid => "4229f0e9-bfdc-d9a7-7bac-12070772e6dc", - :path => "/Datacenters/Solutions/vm", - :id => "5029c440-85ee-c2a1-e9dd-b63e39364603", - :tools_version => "guestToolsUnmanaged", - :ipaddress => "192.168.100.184", - }, - { :resource_pool => "Resources", - :memory_mb => 512, - :power_state => "poweredOn", - :mac_addresses => { "Network adapter 1" => "00:50:56:a9:00:00" }, - :hostname => nil, - :cpus => 1, - :connection_state => "connected", - :mo_ref => "vm-621", - :overall_status => "green", - :datacenter => "Solutions", - :volumes => - [{ :thin => false, - :size_gb => 10, - :datastore => "datastore1", - :filename => "[datastore1] i-1342439683/i-1342439683.vmdk", - :size => 10485762, - :name => "Hard disk 1", - :mode => "persistent", - :id => "6000C29b-f364-d073-8316-8e98ac0a0eae" }], - :interfaces => - [{ :summary => "VM Network", - :mac => "00:50:56:a9:00:00", - :status => "ok", - :network => "VM Network", - :name => "Network adapter 1" }], - :instance_uuid => "502916a3-b42e-17c7-43ce-b3206e9524dc", - :hypervisor => "gunab.puppetlabs.lan", - :guest_id => nil, - :cluster => "Solutionscluster", - :tools_state => "toolsNotInstalled", - :uuid => "4229e0de-30cb-ceb2-21f9-4d8d8beabb52", - :name => "i-1342439683", - :operatingsystem => nil, - :path => "/", - :tools_version => "guestToolsNotInstalled", - :id => "502916a3-b42e-17c7-43ce-b3206e9524dc", - :ipaddress => nil } - - - ] - when '5032c8a5-9c5e-ba7a-3804-832a03e16381' - [{ :resource_pool => "Resources", - :memory_mb => 2196, - :power_state => "poweredOn", - :mac_addresses => { "Network adapter 1" => "00:50:56:b2:00:af" }, - :hostname => "centos56gm.localdomain", - :cpus => 1, - :connection_state => "connected", - :mo_ref => "vm-715", - :overall_status => "green", - :datacenter => "Solutions", - :instance_uuid => "5029c440-85ee-c2a1-e9dd-b63e39364603", - :hypervisor => "gunab.puppetlabs.lan", - :guest_id => "rhel6_64Guest", - :cluster => "Solutionscluster", - :tools_state => "toolsOk", - :name => "jefftest", - :operatingsystem => "Red Hat Enterprise Linux 6 (64-bit)", - :path => "/", - :tools_version => "guestToolsUnmanaged", - :ipaddress => "192.168.100.187", - :id => "5032c8a5-9c5e-ba7a-3804-832a03e16381", - :uuid => "42329da7-e8ab-29ec-1892-d6a4a964912a" - - } - - ] - when 'does-not-exist-and-is-not-a-uuid', '50323f93-6835-1178-8b8f-9e2109890e1a' - [] + if options['instance_uuid'].nil? and options['mo_ref'].nil? + self.data[:servers].values + elsif !options['instance_uuid'].nil? + server = self.data[:servers][options['instance_uuid']] + server.nil? ? [] : [server] + else + self.data[:servers].values.select{|vm| vm['mo_ref'] == options['mo_ref']} end end end diff --git a/lib/fog/vsphere/requests/compute/vm_clone.rb b/lib/fog/vsphere/requests/compute/vm_clone.rb index 317befb21..f818f00ab 100644 --- a/lib/fog/vsphere/requests/compute/vm_clone.rb +++ b/lib/fog/vsphere/requests/compute/vm_clone.rb @@ -17,11 +17,8 @@ module Fog required_options.each do |param| raise ArgumentError, "#{required_options.join(', ')} are required" unless options.has_key? param end - # TODO This is ugly and needs to rethink mocks - unless Fog.mock? - raise Fog::Compute::Vsphere::NotFound, "Datacenter #{options["datacenter"]} Doesn't Exist!" unless get_datacenter(options["datacenter"]) - raise Fog::Compute::Vsphere::NotFound, "Template #{options["template_path"]} Doesn't Exist!" unless get_virtual_machine(options["template_path"], options["datacenter"]) - end + raise Fog::Compute::Vsphere::NotFound, "Datacenter #{options["datacenter"]} Doesn't Exist!" unless get_datacenter(options["datacenter"]) + raise Fog::Compute::Vsphere::NotFound, "Template #{options["template_path"]} Doesn't Exist!" unless get_virtual_machine(options["template_path"], options["datacenter"]) options end end @@ -291,12 +288,24 @@ module Fog # Option handling TODO Needs better method of checking options = vm_clone_check_options(options) notfound = lambda { raise Fog::Compute::Vsphere::NotFound, "Could not find VM template" } - list_virtual_machines.find(notfound) do |vm| - vm[:name] == options['template_path'].split("/")[-1] + template = list_virtual_machines.find(notfound) do |vm| + vm['name'] == options['template_path'].split("/")[-1] end + + # generate a random id + id = [8,4,4,4,12].map{|i| Fog::Mock.random_hex(i)}.join("-") + new_vm = template.clone.merge({ + "name" => options['name'], + "id" => id, + "instance_uuid" => id, + "path" => "/Datacenters/#{options['datacenter']}/#{options['dest_folder'] ? options['dest_folder']+"/" : ""}#{options['name']}" + }) + self.data[:servers][id] = new_vm + { - 'vm_ref' => 'vm-123', - 'task_ref' => 'task-1234', + 'vm_ref' => "vm-#{Fog::Mock.random_numbers(3)}", + 'new_vm' => new_vm, + 'task_ref' => "task-#{Fog::Mock.random_numbers(4)}", } end diff --git a/lib/fog/vsphere/requests/compute/vm_power_off.rb b/lib/fog/vsphere/requests/compute/vm_power_off.rb index d167d111a..423e62352 100644 --- a/lib/fog/vsphere/requests/compute/vm_power_off.rb +++ b/lib/fog/vsphere/requests/compute/vm_power_off.rb @@ -29,6 +29,8 @@ module Fog def vm_power_off(options = {}) raise ArgumentError, "instance_uuid is a required parameter" unless options.has_key? 'instance_uuid' + vm = get_virtual_machine(options['instance_uuid']) + vm["power_state"] = "poweredOff" { 'task_state' => "running", 'power_off_type' => options['force'] ? 'cut_power' : 'shutdown_guest', diff --git a/tests/vsphere/models/compute/server_tests.rb b/tests/vsphere/models/compute/server_tests.rb index 6c77cb5ca..261fc2449 100644 --- a/tests/vsphere/models/compute/server_tests.rb +++ b/tests/vsphere/models/compute/server_tests.rb @@ -26,7 +26,7 @@ Shindo.tests('Fog::Compute[:vsphere] | server model', ['vsphere']) do :connection_state, :hypervisor, :name, - :ipaddress] + :public_ip_address] tests("The server model should respond to") do attributes.each do |attribute| test("#{attribute}") { server.respond_to? attribute } diff --git a/tests/vsphere/requests/compute/list_virtual_machines_tests.rb b/tests/vsphere/requests/compute/list_virtual_machines_tests.rb index 4c4f613d2..6f572a797 100644 --- a/tests/vsphere/requests/compute/list_virtual_machines_tests.rb +++ b/tests/vsphere/requests/compute/list_virtual_machines_tests.rb @@ -14,13 +14,13 @@ Shindo.tests('Fog::Compute[:vsphere] | list_virtual_machines request', ['vsphere # pending unless Fog.mock? tests("that does exist") do - uuid = "5032c8a5-9c5e-ba7a-3804-832a03e16381" + uuid = "5029c440-85ee-c2a1-e9dd-b63e39364603" response = Fog::Compute[:vsphere].list_virtual_machines({'instance_uuid' => uuid}) tests("The response should") do test("contain one vm") { response.length == 1 } test("contain that is an attribute hash") { response[0].kind_of? Hash } - test("find jefftest") { response.first[:name] == 'jefftest' } + test("find jefftest") { response.first['name'] == 'jefftest' } end end diff --git a/tests/vsphere/requests/compute/vm_clone_tests.rb b/tests/vsphere/requests/compute/vm_clone_tests.rb index 475e8e735..0dd338321 100644 --- a/tests/vsphere/requests/compute/vm_clone_tests.rb +++ b/tests/vsphere/requests/compute/vm_clone_tests.rb @@ -4,34 +4,40 @@ Shindo.tests("Fog::Compute[:vsphere] | vm_clone request", 'vsphere') do response = nil response_linked = nil - template = "folder/rhel64" + template = "rhel64" datacenter = "Solutions" + tests("Standard Clone | The return value should") do + servers_size = compute.servers.size response = compute.vm_clone('datacenter' => datacenter, 'template_path' => template, 'name' => 'cloning_vm', 'wait' => true) test("be a kind of Hash") { response.kind_of? Hash } - %w{ vm_ref task_ref }.each do |key| + %w{ vm_ref new_vm task_ref }.each do |key| test("have a #{key} key") { response.has_key? key } end + test("creates a new server") { compute.servers.size == servers_size+1 } + test("new server name is set") { compute.get_virtual_machine(response['new_vm']['id'])['name'] == 'cloning_vm' } end - template = "folder/rhel64" - datacenter = "Solutions" tests("Standard Clone setting ram and cpu | The return value should") do + servers_size = compute.servers.size response = compute.vm_clone('datacenter' => datacenter, 'template_path' => template, 'name' => 'cloning_vm', 'memoryMB' => '8192', 'numCPUs' => '8', 'wait' => true) test("be a kind of Hash") { response.kind_of? Hash } - %w{ vm_ref task_ref }.each do |key| + %w{ vm_ref new_vm task_ref }.each do |key| test("have a #{key} key") { response.has_key? key } end + test("creates a new server") { compute.servers.size == servers_size+1 } + test("new server name is set") { compute.get_virtual_machine(response['new_vm']['id'])['name'] == 'cloning_vm' } end - template = "folder/rhel64" - datacenter = "Solutions" tests("Linked Clone | The return value should") do + servers_size = compute.servers.size response = compute.vm_clone('datacenter' => datacenter, 'template_path' => template, 'name' => 'cloning_vm_linked', 'wait' => 1, 'linked_clone' => true) test("be a kind of Hash") { response.kind_of? Hash } - %w{ vm_ref task_ref }.each do |key| + %w{ vm_ref new_vm task_ref }.each do |key| test("have a #{key} key") { response.has_key? key } end + test("creates a new server") { compute.servers.size == servers_size+1 } + test("new server name is set") { compute.get_virtual_machine(response['new_vm']['id'])['name'] == 'cloning_vm_linked' } end tests("When invalid input is presented") do