269 lines
8.0 KiB
Ruby
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
|