2010-01-30 08:06:56 +00:00
|
|
|
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
|
|
|
|
|
|
|
class VMTest < Test::Unit::TestCase
|
|
|
|
setup do
|
2010-02-01 01:59:19 +00:00
|
|
|
@mock_vm = mock("vm")
|
2010-02-02 06:14:40 +00:00
|
|
|
hobo_mock_config
|
2010-02-01 02:53:35 +00:00
|
|
|
|
|
|
|
@persisted_vm = mock("persisted_vm")
|
|
|
|
Hobo::Env.stubs(:persisted_vm).returns(@persisted_vm)
|
2010-02-01 06:23:19 +00:00
|
|
|
|
|
|
|
Net::SSH.stubs(:start)
|
2010-02-01 02:53:35 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
context "hobo ssh" do
|
|
|
|
setup do
|
|
|
|
Hobo::SSH.stubs(:connect)
|
|
|
|
end
|
|
|
|
|
|
|
|
should "require a persisted VM" do
|
|
|
|
Hobo::Env.expects(:require_persisted_vm).once
|
|
|
|
Hobo::VM.ssh
|
|
|
|
end
|
|
|
|
|
|
|
|
should "connect to SSH" do
|
|
|
|
Hobo::SSH.expects(:connect).once
|
|
|
|
Hobo::VM.ssh
|
|
|
|
end
|
2010-01-30 08:06:56 +00:00
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-01-31 09:27:18 +00:00
|
|
|
context "hobo down" do
|
|
|
|
setup do
|
|
|
|
@persisted_vm.stubs(:destroy)
|
|
|
|
end
|
|
|
|
|
|
|
|
should "require a persisted VM" do
|
|
|
|
Hobo::Env.expects(:require_persisted_vm).once
|
|
|
|
Hobo::VM.down
|
|
|
|
end
|
|
|
|
|
|
|
|
should "destroy the persisted VM and the VM image" do
|
2010-02-01 02:12:09 +00:00
|
|
|
@persisted_vm.expects(:destroy).once
|
2010-01-31 09:27:18 +00:00
|
|
|
Hobo::VM.down
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-01-30 08:06:56 +00:00
|
|
|
context "hobo up" do
|
2010-02-01 01:59:19 +00:00
|
|
|
should "create a Hobo::VM instance and call create" do
|
|
|
|
inst = mock("instance")
|
|
|
|
inst.expects(:create).once
|
|
|
|
Hobo::VM.expects(:new).returns(inst)
|
2010-01-30 08:06:56 +00:00
|
|
|
Hobo::VM.up
|
|
|
|
end
|
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-01 02:10:01 +00:00
|
|
|
context "finding a VM" do
|
|
|
|
should "return nil if the VM is not found" do
|
|
|
|
VirtualBox::VM.expects(:find).returns(nil)
|
|
|
|
assert_nil Hobo::VM.find("foo")
|
|
|
|
end
|
|
|
|
|
|
|
|
should "return a Hobo::VM object for that VM otherwise" do
|
|
|
|
VirtualBox::VM.expects(:find).with("foo").returns("bar")
|
|
|
|
result = Hobo::VM.find("foo")
|
|
|
|
assert result.is_a?(Hobo::VM)
|
|
|
|
assert_equal "bar", result.vm
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
context "hobo VM instance" do
|
|
|
|
setup do
|
|
|
|
@vm = Hobo::VM.new(@mock_vm)
|
2010-01-30 08:06:56 +00:00
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
context "creating" do
|
|
|
|
should "create the VM in the proper order" do
|
|
|
|
create_seq = sequence("create_seq")
|
|
|
|
@vm.expects(:import).in_sequence(create_seq)
|
|
|
|
@vm.expects(:persist).in_sequence(create_seq)
|
|
|
|
@vm.expects(:setup_mac_address).in_sequence(create_seq)
|
2010-02-03 08:02:12 +00:00
|
|
|
@vm.expects(:forward_ports).in_sequence(create_seq)
|
2010-02-01 01:59:19 +00:00
|
|
|
@vm.expects(:setup_shared_folder).in_sequence(create_seq)
|
2010-02-01 02:43:36 +00:00
|
|
|
@vm.expects(:start).in_sequence(create_seq)
|
2010-02-06 08:01:47 +00:00
|
|
|
@vm.expects(:mount_shared_folder).in_sequence(create_seq)
|
2010-02-01 01:59:19 +00:00
|
|
|
@vm.create
|
|
|
|
end
|
2010-01-30 08:06:56 +00:00
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-01 02:12:09 +00:00
|
|
|
context "destroying" do
|
2010-02-01 02:43:36 +00:00
|
|
|
setup do
|
|
|
|
@mock_vm.stubs(:running?).returns(false)
|
|
|
|
end
|
|
|
|
|
2010-02-01 02:12:09 +00:00
|
|
|
should "destoy the VM along with images" do
|
|
|
|
@mock_vm.expects(:destroy).with(:destroy_image => true).once
|
|
|
|
@vm.destroy
|
|
|
|
end
|
2010-02-01 02:43:36 +00:00
|
|
|
|
|
|
|
should "stop the VM if its running" do
|
|
|
|
@mock_vm.expects(:running?).returns(true)
|
|
|
|
@mock_vm.expects(:stop).with(true)
|
|
|
|
@mock_vm.expects(:destroy).with(:destroy_image => true).once
|
|
|
|
@vm.destroy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "starting" do
|
2010-02-01 06:23:19 +00:00
|
|
|
setup do
|
|
|
|
@mock_vm.stubs(:start)
|
|
|
|
end
|
|
|
|
|
2010-02-01 02:43:36 +00:00
|
|
|
should "start the VM in headless mode" do
|
|
|
|
@mock_vm.expects(:start).with(:headless, true).once
|
|
|
|
@vm.start
|
|
|
|
end
|
2010-02-01 06:23:19 +00:00
|
|
|
|
2010-02-02 08:48:38 +00:00
|
|
|
should "repeatedly ping the SSH port and return false with no response" do
|
|
|
|
seq = sequence('pings')
|
|
|
|
Ping.expects(:pingecho).times(Hobo.config[:ssh][:max_tries].to_i - 1).returns(false).in_sequence(seq)
|
|
|
|
Ping.expects(:pingecho).once.returns(true).in_sequence(seq)
|
|
|
|
assert @vm.start
|
2010-02-01 06:23:19 +00:00
|
|
|
end
|
2010-02-01 06:38:00 +00:00
|
|
|
|
2010-02-02 08:48:38 +00:00
|
|
|
should "ping the max number of times then just return" do
|
|
|
|
Ping.expects(:pingecho).times(Hobo.config[:ssh][:max_tries].to_i).returns(false)
|
2010-02-01 06:38:00 +00:00
|
|
|
assert !@vm.start
|
|
|
|
end
|
2010-02-01 02:12:09 +00:00
|
|
|
end
|
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
context "importing" do
|
|
|
|
should "call import on VirtualBox::VM with the proper base" do
|
|
|
|
VirtualBox::VM.expects(:import).once
|
|
|
|
@vm.import
|
|
|
|
end
|
|
|
|
|
|
|
|
should "return the VM object" do
|
|
|
|
VirtualBox::VM.expects(:import).returns(@mock_vm).once
|
|
|
|
assert_equal @mock_vm, @vm.import
|
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
end
|
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
context "persisting" do
|
|
|
|
should "persist the VM with Env" do
|
|
|
|
@mock_vm.stubs(:uuid)
|
|
|
|
Hobo::Env.expects(:persist_vm).with(@mock_vm).once
|
|
|
|
@vm.persist
|
|
|
|
end
|
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
context "setting up MAC address" do
|
|
|
|
should "match the mac address with the base" do
|
|
|
|
nic = mock("nic")
|
|
|
|
nic.expects(:macaddress=).once
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
@mock_vm.expects(:nics).returns([nic]).once
|
|
|
|
@mock_vm.expects(:save).with(true).once
|
|
|
|
|
|
|
|
@vm.setup_mac_address
|
|
|
|
end
|
2010-01-30 08:06:56 +00:00
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-03 08:02:12 +00:00
|
|
|
context "forwarding ports" do
|
2010-02-01 01:59:19 +00:00
|
|
|
should "create a port forwarding for the VM" do
|
|
|
|
# TODO: Test the actual port value to make sure it has the
|
|
|
|
# correct attributes
|
|
|
|
forwarded_ports = mock("forwarded_ports")
|
|
|
|
forwarded_ports.expects(:<<)
|
|
|
|
@mock_vm.expects(:forwarded_ports).returns(forwarded_ports)
|
|
|
|
@mock_vm.expects(:save).with(true).once
|
2010-02-03 08:02:12 +00:00
|
|
|
@vm.forward_ports
|
2010-02-01 01:59:19 +00:00
|
|
|
end
|
2010-01-30 08:06:56 +00:00
|
|
|
end
|
2010-01-31 07:00:56 +00:00
|
|
|
|
2010-02-01 01:59:19 +00:00
|
|
|
context "setting up the shared folder" do
|
2010-02-01 02:35:35 +00:00
|
|
|
should "create a shared folder with the root folder for the VM" do
|
|
|
|
shared_folder = mock("shared_folder")
|
|
|
|
shared_folder.stubs(:name=)
|
|
|
|
shared_folder.expects(:hostpath=).with(Hobo::Env.root_path).once
|
|
|
|
shared_folder_collection = mock("collection")
|
|
|
|
shared_folder_collection.expects(:<<).with(shared_folder)
|
|
|
|
VirtualBox::SharedFolder.expects(:new).returns(shared_folder)
|
|
|
|
@mock_vm.expects(:shared_folders).returns(shared_folder_collection)
|
|
|
|
@mock_vm.expects(:save).with(true).once
|
|
|
|
@vm.setup_shared_folder
|
|
|
|
end
|
2010-02-01 01:59:19 +00:00
|
|
|
end
|
2010-02-02 08:48:38 +00:00
|
|
|
|
2010-02-06 08:01:47 +00:00
|
|
|
context "mounting the shared folders" do
|
|
|
|
should "create the directory then mount the shared folder" do
|
|
|
|
mount_seq = sequence("mount_seq")
|
|
|
|
ssh = mock("ssh")
|
|
|
|
ssh.expects(:exec!).with("sudo mkdir -p #{Hobo.config.vm.project_directory}").in_sequence(mount_seq)
|
|
|
|
ssh.expects(:exec!).with("sudo mount -t vboxsf hobo-root-path #{Hobo.config.vm.project_directory}").in_sequence(mount_seq)
|
|
|
|
Hobo::SSH.expects(:execute).yields(ssh)
|
|
|
|
@vm.mount_shared_folder
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-02-02 17:11:06 +00:00
|
|
|
context "suspending and resuming a vm" do
|
2010-02-03 08:02:12 +00:00
|
|
|
should "put the vm in a suspended state" do
|
2010-02-02 17:11:06 +00:00
|
|
|
saved_state_expectation(false)
|
|
|
|
save_expectation
|
2010-02-02 08:48:38 +00:00
|
|
|
Hobo::VM.suspend
|
|
|
|
end
|
|
|
|
|
|
|
|
should "results in an error and exit if the vm is already in a saved state" do
|
2010-02-02 17:11:06 +00:00
|
|
|
saved_state_expectation(true)
|
|
|
|
save_expectation
|
2010-02-02 08:48:38 +00:00
|
|
|
Hobo::VM.expects(:error_and_exit)
|
|
|
|
Hobo::VM.suspend
|
|
|
|
end
|
|
|
|
|
2010-02-03 08:02:12 +00:00
|
|
|
should "start a vm in a suspended state" do
|
2010-02-02 17:11:06 +00:00
|
|
|
saved_state_expectation(true)
|
|
|
|
start_expectation
|
2010-02-02 08:48:38 +00:00
|
|
|
Hobo::VM.resume
|
|
|
|
end
|
|
|
|
|
|
|
|
should "results in an error and exit if the vm is not in a saved state" do
|
2010-02-02 17:11:06 +00:00
|
|
|
saved_state_expectation(false)
|
|
|
|
start_expectation
|
2010-02-02 08:48:38 +00:00
|
|
|
# TODO research the matter of mocking exit
|
|
|
|
Hobo::VM.expects(:error_and_exit)
|
|
|
|
Hobo::VM.resume
|
2010-02-03 08:02:12 +00:00
|
|
|
end
|
2010-02-02 08:48:38 +00:00
|
|
|
|
2010-02-02 17:11:06 +00:00
|
|
|
def saved_state_expectation(saved)
|
2010-02-02 08:48:38 +00:00
|
|
|
@persisted_vm.expects(:saved?).returns(saved)
|
2010-02-02 17:11:06 +00:00
|
|
|
end
|
2010-02-03 08:02:12 +00:00
|
|
|
|
2010-02-02 17:11:06 +00:00
|
|
|
def save_expectation
|
|
|
|
@persisted_vm.expects(:save_state).with(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
def start_expectation
|
2010-02-02 08:48:38 +00:00
|
|
|
Hobo::Env.persisted_vm.expects(:start).once.returns(true)
|
|
|
|
end
|
|
|
|
end
|
2010-02-08 03:56:56 +00:00
|
|
|
|
|
|
|
context "creating a new vm with a specified disk storage location" do
|
|
|
|
|
|
|
|
should "error and exit of the vm is not powered off" do
|
|
|
|
# Exit does not prevent method from proceeding in test, so we must set expectations
|
|
|
|
vm = move_hd_expectations
|
|
|
|
@mock_vm.expects(:powered_off?).returns(false)
|
|
|
|
vm.expects(:error_and_exit)
|
|
|
|
vm.move_hd
|
|
|
|
end
|
|
|
|
|
|
|
|
should "create assign a new disk image, and delete the old one" do
|
|
|
|
vm = move_hd_expectations
|
|
|
|
@mock_vm.expects(:powered_off?).returns(true)
|
|
|
|
vm.move_hd
|
|
|
|
end
|
|
|
|
|
|
|
|
def move_hd_expectations
|
|
|
|
image, hd = mock('image'), mock('hd')
|
|
|
|
|
|
|
|
Hobo.config[:vm].expects(:hd_location).at_least_once.returns('/locations/')
|
|
|
|
image.expects(:clone).with(Hobo.config[:vm][:hd_location] + 'foo', Hobo::VM::HD_EXT_DEFAULT, true).returns(image)
|
|
|
|
image.expects(:filename).twice.returns('foo')
|
|
|
|
|
|
|
|
hd.expects(:image).twice.returns(image)
|
|
|
|
hd.expects(:image=).with(image)
|
|
|
|
|
|
|
|
image.expects(:destroy)
|
|
|
|
|
|
|
|
@mock_vm.expects(:save)
|
|
|
|
|
|
|
|
vm = Hobo::VM.new(@mock_vm)
|
|
|
|
vm.expects(:hd).times(3).returns(hd)
|
|
|
|
vm
|
|
|
|
end
|
|
|
|
end
|
2010-01-30 08:06:56 +00:00
|
|
|
end
|
|
|
|
end
|