diff --git a/lib/vagrant/busy.rb b/lib/vagrant/busy.rb index dabb5d97a..d7c123bb8 100644 --- a/lib/vagrant/busy.rb +++ b/lib/vagrant/busy.rb @@ -12,6 +12,7 @@ module Vagrant @@busy = false @@mutex = Mutex.new + @@trap_thread = nil class << self def busy? @@ -34,6 +35,9 @@ module Vagrant # busy back to some sane state. Busy.busy = false + # Make sure that the trap thread completes, if it is running + trap_thread.join if trap_thread + # And restore the INT trap to the default Signal.trap("INT", "DEFAULT") end @@ -41,7 +45,7 @@ module Vagrant end def wait_for_not_busy(sleeptime=5) - Thread.new do + @@trap_thread ||= Thread.new do # Wait while the app is busy loop do break unless busy? @@ -50,9 +54,20 @@ module Vagrant end # Exit out of the entire script + logger.info "Exiting vagrant..." exit end end + + # Used for testing + def reset_trap_thread! + @@trap_thread = nil + end + + # Returns the trap thread + def trap_thread + @@trap_thread + end end end end diff --git a/test/vagrant/busy_test.rb b/test/vagrant/busy_test.rb index 4e15a7591..3f9e33b5d 100644 --- a/test/vagrant/busy_test.rb +++ b/test/vagrant/busy_test.rb @@ -2,7 +2,19 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper') class BusyTest < Test::Unit::TestCase context "waiting for not busy" do - # TODO: Need to test this method + setup do + Vagrant::Busy.reset_trap_thread! + end + + should "run in a thread" do + Thread.expects(:new).once.returns(nil) + Vagrant::Busy.wait_for_not_busy + end + + should "not start a thread multiple times" do + Thread.expects(:new).once.returns("foo") + Vagrant::Busy.wait_for_not_busy + end end context "during an action in a busy block" do @@ -27,6 +39,18 @@ class BusyTest < Test::Unit::TestCase assert !Vagrant.busy? end + should "complete the trap thread even if an exception occurs" do + trap_thread = mock("trap_thread") + trap_thread.expects(:join).once + Vagrant::Busy.stubs(:trap_thread).returns(trap_thread) + + assert_raise Exception do + Vagrant.busy do + raise Exception + end + end + end + should "report busy to the outside world regardless of thread" do Thread.new do Vagrant.busy do