vaguerent/test/vagrant/actions/runner_test.rb
2010-04-08 23:32:26 -07:00

269 lines
8.0 KiB
Ruby

require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ActionRunnerTest < Test::Unit::TestCase
class MockAction; end
class MockActionOther; end
def mock_fake_action(action_klass = nil, runner = nil)
action = action_klass ? action_klass.new(runner) : mock("action")
action.stubs(:prepare)
action.stubs(:execute!)
action.stubs(:cleanup)
stub_default_action_dependecies(action)
action
end
context "callbacks" do
setup do
@runner = Vagrant::Actions::Runner.new
end
context "around callbacks" do
should "invoke before/after_name for around callbacks" do
block_obj = mock("block_obj")
around_seq = sequence("around_seq")
@runner.expects(:invoke_callback).with(:before_foo).once.in_sequence(around_seq)
block_obj.expects(:foo).once.in_sequence(around_seq)
@runner.expects(:invoke_callback).with(:after_foo).once.in_sequence(around_seq)
@runner.invoke_around_callback(:foo) do
block_obj.foo
end
end
should "forward arguments to invoke_callback" do
@runner.expects(:invoke_callback).with(:before_foo, "foo").once
@runner.expects(:invoke_callback).with(:after_foo, "foo").once
@runner.invoke_around_callback(:foo, "foo") do; end
end
end
should "not invoke callback on actions which don't respond to it" do
action = mock("action")
action.stubs(:respond_to?).with(:foo).returns(false)
action.expects(:foo).never
assert_nothing_raised do
@runner.actions << action
@runner.invoke_callback(:foo)
end
end
should "invoke callback on actions which do respond to the method" do
action = mock("action")
action.expects(:foo).once
@runner.actions << action
@runner.invoke_callback(:foo)
end
should "collect all the results and return them as an array" do
result = []
3.times do |i|
action = mock("action#{i}")
action.expects(:foo).returns("foo#{i}").once
@runner.actions << action
result << "foo#{i}"
end
assert_equal result, @runner.invoke_callback(:foo)
end
end
context "finding actions" do
setup do
@runner = Vagrant::Actions::Runner.new
end
should "return nil if the action could not be found" do
assert_nil @runner.find_action(Vagrant::Actions::VM::Export)
end
should "return the first instance of the action found" do
@runner.add_action(Vagrant::Actions::VM::Export)
@runner.add_action(Vagrant::Actions::VM::Export)
assert @runner.actions[0].equal?(@runner.find_action(Vagrant::Actions::VM::Export))
end
end
context "adding actions" do
setup do
@runner = Vagrant::Actions::Runner.new
end
should "initialize the action when added" do
action_klass = mock("action_class")
action_inst = mock("action_inst")
action_klass.expects(:new).once.returns(action_inst)
@runner.add_action(action_klass)
assert_equal 1, @runner.actions.length
end
should "initialize the action with given arguments when added" do
action_klass = mock("action_class")
action_klass.expects(:new).with(@runner, "foo", "bar").once
@runner.add_action(action_klass, "foo", "bar")
end
end
context "class method execute" do
should "run actions on class method execute!" do
vm = mock("vm")
execute_seq = sequence("execute_seq")
Vagrant::Actions::Runner.expects(:new).returns(vm).in_sequence(execute_seq)
vm.expects(:add_action).with("foo").in_sequence(execute_seq)
vm.expects(:execute!).once.in_sequence(execute_seq)
Vagrant::Actions::Runner.execute!("foo")
end
should "forward arguments to add_action on class method execute!" do
vm = mock("vm")
execute_seq = sequence("execute_seq")
Vagrant::Actions::Runner.expects(:new).returns(vm).in_sequence(execute_seq)
vm.expects(:add_action).with("foo", "bar", "baz").in_sequence(execute_seq)
vm.expects(:execute!).once.in_sequence(execute_seq)
Vagrant::Actions::Runner.execute!("foo", "bar", "baz")
end
end
context "instance method execute" do
setup do
@runner = Vagrant::Actions::Runner.new
@runner.stubs(:action_klasses).returns([Vagrant::Actions::Base])
end
should "clear the actions and run a single action if given to execute!" do
action = mock("action")
run_action = mock("action_run")
stub_default_action_dependecies(run_action)
run_class = mock("run_class")
run_class.expects(:new).once.returns(run_action)
@runner.actions << action
[:prepare, :execute!, :cleanup].each do |method|
action.expects(method).never
run_action.expects(method).once
end
@runner.execute!(run_class)
end
should "clear actions after running execute!" do
@runner.actions << mock_fake_action
assert !@runner.actions.empty? # sanity
@runner.execute!
assert @runner.actions.empty?
end
should "run #prepare on all actions, then #execute!" do
action_seq = sequence("action_seq")
actions = []
[MockAction, MockActionOther].each_with_index do |klass, i|
action = mock("action#{i}")
action.expects(:class).returns(klass)
stub_default_action_dependecies(action)
@runner.actions << action
actions << action
end
[:prepare, :execute!, :cleanup].each do |method|
actions.each do |action|
action.expects(method).once.in_sequence(action_seq)
end
end
@runner.execute!
end
context "exceptions" do
setup do
@actions = [MockAction, MockActionOther].map do |klass|
action = mock_fake_action
action.expects(:class).returns(klass)
action.stubs(:rescue)
@runner.actions << action
action
end
@exception = Exception.new
end
should "call #rescue on each action if an exception is raised during execute!" do
@actions.each do |a|
a.expects(:rescue).with(@exception).once
end
@actions[0].stubs(:execute!).raises(@exception)
@runner.expects(:error_and_exit).never
assert_raises(Exception) { @runner.execute! }
end
should "call #rescue on each action if an exception is raised during prepare" do
@actions.each do |a|
a.expects(:rescue).with(@exception).once
end
@actions[0].stubs(:prepare).raises(@exception)
@runner.expects(:error_and_exit).never
assert_raises(Exception) { @runner.execute! }
end
should "call error_and_exit if it is an ActionException" do
@exception = Vagrant::Actions::ActionException.new("foo")
@actions[0].stubs(:prepare).raises(@exception)
@runner.expects(:error_and_exit).with(@exception.key, @exception.data).once
@runner.execute!
end
end
end
context "actions" do
setup do
@runner = Vagrant::Actions::Runner.new
end
should "setup actions to be an array" do
assert_nil @runner.instance_variable_get(:@actions)
actions = @runner.actions
assert actions.is_a?(Array)
assert actions.equal?(@runner.actions)
end
should "be empty initially" do
assert @runner.actions.empty?
end
end
context "duplicate action exceptions" do
setup do
@runner = Vagrant::Actions::Runner.new
end
should "should be raised when a duplicate is added" do
action = mock_fake_action
2.times {@runner.actions << action }
assert_raise Vagrant::Actions::DuplicateActionException do
@runner.execute!
end
end
should "should not be raise when no duplicate actions are present" do
@runner.actions << mock_fake_action(Vagrant::Actions::Base, @runner)
@runner.actions << mock_fake_action(Vagrant::Actions::VM::Halt, @runner)
assert_nothing_raised { @runner.execute! }
end
should "should not raise when a single action is specified" do
assert_nothing_raised { @runner.execute!(Vagrant::Actions::Base) }
end
end
end