Import action. Erroneous environments for actions.

This commit is contained in:
Mitchell Hashimoto 2010-07-04 08:52:01 +02:00
parent 64b533edc4
commit 67729304a2
7 changed files with 124 additions and 2 deletions

View File

@ -3,6 +3,8 @@ module Vagrant
# has an instance of {Action} to allow for running in the context of # has an instance of {Action} to allow for running in the context of
# the environment. # the environment.
class Action class Action
include Util
class << self class << self
# Returns the list of registered actions. # Returns the list of registered actions.
def actions def actions
@ -37,7 +39,17 @@ module Vagrant
# @param [Object] callable An object which responds to `call`. # @param [Object] callable An object which responds to `call`.
def run(callable) def run(callable)
callable = self.class.actions[callable] if callable.kind_of?(Symbol) callable = self.class.actions[callable] if callable.kind_of?(Symbol)
callable.call(Action::Environment.new(env))
action_environment = Action::Environment.new(env)
callable.call(action_environment)
if action_environment.error?
# Erroneous environment resulted. Properly display error
# message.
key, options = action_environment.error
error_and_exit(key, options)
return false
end
end end
end end
end end

View File

@ -9,8 +9,34 @@ module Vagrant
# action environment. # action environment.
attr_reader :env attr_reader :env
# If nonnil, the error associated with this environment. Set
# using {#error!}
attr_reader :error
def initialize(env) def initialize(env)
@env = env @env = env
@error = nil
end
# Returns a logger associated with the environment.
def logger
env.logger
end
# Flags the environment as erroneous. Stores the given key
# and options until the end of the action sequence.
#
# @param [Symbol] key Key to translation to display error message.
# @param [Hash] options Variables to pass to the translation
def error!(key, options=nil)
@error = [key, (options || {})]
end
# Returns boolean denoting if environment is in erroneous state.
#
# @return [Boolean]
def error?
!error.nil?
end end
end end
end end

View File

@ -7,8 +7,22 @@ module Vagrant
end end
def call(env) def call(env)
env.logger.info "Importing base VM (#{env.env.box.ovf_file})"
begin
# Import the virtual machine
env['vm'] = VirtualBox::VM.import(env.env.box.ovf_file) do |progress|
env.logger.report_progress(progress.percent, 100, false)
end
# Flag as erroneous and return if import failed
return env.error!(:virtualbox_import_failure) if !env['vm']
ensure
env.logger.clear_progress
end
# Import completed successfully. Continue the chain
@app.call(env) @app.call(env)
p env['vm']
end end
end end
end end

View File

@ -94,6 +94,12 @@ class Test::Unit::TestCase
vm vm
end end
def mock_action_data
app = lambda { |env| }
env = Vagrant::Action::Environment.new(mock_environment)
[app, env]
end
# Sets up the mocks and instantiates an action for testing # Sets up the mocks and instantiates an action for testing
def mock_action(action_klass, *args) def mock_action(action_klass, *args)
vm = mock("vboxvm") vm = mock("vboxvm")

View File

@ -3,6 +3,24 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
class ActionEnvironmentTest < Test::Unit::TestCase class ActionEnvironmentTest < Test::Unit::TestCase
setup do setup do
@klass = Vagrant::Action::Environment @klass = Vagrant::Action::Environment
@instance = @klass.new(mock_environment)
end end
should "setup the logger" do
assert_equal @instance.env.logger, @instance.logger
end
should "not be erroneous initially" do
assert !@instance.error?
end
should "mark as erroneous" do
@instance.error!(:key)
assert_equal [:key, {}], @instance.error
end
should "properly report erroneous" do
@instance.error!(:key)
assert @instance.error?
end
end end

View File

@ -0,0 +1,37 @@
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
class ImportVMActionTest < Test::Unit::TestCase
setup do
@klass = Vagrant::Action::VM::Import
@app, @env = mock_action_data
@instance = @klass.new(@app, @env)
ovf_file = "foo"
@box = mock("box")
@box.stubs(:ovf_file).returns(ovf_file)
@env.env.stubs(:box).returns(@box)
VirtualBox::VM.stubs(:import)
end
should "call import on VirtualBox with proper base" do
VirtualBox::VM.expects(:import).once.with(@env.env.box.ovf_file).returns("foo")
@instance.call(@env)
end
should "call next in chain on success and set VM" do
vm = mock("vm")
VirtualBox::VM.stubs(:import).returns(vm)
@app.expects(:call).with(@env).once
@instance.call(@env)
assert_equal vm, @env["vm"]
end
should "mark environment erroneous and not continue chain on failure" do
@app.expects(:call).never
@instance.call(@env)
assert @env.error?
end
end

View File

@ -32,5 +32,14 @@ class ActionTest < Test::Unit::TestCase
@klass.register(:call, callable) @klass.register(:call, callable)
@instance.run(:call) @instance.run(:call)
end end
should "error and exit if erroneous environment results" do
callable = lambda do |env|
env.error!(:key, :foo => :bar)
end
@instance.expects(:error_and_exit).with(:key, :foo => :bar)
@instance.run(callable)
end
end end
end end