diff --git a/test/unit/vagrant/action/warden_test.rb b/test/unit/vagrant/action/warden_test.rb new file mode 100644 index 000000000..40d03b13e --- /dev/null +++ b/test/unit/vagrant/action/warden_test.rb @@ -0,0 +1,92 @@ +require File.expand_path("../../../base", __FILE__) + +describe Vagrant::Action::Warden do + let(:data) { { :data => [] } } + let(:instance) { described_class.new } + + # This returns a proc that can be used with the builder + # that simply appends data to an array in the env. + def appender_proc(data) + Proc.new { |env| env[:data] << data } + end + + it "calls the actions like normal" do + instance = described_class.new([appender_proc(1), appender_proc(2)], data) + instance.call(data) + + data[:data].should == [1, 2] + end + + it "starts a recovery sequence when an exception is raised" do + class Action + def initialize(app, env) + @app = app + end + + def call(env) + @app.call(env) + end + + def recover(env) + env[:recover] << 1 + end + end + + class ActionTwo + def initialize(app, env) + @app = app + end + + def call(env) + @app.call(env) + end + + def recover(env) + env[:recover] << 2 + end + end + + error_proc = Proc.new { raise "ERROR!" } + + data = { :recover => [] } + instance = described_class.new([Action, ActionTwo, error_proc], data) + + # The error should be raised back up + expect { instance.call(data) }. + to raise_error(RuntimeError) + + # Verify the recovery process goes in reverse order + data[:recover].should == [2, 1] + + # Verify that the error is available in the data + data["vagrant.error"].should be_kind_of(RuntimeError) + end + + it "does not do a recovery sequence if SystemExit is raised" do + class Action + def initialize(app, env) + @app = app + end + + def call(env) + @app.call(env) + end + + def recover(env) + env[:recover] = true + end + end + + # Make a proc that just calls "abort" which raises a + # SystemExit exception. + error_proc = Proc.new { abort } + + instance = described_class.new([Action, error_proc], data) + + # The SystemExit should come through + expect { instance.call(data) }.to raise_error(SystemExit) + + # The recover should not have been called + data.has_key?(:recover).should_not be + end +end diff --git a/test/unit_legacy/vagrant/action/warden_test.rb b/test/unit_legacy/vagrant/action/warden_test.rb deleted file mode 100644 index 7a6615745..000000000 --- a/test/unit_legacy/vagrant/action/warden_test.rb +++ /dev/null @@ -1,125 +0,0 @@ -require "test_helper" -require "logger" - -class ActionWardenTest < Test::Unit::TestCase - setup do - @klass = Vagrant::Action::Warden - @instance = @klass.new([], {}) - end - - context "initializing" do - should "finalize the middleware" do - env = new_env - middleware = [1,2,3] - middleware.each do |m| - @klass.any_instance.expects(:finalize_action).with(m, env).returns(m) - end - @warden = @klass.new(middleware, env) - assert_equal @warden.actions, [1,2,3] - end - end - - context "setting up middleware" do - should "make non-classes lambdas" do - env = new_env - env.expects(:foo).once - - func = lambda { |x| x.foo } - @instance.finalize_action(func, env).call(env) - end - - should "raise exception if given invalid middleware" do - assert_raises(RuntimeError) { - @instance.finalize_action(7, nil) - } - end - end - - context "calling" do - should "return if there are no actions to execute" do - @instance.actions.expects(:pop).never - assert !@instance.call(new_env) - end - - should "move the last action to the front of the stack" do - @instance.actions << lambda { |env| } - assert @instance.stack.empty? - @instance.call(new_env) - assert !@instance.stack.empty? - assert @instance.actions.empty? - end - - should "call the next action" do - env = new_env - action = mock('action') - action.expects(:call).with(env) - @instance.actions << action - @instance.call(env) - end - - should "begin recovery sequence when the called action raises an exception" do - class Foo - def initialize(*args); end - def call(env) - raise "An exception" - end - end - - @instance.actions << Foo.new - @instance.expects(:begin_rescue).with() do |env| - assert env["vagrant.error"].is_a?(RuntimeError) - true - end - assert_raises(RuntimeError) { @instance.call(new_env) } - end - - should "not begin recovery sequence if a SystemExit is raised" do - class Foo - def initialize(*args); end - def call(env) - # Raises a system exit - abort - end - end - - @instance.actions << Foo.new - @instance.expects(:begin_rescue).never - assert_raises(SystemExit) { @instance.call(new_env) } - end - - should "raise interrupt if the environment is interupted" do - env = new_env - env.expects(:interrupted?).returns(true) - @instance.actions << lambda { |env| } - - assert_raises(Vagrant::Errors::VagrantInterrupt) { - @instance.call(env) - } - end - end - - context "recover" do - should "call recover on all items in the stack" do - env = new_env - seq = sequence("sequence") - @instance.stack = [rescueable_mock("action"), rescueable_mock("another")] - @instance.stack.each do |action| - action.expects(:recover).with(env).in_sequence(seq) - end - - @instance.begin_rescue(env) - end - end - - def new_env - env = Vagrant::Action::Environment.new(nil) - env["logger"] = Logger.new(nil) - env - end - - def rescueable_mock(name) - mock_action = mock(name) - mock_action.stubs(:respond_to?).with(:recover).returns(true) - mock_action - end -end