From d0f728b3539fbcdb10237da6b92f76da18066cb2 Mon Sep 17 00:00:00 2001 From: John Bender Date: Tue, 2 Feb 2010 00:48:38 -0800 Subject: [PATCH] suspend and resume, test for both and failures, small refactor of the Hobo::VM#start and the use of Ping.pingecho in SSH.up? --- bin/hobo-resume | 26 ++++++++++++++++++++ bin/hobo-suspend | 26 ++++++++++++++++++++ lib/hobo.rb | 2 ++ lib/hobo/env.rb | 13 ++-------- lib/hobo/error.rb | 14 +++++++++++ lib/hobo/ssh.rb | 6 ++++- lib/hobo/vm.rb | 53 ++++++++++++++++++++++++++++------------ test/hobo/vm_test.rb | 57 ++++++++++++++++++++++++++++++++++++++------ 8 files changed, 163 insertions(+), 34 deletions(-) create mode 100755 bin/hobo-resume create mode 100755 bin/hobo-suspend create mode 100644 lib/hobo/error.rb diff --git a/bin/hobo-resume b/bin/hobo-resume new file mode 100755 index 000000000..15c8369a2 --- /dev/null +++ b/bin/hobo-resume @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +begin + require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/ruby/1.8/environment")) +rescue LoadError +end + +require 'git-style-binary/command' + +# Get hobo +hobodir = File.join(File.dirname(__FILE__), '..', 'lib') +$:.unshift(hobodir) unless $:.include?(hobodir) +require 'hobo' + +GitStyleBinary.command do + short_desc "resumes the hobo environment" + banner <<-EOS +Usage: #{command.full_name} #{all_options_string} + +Resumes the hobo environment. + +EOS + + run do |command| + Hobo::VM.resume + end +end diff --git a/bin/hobo-suspend b/bin/hobo-suspend new file mode 100755 index 000000000..ff5594809 --- /dev/null +++ b/bin/hobo-suspend @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby +begin + require File.expand_path(File.join(File.dirname(__FILE__), "../vendor/gems/ruby/1.8/environment")) +rescue LoadError +end + +require 'git-style-binary/command' + +# Get hobo +hobodir = File.join(File.dirname(__FILE__), '..', 'lib') +$:.unshift(hobodir) unless $:.include?(hobodir) +require 'hobo' + +GitStyleBinary.command do + short_desc "suspends the hobo environment" + banner <<-EOS +Usage: #{command.full_name} #{all_options_string} + +Suspends the hobo environment. + +EOS + + run do |command| + Hobo::VM.suspend + end +end diff --git a/lib/hobo.rb b/lib/hobo.rb index 8e3768f41..7a34b4ca3 100644 --- a/lib/hobo.rb +++ b/lib/hobo.rb @@ -7,6 +7,8 @@ require 'pathname' require 'logger' require 'virtualbox' require 'net/ssh' +require 'ping' +require 'hobo/error' require 'hobo/config' require 'hobo/env' require 'hobo/ssh' diff --git a/lib/hobo/env.rb b/lib/hobo/env.rb index ec3d325b5..f0b553fe2 100644 --- a/lib/hobo/env.rb +++ b/lib/hobo/env.rb @@ -7,6 +7,8 @@ module Hobo # Initialize class variables used @@persisted_vm = nil @@root_path = nil + + extend Hobo::Error class << self def persisted_vm; @@persisted_vm; end @@ -79,17 +81,6 @@ error return end end - - def error_and_exit(error) - puts <<-error -===================================================================== -Hobo experienced an error! - -#{error.chomp} -===================================================================== -error - exit - end end end end diff --git a/lib/hobo/error.rb b/lib/hobo/error.rb new file mode 100644 index 000000000..d9f5145c7 --- /dev/null +++ b/lib/hobo/error.rb @@ -0,0 +1,14 @@ +module Hobo + module Error + def error_and_exit(error) + puts <<-error +===================================================================== +Hobo experienced an error! + +#{error.chomp} +===================================================================== +error + exit + end + end +end diff --git a/lib/hobo/ssh.rb b/lib/hobo/ssh.rb index c3019ae7c..7d483daa4 100644 --- a/lib/hobo/ssh.rb +++ b/lib/hobo/ssh.rb @@ -2,7 +2,7 @@ module Hobo class SSH SCRIPT = File.join(File.dirname(__FILE__), '..', '..', 'script', 'hobo-ssh-expect.sh') - class <= Hobo.config[:ssh][:max_tries].to_i - HOBO_LOGGER.info "Failed to connect to VM! Failed to boot?" - return false + HOBO_LOGGER.info "Trying to connect (attempt ##{i+1} of #{Hobo.config[:ssh][:max_tries]})..." + + if Hobo::SSH.up? + HOBO_LOGGER.info "VM booted and ready for use!" + return true end - - counter += 1 - retry end - HOBO_LOGGER.info "VM booted and ready for use!" - true + HOBO_LOGGER.info "Failed to connect to VM! Failed to boot?" + false end + + def saved?; @vm.saved? end + + def save_state(errs); @vm.save_state(errs) end end -end \ No newline at end of file +end diff --git a/test/hobo/vm_test.rb b/test/hobo/vm_test.rb index 90c29155c..bbcfea8a3 100644 --- a/test/hobo/vm_test.rb +++ b/test/hobo/vm_test.rb @@ -112,15 +112,15 @@ class VMTest < Test::Unit::TestCase @vm.start end - should "repeatedly SSH while waiting for the VM to start" do - ssh_seq = sequence("ssh_seq") - Net::SSH.expects(:start).once.raises(Errno::ECONNREFUSED).in_sequence(ssh_seq) - Net::SSH.expects(:start).once.in_sequence(ssh_seq) - @vm.start + 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 end - should "try the max number of times then just return" do - Net::SSH.expects(:start).times(Hobo.config[:ssh][:max_tries].to_i).raises(Errno::ECONNREFUSED) + should "ping the max number of times then just return" do + Ping.expects(:pingecho).times(Hobo.config[:ssh][:max_tries].to_i).returns(false) assert !@vm.start end end @@ -182,5 +182,48 @@ class VMTest < Test::Unit::TestCase @vm.setup_shared_folder end end + + context "suspending a vm" do + should "put the vm in a suspended state" do + saved_state_expectations(false) + Hobo::VM.suspend + end + + should "results in an error and exit if the vm is already in a saved state" do + saved_state_expectations(true) + Hobo::VM.expects(:error_and_exit) + Hobo::VM.suspend + end + + def saved_state_expectations(saved) + @persisted_vm.expects(:saved?).returns(saved) + + # In this case the exit, is ignored so the expectation of save_state on the persisted + # vm must be set + @persisted_vm.expects(:save_state).with(true) + end + end + + context "resuming a vm" do + should "start a vm in a suspended state" do + start_state_expectaions(true) + Hobo::VM.resume + end + + should "results in an error and exit if the vm is not in a saved state" do + start_state_expectaions(false) + + # In this case the exit, is ignored so the expectation of start on the persisted + # vm must be set + # TODO research the matter of mocking exit + Hobo::VM.expects(:error_and_exit) + Hobo::VM.resume + end + + def start_state_expectaions(saved) + @persisted_vm.expects(:saved?).returns(saved) + Hobo::Env.persisted_vm.expects(:start).once.returns(true) + end + end end end