Goodbye, Actions
This commit is contained in:
parent
13a46ac1bd
commit
f558304b50
|
@ -12,8 +12,7 @@ require File.expand_path("util/glob_loader", libdir)
|
|||
|
||||
# Load them up
|
||||
Vagrant::GlobLoader.glob_require(libdir, %w{util/stacked_proc_runner
|
||||
actions/base downloaders/base actions/collection actions/runner config
|
||||
provisioners/base provisioners/chef systems/base commands/base commands/box})
|
||||
downloaders/base config provisioners/base provisioners/chef systems/base commands/base commands/box})
|
||||
|
||||
# Initialize the built-in actions
|
||||
Vagrant::Action.builtin!
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
# Base class for any command actions.
|
||||
#
|
||||
# Actions are the smallest unit of functionality found within
|
||||
# Vagrant. Vagrant composes many actions together to execute
|
||||
# its complex tasks while keeping the individual pieces of a
|
||||
# task as discrete reusable actions. Actions are ran exclusively
|
||||
# by an {Runner action runner} which is simply a subclass of {Runner}.
|
||||
#
|
||||
# Actions work by implementing any or all of the following methods
|
||||
# which a {Runner} executes:
|
||||
#
|
||||
# * `prepare` - Called once for each action before any action has `execute!`
|
||||
# called. This is meant for basic setup.
|
||||
# * `execute!` - This is where the meat of the action typically goes;
|
||||
# the main code which executes the action.
|
||||
# * `cleanup` - This is called exactly once for each action after every
|
||||
# other action is completed. It is meant for cleaning up any resources.
|
||||
# * `rescue` - This is called if an exception occurs in _any action_. This
|
||||
# gives every other action a chance to clean itself up.
|
||||
#
|
||||
# For details of each step of an action, read the specific function call
|
||||
# documentation below.
|
||||
class Base
|
||||
# The {Runner runner} which is executing the action
|
||||
attr_reader :runner
|
||||
|
||||
# Any options which are passed into the initializer as a hash.
|
||||
attr_reader :options
|
||||
|
||||
# Included so subclasses don't need to include it themselves.
|
||||
include Vagrant::Util
|
||||
|
||||
# A helper method for logging which simply gets the logger from
|
||||
# the runner. Since actions tend to log quite a bit, this
|
||||
# removes the need to prefix `logger` with `@runner` over and
|
||||
# over.
|
||||
def logger
|
||||
runner.env.logger
|
||||
end
|
||||
|
||||
# Initialization of the action, passing any arguments which may have
|
||||
# been given to the {Runner runner}. This method can be used by subclasses
|
||||
# to save any of the configuration options which are passed in.
|
||||
def initialize(runner, options=nil)
|
||||
@runner = runner
|
||||
@options = options || {}
|
||||
end
|
||||
|
||||
# This method is called once per action, allowing the action
|
||||
# to setup any callbacks, add more events, etc. Prepare is
|
||||
# called in the order the actions are defined, and the action
|
||||
# itself has no control over this.
|
||||
#
|
||||
# Examples of its usage:
|
||||
#
|
||||
# Perhaps we need an additional action only if a configuration is set:
|
||||
#
|
||||
# def prepare
|
||||
# @vm.actions << FooAction if Vagrant.config[:foo] == :bar
|
||||
# end
|
||||
#
|
||||
def prepare; end
|
||||
|
||||
# This method is called once, after preparing, to execute the
|
||||
# actual task. This method is responsible for calling any
|
||||
# callbacks. Adding new actions here will have unpredictable
|
||||
# effects and should never be done.
|
||||
#
|
||||
# Examples of its usage:
|
||||
#
|
||||
# def execute!
|
||||
# @vm.invoke_callback(:before_oven, "cookies")
|
||||
# # Do lots of stuff here
|
||||
# @vm.invoke_callback(:after_oven, "more", "than", "one", "option")
|
||||
# end
|
||||
#
|
||||
def execute!; end
|
||||
|
||||
# This method is called after all actions have finished executing.
|
||||
# It is meant as a place where final cleanup code can be done, knowing
|
||||
# that all other actions are finished using your data.
|
||||
def cleanup; end
|
||||
|
||||
# This method is only called if some exception occurs in the chain
|
||||
# of actions. If an exception is raised in any action in the current
|
||||
# chain, then every action part of that chain has {#rescue} called
|
||||
# before raising the exception further. This method should be used to
|
||||
# perform any cleanup necessary in the face of errors.
|
||||
#
|
||||
# **Warning:** Since this method is called when an exception is already
|
||||
# raised, be _extra careful_ when implementing this method to handle
|
||||
# all your own exceptions, otherwise it'll mask the initially raised
|
||||
# exception.
|
||||
def rescue(exception); end
|
||||
|
||||
# The following two methods are used for declaring action dependencies.
|
||||
# For example, you require that the reload action be in place before
|
||||
# a your new FooAction you might do the following
|
||||
#
|
||||
# def follows; [Reload] end
|
||||
|
||||
# This method is called when the runner is determining the actions that
|
||||
# must precede a given action. You would say "This action follows [Action1, Action2]"
|
||||
def follows; [] end
|
||||
|
||||
# This method is called when the runner is determining the actions that
|
||||
# must follow a given action. You would say "This action precedes [Action3, Action4]
|
||||
def precedes; [] end
|
||||
end
|
||||
|
||||
# An exception which occured within an action. This should be used instead of
|
||||
# {Vagrant::Util#error_and_exit error_and_exit}, since it allows the {Runner} to call
|
||||
# {Base#rescue rescue} on all the actions and properly exit. Any message
|
||||
# passed into the {ActionException} is then shown and and vagrant exits.
|
||||
class ActionException < Exception
|
||||
attr_reader :key
|
||||
attr_reader :data
|
||||
|
||||
def initialize(key, data = {})
|
||||
@key = key
|
||||
@data = data
|
||||
|
||||
message = Vagrant::Util::Translator.t(key, data)
|
||||
super(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module Box
|
||||
# A meta-action which adds a box by downloading and unpackaging it.
|
||||
# This action downloads and unpackages a box with a given URI. This
|
||||
# is a _meta action_, meaning it simply adds more actions to the
|
||||
# action chain, and those actions do the work.
|
||||
#
|
||||
# This is the action called by {Box#add}.
|
||||
class Add < Base
|
||||
def prepare
|
||||
if File.exists?(@runner.directory)
|
||||
raise ActionException.new(:box_add_already_exists, :box_name => @runner.name)
|
||||
end
|
||||
|
||||
@runner.add_action(Download)
|
||||
@runner.add_action(Unpackage)
|
||||
@runner.add_action(Verify)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,14 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module Box
|
||||
# Action to destroy a box. This action is not reversible and expects
|
||||
# to be called by a {Box} object.
|
||||
class Destroy < Base
|
||||
def execute!
|
||||
logger.info "Deleting box directory..."
|
||||
FileUtils.rm_rf(@runner.directory)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,67 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module Box
|
||||
# An action which acts on a box by downloading the box file from
|
||||
# the given URI into a temporary location. This action parses a
|
||||
# given URI and handles downloading it via one of the many Vagrant
|
||||
# downloads (such as {Vagrant::Downloaders::File}).
|
||||
#
|
||||
# This action cleans itself up by removing the downloaded box file.
|
||||
class Download < Base
|
||||
BASENAME = "box"
|
||||
BUFFERSIZE = 1048576 # 1 MB
|
||||
|
||||
attr_reader :downloader
|
||||
|
||||
def prepare
|
||||
# Check the URI given and prepare a downloader
|
||||
[Downloaders::HTTP, Downloaders::File].each do |dler|
|
||||
if dler.match?(@runner.uri)
|
||||
logger.info "Downloading via #{dler}..."
|
||||
@downloader = dler.new(@runner.env)
|
||||
end
|
||||
end
|
||||
|
||||
raise ActionException.new(:box_download_unknown_type) unless @downloader
|
||||
|
||||
# Prepare the downloader
|
||||
@downloader.prepare(@runner.uri)
|
||||
end
|
||||
|
||||
def execute!
|
||||
with_tempfile do |tempfile|
|
||||
download_to(tempfile)
|
||||
@runner.temp_path = tempfile.path
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup
|
||||
if @runner.temp_path && File.exist?(@runner.temp_path)
|
||||
logger.info "Cleaning up downloaded box..."
|
||||
File.unlink(@runner.temp_path)
|
||||
end
|
||||
end
|
||||
|
||||
def rescue(exception)
|
||||
cleanup
|
||||
end
|
||||
|
||||
def with_tempfile
|
||||
logger.info "Creating tempfile for storing box file..."
|
||||
File.open(box_temp_path, Platform.tar_file_options) do |tempfile|
|
||||
yield tempfile
|
||||
end
|
||||
end
|
||||
|
||||
def box_temp_path
|
||||
File.join(@runner.env.tmp_path, BASENAME + Time.now.to_i.to_s)
|
||||
end
|
||||
|
||||
def download_to(f)
|
||||
logger.info "Copying box to temporary location..."
|
||||
downloader.download!(@runner.uri, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,42 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module Box
|
||||
# This action unpackages a downloaded box file into its final
|
||||
# box destination within the vagrant home folder.
|
||||
class Unpackage < Base
|
||||
def execute!
|
||||
@runner.invoke_around_callback(:unpackage) do
|
||||
setup_box_dir
|
||||
decompress
|
||||
end
|
||||
end
|
||||
|
||||
def rescue(exception)
|
||||
if File.directory?(box_dir)
|
||||
logger.info "An error occurred, rolling back box unpackaging..."
|
||||
FileUtils.rm_rf(box_dir)
|
||||
end
|
||||
end
|
||||
|
||||
def setup_box_dir
|
||||
if File.directory?(box_dir)
|
||||
error_and_exit(:box_already_exists, :box_name => @runner.name)
|
||||
end
|
||||
|
||||
FileUtils.mkdir_p(box_dir)
|
||||
end
|
||||
|
||||
def box_dir
|
||||
@runner.directory
|
||||
end
|
||||
|
||||
def decompress
|
||||
Dir.chdir(box_dir) do
|
||||
logger.info "Extracting box to #{box_dir}..."
|
||||
Archive::Tar::Minitar.unpack(@runner.temp_path, box_dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module Box
|
||||
# This action verifies that a given box is valid. This works by attempting
|
||||
# to read/interpret the appliance file (OVF). If the reading succeeds, then
|
||||
# the box is assumed to be valid.
|
||||
class Verify < Base
|
||||
def execute!
|
||||
logger.info "Verifying box..."
|
||||
reload_configuration
|
||||
verify_appliance
|
||||
end
|
||||
|
||||
def reload_configuration
|
||||
# We have to reload the environment config since we _just_ added the
|
||||
# box. We do this by setting the current box to the recently added box,
|
||||
# then reloading
|
||||
@runner.env.config.vm.box = @runner.name
|
||||
@runner.env.load_box!
|
||||
@runner.env.load_config!
|
||||
end
|
||||
|
||||
def verify_appliance
|
||||
# We now try to read the applince. If it succeeds, we return true.
|
||||
VirtualBox::Appliance.new(@runner.ovf_file)
|
||||
rescue Exception
|
||||
raise ActionException.new(:box_verification_failed)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,36 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
class Collection < Array
|
||||
def dependencies!
|
||||
each_with_index do |action, i|
|
||||
action.follows.each do |klass|
|
||||
unless self[0..i].klasses.include?(klass)
|
||||
raise DependencyNotSatisfiedException.new("#{action.class} action must follow #{klass}")
|
||||
end
|
||||
end
|
||||
|
||||
action.precedes.each do |klass|
|
||||
unless self[i..length].klasses.include?(klass)
|
||||
raise DependencyNotSatisfiedException.new("#{action.class} action must precede #{klass}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def duplicates?
|
||||
klasses.uniq.size != size
|
||||
end
|
||||
|
||||
def duplicates!
|
||||
raise DuplicateActionException.new if duplicates?
|
||||
end
|
||||
|
||||
def klasses
|
||||
map { |o| o.class }
|
||||
end
|
||||
end
|
||||
|
||||
class DuplicateActionException < Exception; end
|
||||
class DependencyNotSatisfiedException < Exception; end
|
||||
end
|
||||
end
|
|
@ -1,131 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
# Base class for any class which will act as a runner
|
||||
# for actions. A runner handles queueing up and executing actions,
|
||||
# and executing the methods of an action in the proper order. The
|
||||
# action runner also handles invoking callbacks that actions may
|
||||
# request.
|
||||
#
|
||||
# # Executing Actions
|
||||
#
|
||||
# Actions can be executed by adding them and executing them all
|
||||
# at once:
|
||||
#
|
||||
# runner = Vagrant::Actions::Runner.new
|
||||
# runner.add_action(FooAction)
|
||||
# runner.add_action(BarAction)
|
||||
# runner.add_action(BazAction)
|
||||
# runner.execute!
|
||||
#
|
||||
# Single actions have a shorthand to be executed:
|
||||
#
|
||||
# Vagrant::Actions::Runner.execute!(FooAction)
|
||||
#
|
||||
# Arguments may be passed into added actions by adding them after
|
||||
# the action class:
|
||||
#
|
||||
# runner.add_action(FooAction, "many", "arguments", "may", "follow")
|
||||
#
|
||||
class Runner
|
||||
include Vagrant::Util
|
||||
|
||||
class << self
|
||||
# Executes a specific action, optionally passing in any arguments to that
|
||||
# action. This method is shorthand to initializing a runner, adding a single
|
||||
# action, and executing it.
|
||||
def execute!(action_klass, *args)
|
||||
runner = new
|
||||
runner.add_action(action_klass, *args)
|
||||
runner.execute!
|
||||
end
|
||||
end
|
||||
|
||||
# Returns an array of all the actions in queue. Because this
|
||||
# will persist accross calls (calling {#actions} twice will yield
|
||||
# exactly the same object), to clear or modify it, use the ruby
|
||||
# array methods which act on `self`, such as `Array#clear`.
|
||||
#
|
||||
# @return [Array]
|
||||
def actions
|
||||
@actions ||= Actions::Collection.new
|
||||
end
|
||||
|
||||
# Returns the first action instance which matches the given class.
|
||||
#
|
||||
# @param [Class] action_klass The action to search for in the queue
|
||||
# @return [Object]
|
||||
def find_action(action_klass)
|
||||
actions.find { |a| a.is_a?(action_klass) }
|
||||
end
|
||||
|
||||
# Add an action to the list of queued actions to execute. This method
|
||||
# appends the given action class to the end of the queue. Any arguments
|
||||
# given after the class are passed into the class constructor.
|
||||
def add_action(action_klass, *args)
|
||||
actions << action_klass.new(self, *args)
|
||||
end
|
||||
|
||||
# Execute the actions in queue. This method can also optionally be used
|
||||
# to execute a single action on an instance. The syntax for executing a
|
||||
# single method on an instance is the same as the {execute!} class method.
|
||||
def execute!(single_action=nil, *args)
|
||||
if single_action
|
||||
actions.clear
|
||||
add_action(single_action, *args)
|
||||
end
|
||||
|
||||
actions.duplicates!
|
||||
actions.dependencies!
|
||||
|
||||
# Call the prepare method on each once its
|
||||
# initialized, then call the execute! method
|
||||
begin
|
||||
[:prepare, :execute!, :cleanup].each do |method|
|
||||
actions.each do |action|
|
||||
action.send(method)
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
# Run the rescue code to do any emergency cleanup
|
||||
actions.each do |action|
|
||||
action.rescue(e)
|
||||
end
|
||||
|
||||
# If its an ActionException, error and exit the message
|
||||
if e.is_a?(ActionException)
|
||||
error_and_exit(e.key, e.data)
|
||||
return
|
||||
end
|
||||
|
||||
# Finally, reraise the exception
|
||||
raise
|
||||
end
|
||||
|
||||
# Clear the actions
|
||||
actions.clear
|
||||
end
|
||||
|
||||
# Invokes an "around callback" which invokes before_name and
|
||||
# after_name for the given callback name, yielding a block between
|
||||
# callback invokations.
|
||||
def invoke_around_callback(name, *args)
|
||||
invoke_callback("before_#{name}".to_sym, *args)
|
||||
yield
|
||||
invoke_callback("after_#{name}".to_sym, *args)
|
||||
end
|
||||
|
||||
# Invokes a single callback. This method will go through each action
|
||||
# and call the method given in the parameter `name` if the action
|
||||
# responds to it.
|
||||
def invoke_callback(name, *args)
|
||||
# Attempt to call the method for the callback on each of the
|
||||
# actions
|
||||
results = []
|
||||
actions.each do |action|
|
||||
results << action.send(name, *args) if action.respond_to?(name)
|
||||
end
|
||||
results
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Boot < Base
|
||||
def execute!
|
||||
@runner.invoke_around_callback(:boot) do
|
||||
# Startup the VM
|
||||
boot
|
||||
|
||||
# Wait for it to complete booting, or error if we could
|
||||
# never detect it booted up successfully
|
||||
if !wait_for_boot
|
||||
error_and_exit(:vm_failed_to_boot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def boot
|
||||
logger.info "Booting VM..."
|
||||
@runner.vm.start(@runner.env.config.vm.boot_mode)
|
||||
end
|
||||
|
||||
def wait_for_boot(sleeptime=5)
|
||||
logger.info "Waiting for VM to boot..."
|
||||
|
||||
@runner.env.config.ssh.max_tries.to_i.times do |i|
|
||||
logger.info "Trying to connect (attempt ##{i+1} of #{@runner.env.config[:ssh][:max_tries]})..."
|
||||
|
||||
if @runner.ssh.up?
|
||||
logger.info "VM booted and ready for use!"
|
||||
return true
|
||||
end
|
||||
|
||||
sleep sleeptime
|
||||
end
|
||||
|
||||
logger.info "Failed to connect to VM! Failed to boot?"
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Customize < Base
|
||||
def execute!
|
||||
if !runner.env.config.vm.proc_stack.empty?
|
||||
logger.info "Running any VM customizations..."
|
||||
|
||||
# Run the customization procs over the VM
|
||||
runner.env.config.vm.run_procs!(@runner.vm)
|
||||
|
||||
# Save the vm
|
||||
runner.vm.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Destroy < Base
|
||||
def execute!
|
||||
@runner.invoke_around_callback(:destroy) do
|
||||
destroy_vm
|
||||
update_dotfile
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_vm
|
||||
logger.info "Destroying VM and associated drives..."
|
||||
@runner.vm.destroy(:destroy_medium => :delete)
|
||||
@runner.vm = nil
|
||||
end
|
||||
|
||||
def update_dotfile
|
||||
@runner.env.update_dotfile
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Down < Base
|
||||
def prepare
|
||||
# The true as the 2nd parameter always forces the shutdown so its
|
||||
# fast (since we're destroying anyways)
|
||||
@runner.add_action(Halt, :force => true) if @runner.vm.running?
|
||||
@runner.add_action(Network)
|
||||
@runner.add_action(Destroy)
|
||||
end
|
||||
|
||||
def after_halt
|
||||
# This sleep is necessary to wait for the VM to clean itself up.
|
||||
# There appears to be nothing in the API that does this "wait"
|
||||
# for us.
|
||||
Kernel.sleep(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,45 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Export < Base
|
||||
attr_reader :temp_dir
|
||||
|
||||
def execute!
|
||||
setup_temp_dir
|
||||
export
|
||||
end
|
||||
|
||||
def cleanup
|
||||
if temp_dir
|
||||
logger.info "Removing temporary export directory..."
|
||||
FileUtils.rm_r(temp_dir)
|
||||
end
|
||||
end
|
||||
|
||||
def rescue(exception)
|
||||
cleanup
|
||||
end
|
||||
|
||||
def setup_temp_dir
|
||||
@temp_dir = File.join(@runner.env.tmp_path, Time.now.to_i.to_s)
|
||||
|
||||
logger.info "Creating temporary directory for export..."
|
||||
FileUtils.mkpath(temp_dir)
|
||||
end
|
||||
|
||||
def ovf_path
|
||||
File.join(temp_dir, @runner.env.config.vm.box_ovf)
|
||||
end
|
||||
|
||||
def export
|
||||
logger.info "Exporting VM to #{ovf_path}..."
|
||||
@runner.vm.export(ovf_path) do |progress|
|
||||
logger.report_progress(progress.percent, 100, false)
|
||||
end
|
||||
|
||||
logger.clear_progress
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,134 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class ForwardPorts < Base
|
||||
def prepare
|
||||
external_collision_check
|
||||
end
|
||||
|
||||
# This method checks for any port collisions with any VMs
|
||||
# which are already created (by Vagrant or otherwise).
|
||||
# report the collisions detected or will attempt to fix them
|
||||
# automatically if the port is configured to do so.
|
||||
def external_collision_check
|
||||
existing = used_ports
|
||||
runner.env.config.vm.forwarded_ports.each do |name, options|
|
||||
if existing.include?(options[:hostport].to_s)
|
||||
handle_collision(name, options, existing)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Handles any collisions. This method will either attempt to
|
||||
# fix the collision automatically or will raise an error if
|
||||
# auto fixing is disabled.
|
||||
def handle_collision(name, options, existing_ports)
|
||||
if !options[:auto]
|
||||
# Auto fixing is disabled for this port forward, so we
|
||||
# must throw an error so the user can fix it.
|
||||
raise ActionException.new(:vm_port_collision, :name => name, :hostport => options[:hostport].to_s, :guestport => options[:guestport].to_s, :adapter => options[:adapter])
|
||||
end
|
||||
|
||||
# Get the auto port range and get rid of the used ports and
|
||||
# ports which are being used in other forwards so we're just
|
||||
# left with available ports.
|
||||
range = runner.env.config.vm.auto_port_range.to_a
|
||||
range -= runner.env.config.vm.forwarded_ports.collect { |n, o| o[:hostport].to_i }
|
||||
range -= existing_ports
|
||||
|
||||
if range.empty?
|
||||
raise ActionException.new(:vm_port_auto_empty, :vm_name => @runner.name, :name => name, :options => options)
|
||||
end
|
||||
|
||||
# Set the port up to be the first one and add that port to
|
||||
# the used list.
|
||||
options[:hostport] = range.shift
|
||||
existing_ports << options[:hostport]
|
||||
|
||||
# Notify the user
|
||||
logger.info "Fixed port collision: #{name} now on port #{options[:hostport]}"
|
||||
end
|
||||
|
||||
def execute!
|
||||
clear
|
||||
forward_ports
|
||||
end
|
||||
|
||||
def clear
|
||||
if used_ports.length > 0
|
||||
logger.info "Deleting any previously set forwarded ports..."
|
||||
clear_ports
|
||||
runner.reload!
|
||||
end
|
||||
end
|
||||
|
||||
def forward_ports
|
||||
logger.info "Forwarding ports..."
|
||||
|
||||
runner.env.config.vm.forwarded_ports.each do |name, options|
|
||||
adapter = options[:adapter]
|
||||
|
||||
# Assuming the only reason to establish port forwarding is because the VM is using Virtualbox NAT networking.
|
||||
# Host-only or Bridged networking don't require port-forwarding and establishing forwarded ports on these
|
||||
# attachment types has uncertain behaviour.
|
||||
if @runner.vm.network_adapters[adapter].attachment_type == :nat
|
||||
logger.info "Forwarding \"#{name}\": #{options[:guestport]} on adapter \##{adapter+1} => #{options[:hostport]}"
|
||||
forward_port(name, options)
|
||||
else
|
||||
logger.info "VirtualBox adapter \##{adapter+1} not configured as \"NAT\"."
|
||||
logger.info "Skipped port forwarding \"#{name}\": #{options[:guestport]} on adapter\##{adapter+1} => #{options[:hostport]}"
|
||||
end
|
||||
end
|
||||
|
||||
runner.vm.save
|
||||
runner.reload!
|
||||
end
|
||||
|
||||
#------------------------------------------------------------
|
||||
# VirtualBox version-specific helpers below. VirtualBox 3.2
|
||||
# introduced a breaking change into the way that forwarded
|
||||
# ports are handled. For backwards compatability with 3.1, we
|
||||
# need this trickery.
|
||||
#------------------------------------------------------------
|
||||
# TODO In a future version, fix this.
|
||||
|
||||
# Returns an array of used ports. This method is implemented
|
||||
# differently depending on the VirtualBox version, but the
|
||||
# behavior is the same.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
def used_ports
|
||||
result = VirtualBox::VM.all.collect do |vm|
|
||||
if vm.running? && vm.uuid != runner.uuid
|
||||
vm.network_adapters.collect do |na|
|
||||
na.nat_driver.forwarded_ports.collect do |fp|
|
||||
fp.hostport.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
result.flatten.uniq
|
||||
end
|
||||
|
||||
# Deletes existing forwarded ports.
|
||||
def clear_ports
|
||||
runner.vm.network_adapters.each do |na|
|
||||
na.nat_driver.forwarded_ports.dup.each do |fp|
|
||||
fp.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Forwards a port.
|
||||
def forward_port(name, options)
|
||||
port = VirtualBox::NATForwardedPort.new
|
||||
port.name = name
|
||||
port.guestport = options[:guestport]
|
||||
port.hostport = options[:hostport]
|
||||
runner.vm.network_adapters[options[:adapter]].nat_driver.forwarded_ports << port
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Halt < Base
|
||||
def execute!
|
||||
raise ActionException.new(:vm_not_running) unless @runner.vm.running?
|
||||
|
||||
@runner.invoke_around_callback(:halt) do
|
||||
@runner.system.halt if !options[:force]
|
||||
|
||||
if @runner.vm.state(true) != :powered_off
|
||||
logger.info "Forcing shutdown of VM..."
|
||||
@runner.vm.stop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def force?
|
||||
!!options[:force]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Import < Base
|
||||
def execute!
|
||||
@runner.invoke_around_callback(:import) do
|
||||
Busy.busy do
|
||||
logger.info "Importing base VM (#{@runner.env.box.ovf_file})..."
|
||||
# Use the first argument passed to the action
|
||||
@runner.vm = VirtualBox::VM.import(@runner.env.box.ovf_file) do |progress|
|
||||
logger.report_progress(progress.percent, 100, false)
|
||||
end
|
||||
|
||||
logger.clear_progress
|
||||
|
||||
raise ActionException.new(:virtualbox_import_failure) unless @runner.vm
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,51 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class MoveHardDrive < Base
|
||||
def execute!
|
||||
unless @runner.powered_off?
|
||||
error_and_exit(:vm_power_off_to_move_hd)
|
||||
return
|
||||
end
|
||||
|
||||
destroy_drive_after { clone_and_attach }
|
||||
end
|
||||
|
||||
def hard_drive
|
||||
@hard_drive ||= find_hard_drive
|
||||
end
|
||||
|
||||
# TODO won't work if the first disk is not the boot disk or even if there are multiple disks
|
||||
def find_hard_drive
|
||||
@runner.vm.storage_controllers.each do |sc|
|
||||
sc.devices.each do |d|
|
||||
return d if d.image.is_a?(VirtualBox::HardDrive)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def clone_and_attach
|
||||
logger.info "Cloning current VM Disk to new location (#{new_image_path})..."
|
||||
hard_drive.image = hard_drive.image.clone(new_image_path, @runner.env.config.vm.disk_image_format, true)
|
||||
|
||||
logger.info "Attaching new disk to VM ..."
|
||||
@runner.vm.save
|
||||
end
|
||||
|
||||
def destroy_drive_after
|
||||
old_image = hard_drive.image
|
||||
|
||||
yield
|
||||
|
||||
logger.info "Destroying old VM Disk (#{old_image.filename})..."
|
||||
old_image.destroy(true)
|
||||
end
|
||||
|
||||
# Returns the path to the new location for the hard drive
|
||||
def new_image_path
|
||||
File.join(@runner.env.config.vm.hd_location, hard_drive.image.filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,149 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Network < Base
|
||||
def prepare
|
||||
# Verify that the given network options are valid
|
||||
runner.env.config.vm.network_options.compact.each do |network_options|
|
||||
verify_no_bridge_collision(network_options)
|
||||
end
|
||||
end
|
||||
|
||||
def before_destroy
|
||||
# We need to check if the host only network specified by any
|
||||
# of the adapters would not have any more clients if it was
|
||||
# destroyed. And if so, then destroy the host only network
|
||||
# itself.
|
||||
interfaces = runner.vm.network_adapters.collect do |adapter|
|
||||
adapter.host_interface_object
|
||||
end
|
||||
|
||||
interfaces.compact.uniq.each do |interface|
|
||||
# Destroy the network interface if there is only one
|
||||
# attached VM (which must be this VM)
|
||||
if interface.attached_vms.length == 1
|
||||
logger.info "Destroying unused network interface..."
|
||||
interface.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def before_boot
|
||||
assign_network if enable_network?
|
||||
end
|
||||
|
||||
def after_boot
|
||||
if enable_network?
|
||||
logger.info "Enabling host only network..."
|
||||
|
||||
runner.system.prepare_host_only_network
|
||||
|
||||
runner.env.config.vm.network_options.compact.each do |network_options|
|
||||
runner.system.enable_host_only_network(network_options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def enable_network?
|
||||
!runner.env.config.vm.network_options.compact.empty?
|
||||
end
|
||||
|
||||
# Enables and assigns the host only network to the proper
|
||||
# adapter on the VM, and saves the adapter.
|
||||
def assign_network
|
||||
logger.info "Preparing host only network..."
|
||||
|
||||
runner.env.config.vm.network_options.compact.each do |network_options|
|
||||
adapter = runner.vm.network_adapters[network_options[:adapter]]
|
||||
adapter.enabled = true
|
||||
adapter.attachment_type = :host_only
|
||||
adapter.host_interface = network_name(network_options)
|
||||
adapter.save
|
||||
end
|
||||
end
|
||||
|
||||
# Verifies that there is no collision with a bridged network interface
|
||||
# for the given network options.
|
||||
def verify_no_bridge_collision(net_options)
|
||||
# First try to find a matching network
|
||||
interfaces = VirtualBox::Global.global.host.network_interfaces
|
||||
interfaces.each do |ni|
|
||||
next if ni.interface_type == :host_only
|
||||
|
||||
result = if net_options[:name]
|
||||
true if net_options[:name] == ni.name
|
||||
else
|
||||
true if matching_network?(ni, net_options)
|
||||
end
|
||||
|
||||
raise ActionException.new(:network_collides) if result
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the name of the proper host only network, or creates
|
||||
# it if it does not exist. Vagrant determines if the host only
|
||||
# network exists by comparing the netmask and the IP.
|
||||
def network_name(net_options)
|
||||
# First try to find a matching network
|
||||
interfaces = VirtualBox::Global.global.host.network_interfaces
|
||||
interfaces.each do |ni|
|
||||
# Ignore non-host only interfaces which may also match,
|
||||
# since they're not valid options.
|
||||
next if ni.interface_type != :host_only
|
||||
|
||||
if net_options[:name]
|
||||
return ni.name if net_options[:name] == ni.name
|
||||
else
|
||||
return ni.name if matching_network?(ni, net_options)
|
||||
end
|
||||
end
|
||||
|
||||
raise ActionException.new(:network_not_found, :name => net_options[:name]) if net_options[:name]
|
||||
|
||||
# One doesn't exist, create it.
|
||||
logger.info "Creating new host only network for environment..."
|
||||
|
||||
ni = interfaces.create
|
||||
ni.enable_static(network_ip(net_options[:ip], net_options[:netmask]),
|
||||
net_options[:netmask])
|
||||
ni.name
|
||||
end
|
||||
|
||||
# Tests if a network matches the given options by applying the
|
||||
# netmask to the IP of the network and also to the IP of the
|
||||
# virtual machine and see if they match.
|
||||
def matching_network?(interface, net_options)
|
||||
interface.network_mask == net_options[:netmask] &&
|
||||
apply_netmask(interface.ip_address, interface.network_mask) ==
|
||||
apply_netmask(net_options[:ip], net_options[:netmask])
|
||||
end
|
||||
|
||||
# Applies a netmask to an IP and returns the corresponding
|
||||
# parts.
|
||||
def apply_netmask(ip, netmask)
|
||||
ip = split_ip(ip)
|
||||
netmask = split_ip(netmask)
|
||||
|
||||
ip.map do |part|
|
||||
part & netmask.shift
|
||||
end
|
||||
end
|
||||
|
||||
# Splits an IP and converts each portion into an int.
|
||||
def split_ip(ip)
|
||||
ip.split(".").map do |i|
|
||||
i.to_i
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a "network IP" which is a "good choice" for the IP
|
||||
# for the actual network based on the netmask.
|
||||
def network_ip(ip, netmask)
|
||||
parts = apply_netmask(ip, netmask)
|
||||
parts[3] += 1;
|
||||
parts.join(".")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,94 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Package < Base
|
||||
attr_reader :export_action
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
@temp_path = nil
|
||||
end
|
||||
|
||||
def prepare
|
||||
raise ActionException.new(:box_file_exists, :output_file => tar_path) if File.exist?(tar_path)
|
||||
|
||||
# Verify the existance of all the additional files, if any
|
||||
include_files.each do |file|
|
||||
raise ActionException.new(:package_include_file_doesnt_exist, :filename => file) unless File.exists?(file)
|
||||
end
|
||||
|
||||
# Get the export action and store a reference to it
|
||||
@export_action = @runner.find_action(Export)
|
||||
raise ActionException.new(:package_requires_export) unless @export_action
|
||||
end
|
||||
|
||||
def execute!
|
||||
compress
|
||||
end
|
||||
|
||||
def out_path
|
||||
options[:output] || "package"
|
||||
end
|
||||
|
||||
def include_files
|
||||
options[:include] || []
|
||||
end
|
||||
|
||||
def tar_path
|
||||
File.join(FileUtils.pwd, "#{out_path}#{@runner.env.config.package.extension}")
|
||||
end
|
||||
|
||||
def temp_path
|
||||
export_action.temp_dir
|
||||
end
|
||||
|
||||
# This method copies the include files (passed in via command line)
|
||||
# to the temporary directory so they are included in a sub-folder within
|
||||
# the actual box
|
||||
def copy_include_files
|
||||
if include_files.length > 0
|
||||
include_dir = File.join(temp_path, "include")
|
||||
FileUtils.mkdir_p(include_dir)
|
||||
|
||||
include_files.each do |f|
|
||||
logger.info "Packaging additional file: #{f}"
|
||||
FileUtils.cp(f, include_dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This method creates the auto-generated Vagrantfile at the root of the
|
||||
# box. This Vagrantfile contains the MAC address so that the user doesn't
|
||||
# have to worry about it.
|
||||
def create_vagrantfile
|
||||
File.open(File.join(temp_path, "Vagrantfile"), "w") do |f|
|
||||
f.write(TemplateRenderer.render("package_Vagrantfile", {
|
||||
:base_mac => @runner.vm.network_adapters.first.mac_address
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
def compress
|
||||
logger.info "Packaging VM into #{tar_path}..."
|
||||
File.open(tar_path, Platform.tar_file_options) do |tar|
|
||||
Archive::Tar::Minitar::Output.open(tar) do |output|
|
||||
begin
|
||||
current_dir = FileUtils.pwd
|
||||
|
||||
copy_include_files
|
||||
create_vagrantfile
|
||||
|
||||
FileUtils.cd(temp_path)
|
||||
Dir.glob(File.join(".", "**", "*")).each do |entry|
|
||||
Archive::Tar::Minitar.pack_file(entry, output)
|
||||
end
|
||||
ensure
|
||||
FileUtils.cd(current_dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,49 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Provision < Base
|
||||
attr_reader :provisioner
|
||||
|
||||
def intialize(*args)
|
||||
super
|
||||
|
||||
@provisioner = nil
|
||||
end
|
||||
|
||||
def prepare
|
||||
provisioner = @runner.env.config.vm.provisioner
|
||||
|
||||
if provisioner.nil?
|
||||
logger.info("Provisioning not enabled, ignoring this step")
|
||||
return
|
||||
end
|
||||
|
||||
if provisioner.is_a?(Class)
|
||||
@provisioner = provisioner.new(@runner)
|
||||
raise ActionException.new(:provisioner_invalid_class) unless @provisioner.is_a?(Provisioners::Base)
|
||||
elsif provisioner.is_a?(Symbol)
|
||||
# We have a few hard coded provisioners for built-ins
|
||||
mapping = {
|
||||
:chef_solo => Provisioners::ChefSolo,
|
||||
:chef_server => Provisioners::ChefServer
|
||||
}
|
||||
|
||||
provisioner_klass = mapping[provisioner]
|
||||
raise ActionException.new(:provisioner_unknown_type, :provisioner => provisioner.to_s) if provisioner_klass.nil?
|
||||
@provisioner = provisioner_klass.new(@runner)
|
||||
end
|
||||
|
||||
logger.info "Provisioning enabled with #{@provisioner.class}"
|
||||
@provisioner.prepare
|
||||
end
|
||||
|
||||
def execute!
|
||||
if provisioner
|
||||
logger.info "Beginning provisioning process..."
|
||||
provisioner.provision!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Reload < Base
|
||||
def prepare
|
||||
steps = [Customize, ForwardPorts, SharedFolders, Network, Boot]
|
||||
steps.unshift(Halt) if @runner.vm.running?
|
||||
steps << Provision if !@runner.env.config.vm.provisioner.nil?
|
||||
|
||||
steps.each do |action_klass|
|
||||
@runner.add_action(action_klass)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Resume < Base
|
||||
def execute!
|
||||
if !@runner.vm.saved?
|
||||
raise ActionException.new(:vm_not_suspended)
|
||||
end
|
||||
|
||||
logger.info "Resuming suspended VM..."
|
||||
@runner.start
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,98 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class SharedFolders < Base
|
||||
# This method returns an actual list of VirtualBox shared
|
||||
# folders to create and their proper path.
|
||||
def shared_folders
|
||||
runner.env.config.vm.shared_folders.inject({}) do |acc, data|
|
||||
key, value = data
|
||||
|
||||
# This to prevent overwriting the actual shared folders data
|
||||
value = value.dup
|
||||
|
||||
if value[:sync]
|
||||
# Syncing this folder. Change the guestpath to reflect
|
||||
# what we're actually mounting.
|
||||
value[:original] = value.dup
|
||||
value[:guestpath] = "#{value[:guestpath]}#{runner.env.config.unison.folder_suffix}"
|
||||
end
|
||||
|
||||
acc[key] = value
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
# This method returns the list of shared folders which are to
|
||||
# be synced via unison.
|
||||
def unison_folders
|
||||
shared_folders.inject({}) do |acc, data|
|
||||
key, value = data
|
||||
acc[key] = value if !!value[:sync]
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
def before_boot
|
||||
clear_shared_folders
|
||||
create_metadata
|
||||
end
|
||||
|
||||
def after_boot
|
||||
mount_shared_folders
|
||||
setup_unison
|
||||
end
|
||||
|
||||
def mount_shared_folders
|
||||
logger.info "Mounting shared folders..."
|
||||
|
||||
@runner.ssh.execute do |ssh|
|
||||
shared_folders.each do |name, data|
|
||||
logger.info "-- #{name}: #{data[:guestpath]}"
|
||||
@runner.system.mount_shared_folder(ssh, name, data[:guestpath])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup_unison
|
||||
return if unison_folders.empty?
|
||||
|
||||
runner.ssh.execute do |ssh|
|
||||
runner.system.prepare_unison(ssh)
|
||||
|
||||
logger.info "Creating unison crontab entries..."
|
||||
unison_folders.each do |name, data|
|
||||
runner.system.create_unison(ssh, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def clear_shared_folders
|
||||
if runner.vm.shared_folders.length > 0
|
||||
logger.info "Clearing previously set shared folders..."
|
||||
|
||||
folders = @runner.vm.shared_folders.dup
|
||||
folders.each do |shared_folder|
|
||||
shared_folder.destroy
|
||||
end
|
||||
|
||||
@runner.reload!
|
||||
end
|
||||
end
|
||||
|
||||
def create_metadata
|
||||
logger.info "Creating shared folders metadata..."
|
||||
|
||||
shared_folders.each do |name, data|
|
||||
folder = VirtualBox::SharedFolder.new
|
||||
folder.name = name
|
||||
folder.host_path = File.expand_path(data[:hostpath], runner.env.root_path)
|
||||
@runner.vm.shared_folders << folder
|
||||
end
|
||||
|
||||
@runner.vm.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Start < Base
|
||||
def prepare
|
||||
# Start is a "meta-action" so it really just queues up a bunch
|
||||
# of other actions in its place:
|
||||
steps = [Boot]
|
||||
if !@runner.vm || !@runner.vm.saved?
|
||||
steps.unshift([Customize, ForwardPorts, SharedFolders, Network])
|
||||
steps << Provision if provision?
|
||||
end
|
||||
|
||||
steps.flatten.each do |action_klass|
|
||||
@runner.add_action(action_klass, options)
|
||||
end
|
||||
end
|
||||
|
||||
def provision?
|
||||
enabled = options[:provision].nil? ? true : options[:provision]
|
||||
!@runner.env.config.vm.provisioner.nil? && enabled
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Suspend < Base
|
||||
def execute!
|
||||
if !@runner.vm.running?
|
||||
raise ActionException.new(:vm_not_running_for_suspend)
|
||||
end
|
||||
|
||||
logger.info "Saving VM state and suspending execution..."
|
||||
@runner.vm.save_state
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,53 +0,0 @@
|
|||
module Vagrant
|
||||
module Actions
|
||||
module VM
|
||||
class Up < Base
|
||||
def prepare
|
||||
# If the dotfile is not a file, raise error
|
||||
if File.exist?(@runner.env.dotfile_path) && !File.file?(@runner.env.dotfile_path)
|
||||
raise ActionException.new(:dotfile_error, :env => @runner.env)
|
||||
end
|
||||
|
||||
# Up is a "meta-action" so it really just queues up a bunch
|
||||
# of other actions in its place:
|
||||
steps = [Import, Start]
|
||||
steps.insert(0, MoveHardDrive) if @runner.env.config.vm.hd_location
|
||||
|
||||
steps.each do |action_klass|
|
||||
@runner.add_action(action_klass, options)
|
||||
end
|
||||
end
|
||||
|
||||
def after_import
|
||||
update_dotfile
|
||||
setup_mac_address
|
||||
check_guest_additions
|
||||
end
|
||||
|
||||
def update_dotfile
|
||||
logger.info "Persisting the VM UUID (#{@runner.uuid})..."
|
||||
@runner.env.update_dotfile
|
||||
end
|
||||
|
||||
def setup_mac_address
|
||||
logger.info "Matching MAC addresses..."
|
||||
@runner.vm.network_adapters.first.mac_address = @runner.env.config.vm.base_mac
|
||||
@runner.vm.save
|
||||
end
|
||||
|
||||
def check_guest_additions
|
||||
# Use the raw interface for now, while the virtualbox gem
|
||||
# doesn't support guest properties (due to cross platform issues)
|
||||
version = @runner.vm.interface.get_guest_property_value("/VirtualBox/GuestAdd/Version")
|
||||
if version.empty?
|
||||
logger.error Translator.t(:vm_additions_not_detected)
|
||||
elsif version != VirtualBox.version
|
||||
logger.error Translator.t(:vm_additions_version_mismatch,
|
||||
:guest_additions_version => version,
|
||||
:virtualbox_version => VirtualBox.version)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,7 +9,7 @@ module Vagrant
|
|||
|
||||
def prepare(source_url)
|
||||
if !::File.file?(source_url)
|
||||
raise Actions::ActionException.new(:downloader_file_doesnt_exist, :source_url => source_url)
|
||||
raise Action::ActionException.new(:downloader_file_doesnt_exist, :source_url => source_url)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -100,32 +100,6 @@ class Test::Unit::TestCase
|
|||
[app, env]
|
||||
end
|
||||
|
||||
# Sets up the mocks and instantiates an action for testing
|
||||
def mock_action(action_klass, *args)
|
||||
vm = mock("vboxvm")
|
||||
mock_vm = mock("vm")
|
||||
action = action_klass.new(mock_vm, *args)
|
||||
stub_default_action_dependecies(action)
|
||||
|
||||
mock_vm.stubs(:name).returns("foo")
|
||||
mock_vm.stubs(:vm).returns(vm)
|
||||
mock_vm.stubs(:vm=)
|
||||
mock_vm.stubs(:invoke_callback)
|
||||
mock_vm.stubs(:invoke_around_callback).yields
|
||||
mock_vm.stubs(:actions).returns([action])
|
||||
mock_vm.stubs(:env).returns(mock_environment)
|
||||
mock_vm.env.stubs(:logger).returns(quiet_logger("mock"))
|
||||
|
||||
mock_ssh = Vagrant::SSH.new(mock_vm.env)
|
||||
mock_ssh.stubs(:execute)
|
||||
|
||||
mock_vm.stubs(:ssh).returns(mock_ssh)
|
||||
|
||||
vm.stubs(:env).returns(mock_vm.env)
|
||||
|
||||
[mock_vm, vm, action]
|
||||
end
|
||||
|
||||
# Returns a resource logger which is safe for tests
|
||||
def quiet_logger(resource, env=nil)
|
||||
logger = Vagrant::ResourceLogger.new(resource, env)
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class BaseActionTest < Test::Unit::TestCase
|
||||
should "include the util class so subclasses have access to it" do
|
||||
assert Vagrant::Actions::Base.include?(Vagrant::Util)
|
||||
end
|
||||
|
||||
context "base instance" do
|
||||
setup do
|
||||
@mock_vm = mock("vm")
|
||||
@base = Vagrant::Actions::Base.new(@mock_vm)
|
||||
end
|
||||
|
||||
should "allow read-only access to the runner" do
|
||||
assert_equal @mock_vm, @base.runner
|
||||
end
|
||||
|
||||
should "implement prepare which does nothing" do
|
||||
assert_nothing_raised do
|
||||
assert @base.respond_to?(:prepare)
|
||||
@base.prepare
|
||||
end
|
||||
end
|
||||
|
||||
should "implement the execute! method which does nothing" do
|
||||
assert_nothing_raised do
|
||||
assert @base.respond_to?(:execute!)
|
||||
@base.execute!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,36 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class AddBoxActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::Box::Add)
|
||||
end
|
||||
|
||||
context "prepare" do
|
||||
setup do
|
||||
@default_order = [Vagrant::Actions::Box::Download, Vagrant::Actions::Box::Unpackage, Vagrant::Actions::Box::Verify]
|
||||
@runner.stubs(:directory).returns("foo")
|
||||
File.stubs(:exists?).returns(false)
|
||||
end
|
||||
|
||||
def setup_action_expectations
|
||||
default_seq = sequence("default_seq")
|
||||
@default_order.each do |action|
|
||||
@runner.expects(:add_action).with(action).once.in_sequence(default_seq)
|
||||
end
|
||||
end
|
||||
|
||||
should "setup the proper sequence of actions" do
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "result in an action exception if the box already exists" do
|
||||
File.expects(:exists?).once.returns(true)
|
||||
@runner.expects(:name).once.returns('foo')
|
||||
@runner.expects(:add_action).never
|
||||
assert_raise Vagrant::Actions::ActionException do
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class DestroyBoxActionsTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@name = "foo"
|
||||
@dir = "foo"
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::Box::Destroy)
|
||||
@runner.stubs(:directory).returns(@dir)
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
should "rm_rf the directory" do
|
||||
FileUtils.expects(:rm_rf).with(@dir).once
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,137 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class DownloadBoxActionsTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@uri = "foo.com"
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::Box::Download)
|
||||
@runner.stubs(:uri).returns(@uri)
|
||||
@runner.stubs(:temp_path=)
|
||||
|
||||
@runner.env.stubs(:tmp_path).returns("foo")
|
||||
end
|
||||
|
||||
context "preparing" do
|
||||
setup do
|
||||
@downloader = mock("downloader")
|
||||
Vagrant::Downloaders::File.any_instance.stubs(:prepare)
|
||||
Vagrant::Downloaders::HTTP.any_instance.stubs(:prepare)
|
||||
end
|
||||
|
||||
should "raise an exception if no URI type is matched" do\
|
||||
Vagrant::Downloaders::File.expects(:match?).returns(false)
|
||||
Vagrant::Downloaders::HTTP.expects(:match?).returns(false)
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.prepare
|
||||
}
|
||||
end
|
||||
|
||||
should "call #prepare on the downloader" do
|
||||
@downloader.expects(:prepare).with(@runner.uri).once
|
||||
Vagrant::Downloaders::File.expects(:new).returns(@downloader)
|
||||
expect_file
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "set the downloader to file if the uri provided is a file" do
|
||||
expect_file
|
||||
@action.prepare
|
||||
assert @action.downloader.is_a?(Vagrant::Downloaders::File)
|
||||
end
|
||||
|
||||
should "set the downloader to HTTP if the uri provided is a valid url" do
|
||||
expect_http
|
||||
@action.prepare
|
||||
assert @action.downloader.is_a?(Vagrant::Downloaders::HTTP)
|
||||
end
|
||||
|
||||
def expect_file
|
||||
Vagrant::Downloaders::File.expects(:match?).returns(true)
|
||||
Vagrant::Downloaders::HTTP.expects(:match?).returns(false)
|
||||
end
|
||||
|
||||
def expect_http
|
||||
Vagrant::Downloaders::File.expects(:match?).returns(false)
|
||||
Vagrant::Downloaders::HTTP.expects(:match?).returns(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@path = "foo"
|
||||
|
||||
@tempfile = mock("tempfile")
|
||||
@tempfile.stubs(:path).returns(@path)
|
||||
|
||||
@action.stubs(:with_tempfile).yields(@tempfile)
|
||||
@action.stubs(:download_to)
|
||||
end
|
||||
|
||||
should "make a tempfile and copy the URI contents to it" do
|
||||
@action.expects(:with_tempfile).yields(@tempfile)
|
||||
@action.expects(:download_to).with(@tempfile)
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "save the tempfile path" do
|
||||
@runner.expects(:temp_path=).with(@path).once
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "rescue" do
|
||||
should "call cleanup method" do
|
||||
@action.expects(:cleanup).once
|
||||
@action.rescue(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "tempfile" do
|
||||
should "create a tempfile in the vagrant tmp directory" do
|
||||
File.expects(:open).with { |name, bitmask|
|
||||
name =~ /#{Vagrant::Actions::Box::Download::BASENAME}/ && name =~ /#{@runner.env.tmp_path}/
|
||||
}.once
|
||||
@action.with_tempfile
|
||||
end
|
||||
|
||||
should "yield the tempfile object" do
|
||||
@tempfile = mock("tempfile")
|
||||
File.expects(:open).yields(@tempfile)
|
||||
|
||||
@action.with_tempfile do |otherfile|
|
||||
assert @tempfile.equal?(otherfile)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "cleaning up" do
|
||||
setup do
|
||||
@temp_path = "foo"
|
||||
@runner.stubs(:temp_path).returns(@temp_path)
|
||||
File.stubs(:exist?).returns(true)
|
||||
end
|
||||
|
||||
should "delete the temporary file if it exists" do
|
||||
File.expects(:unlink).with(@temp_path).once
|
||||
@action.cleanup
|
||||
end
|
||||
|
||||
should "not delete anything if it doesn't exist" do
|
||||
File.stubs(:exist?).returns(false)
|
||||
File.expects(:unlink).never
|
||||
@action.cleanup
|
||||
end
|
||||
end
|
||||
|
||||
context "downloading" do
|
||||
setup do
|
||||
@downloader = mock("downloader")
|
||||
@action.stubs(:downloader).returns(@downloader)
|
||||
end
|
||||
|
||||
should "call download! on the download with the URI and tempfile" do
|
||||
tempfile = "foo"
|
||||
@downloader.expects(:download!).with(@runner.uri, tempfile)
|
||||
@action.download_to(tempfile)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,99 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class UnpackageBoxActionsTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::Box::Unpackage)
|
||||
@runner.stubs(:name).returns("foo")
|
||||
@runner.stubs(:temp_path).returns("bar")
|
||||
|
||||
@runner.env.stubs(:boxes_path).returns("bar")
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@runner.stubs(:invoke_around_callback).yields
|
||||
end
|
||||
|
||||
should "execute the proper actions in the proper order" do
|
||||
exec_seq = sequence("exec_seq")
|
||||
@action.expects(:setup_box_dir).in_sequence(exec_seq)
|
||||
@action.expects(:decompress).in_sequence(exec_seq)
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "execute it in a around block" do
|
||||
@runner.expects(:invoke_around_callback).with(:unpackage).once
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "rescuing" do
|
||||
setup do
|
||||
File.stubs(:directory?).returns(false)
|
||||
FileUtils.stubs(:rm_rf)
|
||||
|
||||
@box_dir = mock("foo")
|
||||
@action.stubs(:box_dir).returns(@box_dir)
|
||||
end
|
||||
|
||||
should "do nothing if a directory doesn't exist" do
|
||||
FileUtils.expects(:rm_rf).never
|
||||
@action.rescue(nil)
|
||||
end
|
||||
|
||||
should "remove the box directory if it exists" do
|
||||
File.expects(:directory?).returns(true)
|
||||
FileUtils.expects(:rm_rf).with(@box_dir).once
|
||||
@action.rescue(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context "box directory" do
|
||||
should "return the runner directory" do
|
||||
result = mock("object")
|
||||
@runner.expects(:directory).once.returns(result)
|
||||
assert result.equal?(@action.box_dir)
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up the box directory" do
|
||||
setup do
|
||||
File.stubs(:directory?).returns(false)
|
||||
FileUtils.stubs(:mkdir_p)
|
||||
|
||||
@box_dir = "foo"
|
||||
@action.stubs(:box_dir).returns(@box_dir)
|
||||
end
|
||||
|
||||
should "error and exit if the directory exists" do
|
||||
File.expects(:directory?).returns(true)
|
||||
@action.expects(:error_and_exit).with(:box_already_exists, :box_name => @runner.name).once
|
||||
@action.setup_box_dir
|
||||
end
|
||||
|
||||
should "create the directory" do
|
||||
FileUtils.expects(:mkdir_p).with(@box_dir).once
|
||||
@action.setup_box_dir
|
||||
end
|
||||
end
|
||||
|
||||
context "decompressing" do
|
||||
setup do
|
||||
@box_dir = "foo"
|
||||
|
||||
@action.stubs(:box_dir).returns(@box_dir)
|
||||
Dir.stubs(:chdir).yields
|
||||
Archive::Tar::Minitar.stubs(:unpack)
|
||||
end
|
||||
|
||||
should "change to the box directory" do
|
||||
Dir.expects(:chdir).with(@box_dir)
|
||||
@action.decompress
|
||||
end
|
||||
|
||||
should "open the tar file within the new directory, and extract it all" do
|
||||
Archive::Tar::Minitar.expects(:unpack).with(@runner.temp_path, @box_dir).once
|
||||
@action.decompress
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,44 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class VerifyBoxActionsTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::Box::Verify)
|
||||
@runner.stubs(:name).returns("foo")
|
||||
@runner.stubs(:temp_path).returns("bar")
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
should "execute the proper actions in the proper order" do
|
||||
exec_seq = sequence("exec_seq")
|
||||
@action.expects(:reload_configuration).in_sequence(exec_seq)
|
||||
@action.expects(:verify_appliance).in_sequence(exec_seq)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "reloading configuration" do
|
||||
should "set the new box, load box, then load config" do
|
||||
reload_seq = sequence("reload_seq")
|
||||
@runner.env.config.vm.expects(:box=).with(@runner.name).in_sequence(reload_seq)
|
||||
@runner.env.expects(:load_box!).in_sequence(reload_seq)
|
||||
@runner.env.expects(:load_config!).in_sequence(reload_seq)
|
||||
@action.reload_configuration
|
||||
end
|
||||
end
|
||||
|
||||
context "verifying appliance" do
|
||||
setup do
|
||||
@runner.stubs(:ovf_file).returns("foo")
|
||||
end
|
||||
|
||||
should "create new appliance and return true if succeeds" do
|
||||
VirtualBox::Appliance.expects(:new).with(@runner.ovf_file)
|
||||
assert_nothing_raised { @action.verify_appliance }
|
||||
end
|
||||
|
||||
should "return false if an exception is raised" do
|
||||
VirtualBox::Appliance.expects(:new).with(@runner.ovf_file).raises(VirtualBox::Exceptions::FileErrorException)
|
||||
assert_raises(Vagrant::Actions::ActionException) { @action.verify_appliance }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,113 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
||||
|
||||
class CollectionTest < Test::Unit::TestCase
|
||||
class MockAction; end
|
||||
class MockActionOther; end
|
||||
|
||||
context "checking uniqueness" do
|
||||
setup do
|
||||
@actions = Vagrant::Actions::Collection.new([1])
|
||||
end
|
||||
|
||||
should "return true if there are duplicate classes in the collection" do
|
||||
@actions << 1
|
||||
assert @actions.duplicates?
|
||||
end
|
||||
|
||||
should "return false it all the classes are unique" do
|
||||
@actions << 1.0 << "foo"
|
||||
assert !@actions.duplicates?
|
||||
end
|
||||
|
||||
should "raise an exception when there are duplicates" do
|
||||
@actions << 1
|
||||
assert_raise Vagrant::Actions::DuplicateActionException do
|
||||
@actions.duplicates!
|
||||
end
|
||||
end
|
||||
|
||||
should "not raise an exception when there are no duplicates" do
|
||||
@actions << 1.0 << "foo"
|
||||
assert_nothing_raised do
|
||||
@actions.duplicates!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "verifying dependencies" do
|
||||
setup do
|
||||
@mock_action = mock('action')
|
||||
@mock_action.stubs(:class).returns(MockAction)
|
||||
|
||||
@mock_action2 = mock('action2')
|
||||
@mock_action2.stubs(:class).returns(MockActionOther)
|
||||
# see test_helper
|
||||
stub_default_action_dependecies(@mock_action)
|
||||
stub_default_action_dependecies(@mock_action2)
|
||||
end
|
||||
|
||||
context "that come before an action" do
|
||||
setup do
|
||||
@mock_action.stubs(:follows).returns([MockActionOther])
|
||||
end
|
||||
should "raise an exception if they are not met" do
|
||||
assert_raise Vagrant::Actions::DependencyNotSatisfiedException do
|
||||
collection.new([@mock_action]).dependencies!
|
||||
end
|
||||
end
|
||||
|
||||
should "not raise an exception if they are met" do
|
||||
assert_nothing_raised do
|
||||
collection.new([@mock_action2, @mock_action]).dependencies!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "that follow an an action" do
|
||||
setup do
|
||||
@mock_action.stubs(:precedes).returns([MockActionOther])
|
||||
end
|
||||
|
||||
should "raise an exception if they are not met" do
|
||||
assert_raise Vagrant::Actions::DependencyNotSatisfiedException do
|
||||
collection.new([@mock_action]).dependencies!
|
||||
end
|
||||
end
|
||||
|
||||
should "not raise an exception if they are met" do
|
||||
assert_nothing_raised do
|
||||
collection.new([@mock_action, @mock_action2]).dependencies!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "that are before and after an action" do
|
||||
setup do
|
||||
@mock_action.stubs(:precedes).returns([MockActionOther])
|
||||
@mock_action.stubs(:follows).returns([MockActionOther])
|
||||
end
|
||||
|
||||
should "raise an exception if they are met" do
|
||||
assert_raise Vagrant::Actions::DependencyNotSatisfiedException do
|
||||
collection.new([@mock_action2, @mock_action]).dependencies!
|
||||
end
|
||||
end
|
||||
|
||||
should "not raise and exception if they are met" do
|
||||
assert_nothing_raised do
|
||||
collection.new([@mock_action2, @mock_action, @mock_action2]).dependencies!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "klasses" do
|
||||
should "return a list of the collection element's classes" do
|
||||
@action = mock('action')
|
||||
assert_equal collection.new([@action]).klasses, [@action.class]
|
||||
assert_equal collection.new([@action, 1.0, "foo"]).klasses, [@action.class, Float, String]
|
||||
end
|
||||
end
|
||||
|
||||
def collection; Vagrant::Actions::Collection end
|
||||
end
|
|
@ -1,268 +0,0 @@
|
|||
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
|
|
@ -1,49 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class BootActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Boot)
|
||||
@runner.stubs(:invoke_callback)
|
||||
end
|
||||
|
||||
context "execution" do
|
||||
should "invoke the 'boot' around callback" do
|
||||
boot_seq = sequence("boot_seq")
|
||||
@runner.expects(:invoke_around_callback).with(:boot).once.in_sequence(boot_seq).yields
|
||||
@action.expects(:boot).in_sequence(boot_seq)
|
||||
@action.expects(:wait_for_boot).returns(true).in_sequence(boot_seq)
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "error and exit if the bootup failed" do
|
||||
fail_boot_seq = sequence("fail_boot_seq")
|
||||
@action.expects(:boot).once.in_sequence(fail_boot_seq)
|
||||
@action.expects(:wait_for_boot).returns(false).in_sequence(fail_boot_seq)
|
||||
@action.expects(:error_and_exit).with(:vm_failed_to_boot).once.in_sequence(fail_boot_seq)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "booting" do
|
||||
should "start the VM in specified mode" do
|
||||
mode = mock("boot_mode")
|
||||
@runner.env.config.vm.boot_mode = mode
|
||||
@vm.expects(:start).with(mode).once
|
||||
@action.boot
|
||||
end
|
||||
end
|
||||
|
||||
context "waiting for boot" do
|
||||
should "repeatedly ping the SSH port and return false with no response" do
|
||||
seq = sequence('pings')
|
||||
@runner.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i - 1).returns(false).in_sequence(seq)
|
||||
@runner.ssh.expects(:up?).once.returns(true).in_sequence(seq)
|
||||
assert @action.wait_for_boot(0)
|
||||
end
|
||||
|
||||
should "ping the max number of times then just return" do
|
||||
@runner.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i).returns(false)
|
||||
assert !@action.wait_for_boot(0)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class CustomizeActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Customize)
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
should "run the VM customization procs then save the VM" do
|
||||
@runner.env.config.vm.customize { |vm| }
|
||||
@runner.env.config.vm.expects(:run_procs!).with(@vm)
|
||||
@vm.expects(:save).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "not run anything if no customize blocks exist" do
|
||||
@vm.expects(:save).never
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class DestroyActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Destroy)
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
should "invoke an around callback around the destroy" do
|
||||
@runner.expects(:invoke_around_callback).with(:destroy).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "destroy VM and clear persist" do
|
||||
@runner.stubs(:invoke_around_callback).yields
|
||||
clear_seq = sequence("clear")
|
||||
@action.expects(:destroy_vm).in_sequence(clear_seq)
|
||||
@action.expects(:update_dotfile).in_sequence(clear_seq)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "destroying the VM" do
|
||||
should "destroy VM and attached images" do
|
||||
@vm.expects(:destroy).with(:destroy_medium => :delete).once
|
||||
@runner.expects(:vm=).with(nil).once
|
||||
@action.destroy_vm
|
||||
end
|
||||
end
|
||||
|
||||
context "updating the dotfile" do
|
||||
should "update the environment dotfile" do
|
||||
@runner.env.expects(:update_dotfile).once
|
||||
@action.update_dotfile
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,39 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class DownActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Down)
|
||||
end
|
||||
|
||||
context "preparing" do
|
||||
setup do
|
||||
@vm.stubs(:running?).returns(false)
|
||||
end
|
||||
|
||||
def setup_action_expectations(order)
|
||||
default_seq = sequence("default_seq")
|
||||
order.each do |action|
|
||||
action = [action] unless action.is_a?(Array)
|
||||
@runner.expects(:add_action).with(action.shift, *action).once.in_sequence(default_seq)
|
||||
end
|
||||
end
|
||||
|
||||
should "add the destroy action alone if VM is not running" do
|
||||
setup_action_expectations([Vagrant::Actions::VM::Network, Vagrant::Actions::VM::Destroy])
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "add the halt action if the VM is running" do
|
||||
@vm.expects(:running?).returns(true)
|
||||
setup_action_expectations([[Vagrant::Actions::VM::Halt, {:force => true}], Vagrant::Actions::VM::Network, Vagrant::Actions::VM::Destroy])
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
|
||||
context "after halting" do
|
||||
should "sleep" do
|
||||
Kernel.expects(:sleep).once
|
||||
@action.after_halt
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,88 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ExportActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Export)
|
||||
@action.stubs(:complete_progress)
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
should "setup the temp dir then export" do
|
||||
exec_seq = sequence('execute')
|
||||
@action.expects(:setup_temp_dir).once.in_sequence(exec_seq)
|
||||
@action.expects(:export).once.in_sequence(exec_seq)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up the temporary directory" do
|
||||
setup do
|
||||
@time_now = Time.now.to_i.to_s
|
||||
Time.stubs(:now).returns(@time_now)
|
||||
|
||||
@tmp_path = "foo"
|
||||
@runner.env.stubs(:tmp_path).returns(@tmp_path)
|
||||
|
||||
@temp_dir = File.join(@runner.env.tmp_path, @time_now)
|
||||
FileUtils.stubs(:mkpath)
|
||||
end
|
||||
|
||||
should "create the temporary directory using the current time" do
|
||||
FileUtils.expects(:mkpath).with(@temp_dir).once
|
||||
@action.setup_temp_dir
|
||||
end
|
||||
|
||||
should "set the temporary directory to the temp_dir variable" do
|
||||
@action.setup_temp_dir
|
||||
assert_equal @temp_dir, @action.temp_dir
|
||||
end
|
||||
end
|
||||
|
||||
context "path to OVF file" do
|
||||
setup do
|
||||
@temp_dir = "foo"
|
||||
@action.stubs(:temp_dir).returns(@temp_dir)
|
||||
end
|
||||
|
||||
should "be the temporary directory joined with the OVF filename" do
|
||||
assert_equal File.join(@temp_dir, @runner.env.config.vm.box_ovf), @action.ovf_path
|
||||
end
|
||||
end
|
||||
|
||||
context "exporting" do
|
||||
setup do
|
||||
@ovf_path = mock("ovf_path")
|
||||
@action.stubs(:ovf_path).returns(@ovf_path)
|
||||
end
|
||||
|
||||
should "call export on the runner with the ovf path" do
|
||||
@vm.expects(:export).with(@ovf_path).once
|
||||
@action.export
|
||||
end
|
||||
end
|
||||
|
||||
context "cleanup" do
|
||||
setup do
|
||||
@temp_dir = "foo"
|
||||
@action.stubs(:temp_dir).returns(@temp_dir)
|
||||
end
|
||||
|
||||
should "remove the temporary directory" do
|
||||
FileUtils.expects(:rm_r).with(@temp_dir).once
|
||||
@action.cleanup
|
||||
end
|
||||
|
||||
should "not remove a directory if temp_dir is nil" do
|
||||
FileUtils.expects(:rm_r).never
|
||||
@action.stubs(:temp_dir).returns(nil)
|
||||
@action.cleanup
|
||||
end
|
||||
end
|
||||
|
||||
context "rescue" do
|
||||
should "call cleanup method" do
|
||||
@action.expects(:cleanup).once
|
||||
@action.rescue(nil)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,253 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ForwardPortsActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::ForwardPorts)
|
||||
end
|
||||
|
||||
context "preparing" do
|
||||
should "call proper sequence" do
|
||||
prep_seq = sequence("prepare")
|
||||
@action.expects(:external_collision_check).in_sequence(prep_seq)
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
|
||||
context "checking for colliding external ports" do
|
||||
setup do
|
||||
@env = mock_environment do |config|
|
||||
config.vm.forwarded_ports.clear
|
||||
config.vm.forward_port("ssh", 22, 2222)
|
||||
end
|
||||
|
||||
@runner.stubs(:env).returns(@env)
|
||||
|
||||
@used_ports = []
|
||||
@action.stubs(:used_ports).returns(@used_ports)
|
||||
|
||||
# So no exceptions are raised
|
||||
@action.stubs(:handle_collision)
|
||||
end
|
||||
|
||||
should "not raise any errors if no forwarded ports collide" do
|
||||
@used_ports << "80"
|
||||
assert_nothing_raised { @action.external_collision_check }
|
||||
end
|
||||
|
||||
should "handle the collision if it happens" do
|
||||
@used_ports << "2222"
|
||||
@action.expects(:handle_collision).with("ssh", anything, anything).once
|
||||
@action.external_collision_check
|
||||
end
|
||||
end
|
||||
|
||||
context "handling collisions" do
|
||||
setup do
|
||||
@name = :foo
|
||||
@options = {
|
||||
:hostport => 0,
|
||||
:auto => true
|
||||
}
|
||||
@used_ports = [1,2,3]
|
||||
|
||||
@runner.env.config.vm.auto_port_range = (1..5)
|
||||
end
|
||||
|
||||
should "raise an exception if auto forwarding is disabled" do
|
||||
@options[:auto] = false
|
||||
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.handle_collision(@name, @options, @used_ports)
|
||||
}
|
||||
end
|
||||
|
||||
should "set the host port to the first available port" do
|
||||
assert_equal 0, @options[:hostport]
|
||||
@action.handle_collision(@name, @options, @used_ports)
|
||||
assert_equal 4, @options[:hostport]
|
||||
end
|
||||
|
||||
should "add the newly used port to the list of used ports" do
|
||||
assert !@used_ports.include?(4)
|
||||
@action.handle_collision(@name, @options, @used_ports)
|
||||
assert @used_ports.include?(4)
|
||||
end
|
||||
|
||||
should "not use a host port which is being forwarded later" do
|
||||
@runner.env.config.vm.forward_port("http", 80, 4)
|
||||
|
||||
assert_equal 0, @options[:hostport]
|
||||
@action.handle_collision(@name, @options, @used_ports)
|
||||
assert_equal 5, @options[:hostport]
|
||||
end
|
||||
|
||||
should "raise an exception if there are no auto ports available" do
|
||||
@runner.env.config.vm.auto_port_range = (1..3)
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.handle_collision(@name, @options, @used_ports)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context "execution" do
|
||||
should "clear all previous ports and forward new ports" do
|
||||
exec_seq = sequence("exec_seq")
|
||||
@action.expects(:clear).once.in_sequence(exec_seq)
|
||||
@action.expects(:forward_ports).once.in_sequence(exec_seq)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "forwarding ports" do
|
||||
should "create a port forwarding for the VM" do
|
||||
forwarded_ports = mock("forwarded_ports")
|
||||
network_adapter = mock("network_adapter")
|
||||
|
||||
@vm.stubs(:network_adapters).returns([network_adapter])
|
||||
network_adapter.expects(:attachment_type).returns(:nat)
|
||||
|
||||
@action.expects(:forward_port).once
|
||||
@vm.expects(:save).once
|
||||
@runner.expects(:reload!).once
|
||||
@action.forward_ports
|
||||
end
|
||||
|
||||
should "No port forwarding for non NAT interfaces" do
|
||||
forwarded_ports = mock("forwarded_ports")
|
||||
network_adapter = mock("network_adapter")
|
||||
|
||||
@vm.expects(:network_adapters).returns([network_adapter])
|
||||
network_adapter.expects(:attachment_type).returns(:host_only)
|
||||
@vm.expects(:save).once
|
||||
@runner.expects(:reload!).once
|
||||
@action.forward_ports
|
||||
end
|
||||
end
|
||||
|
||||
context "clearing forwarded ports" do
|
||||
setup do
|
||||
@action.stubs(:used_ports).returns([:a])
|
||||
@action.stubs(:clear_ports)
|
||||
end
|
||||
|
||||
should "call destroy on all forwarded ports" do
|
||||
@action.expects(:clear_ports).once
|
||||
@runner.expects(:reload!)
|
||||
@action.clear
|
||||
end
|
||||
|
||||
should "do nothing if there are no forwarded ports" do
|
||||
@action.stubs(:used_ports).returns([])
|
||||
@runner.expects(:reload!).never
|
||||
@action.clear
|
||||
end
|
||||
end
|
||||
|
||||
context "getting list of used ports" do
|
||||
setup do
|
||||
@vms = []
|
||||
VirtualBox::VM.stubs(:all).returns(@vms)
|
||||
VirtualBox.stubs(:version).returns("3.1.0")
|
||||
@runner.stubs(:uuid).returns(:bar)
|
||||
end
|
||||
|
||||
def mock_vm(options={})
|
||||
options = {
|
||||
:running? => true,
|
||||
:uuid => :foo
|
||||
}.merge(options)
|
||||
|
||||
vm = mock("vm")
|
||||
options.each do |k,v|
|
||||
vm.stubs(k).returns(v)
|
||||
end
|
||||
|
||||
vm
|
||||
end
|
||||
|
||||
def mock_fp(hostport)
|
||||
fp = mock("fp")
|
||||
fp.stubs(:hostport).returns(hostport.to_s)
|
||||
fp
|
||||
end
|
||||
|
||||
should "ignore VMs which aren't running" do
|
||||
@vms << mock_vm(:running? => false)
|
||||
@vms[0].expects(:forwarded_ports).never
|
||||
@action.used_ports
|
||||
end
|
||||
|
||||
should "ignore VMs of the same uuid" do
|
||||
@vms << mock_vm(:uuid => @runner.uuid)
|
||||
@vms[0].expects(:forwarded_ports).never
|
||||
@action.used_ports
|
||||
end
|
||||
|
||||
should "return the forwarded ports for VB 3.2.x" do
|
||||
VirtualBox.stubs(:version).returns("3.2.4")
|
||||
fps = [mock_fp(2222), mock_fp(80)]
|
||||
na = mock("na")
|
||||
ne = mock("ne")
|
||||
na.stubs(:nat_driver).returns(ne)
|
||||
ne.stubs(:forwarded_ports).returns(fps)
|
||||
@vms << mock_vm(:network_adapters => [na])
|
||||
assert_equal %W[2222 80], @action.used_ports
|
||||
end
|
||||
end
|
||||
|
||||
context "clearing ports" do
|
||||
def mock_fp
|
||||
fp = mock("fp")
|
||||
fp.expects(:destroy).once
|
||||
fp
|
||||
end
|
||||
|
||||
setup do
|
||||
VirtualBox.stubs(:version).returns("3.2.8")
|
||||
@adapters = []
|
||||
@vm.stubs(:network_adapters).returns(@adapters)
|
||||
end
|
||||
|
||||
def mock_adapter
|
||||
na = mock("adapter")
|
||||
engine = mock("engine")
|
||||
engine.stubs(:forwarded_ports).returns([mock_fp])
|
||||
na.stubs(:nat_driver).returns(engine)
|
||||
na
|
||||
end
|
||||
|
||||
should "destroy each forwarded port" do
|
||||
@adapters << mock_adapter
|
||||
@adapters << mock_adapter
|
||||
@action.clear_ports
|
||||
end
|
||||
end
|
||||
|
||||
context "forwarding ports implementation" do
|
||||
setup do
|
||||
VirtualBox.stubs(:version).returns("3.2.8")
|
||||
end
|
||||
|
||||
should "forward ports" do
|
||||
name, opts = @runner.env.config.vm.forwarded_ports.first
|
||||
|
||||
adapters = []
|
||||
adapter = mock("adapter")
|
||||
engine = mock("engine")
|
||||
fps = mock("forwarded ports")
|
||||
adapter.stubs(:nat_driver).returns(engine)
|
||||
engine.stubs(:forwarded_ports).returns(fps)
|
||||
fps.expects(:<<).with do |port|
|
||||
assert_equal name, port.name
|
||||
assert_equal opts[:hostport], port.hostport
|
||||
assert_equal opts[:guestport], port.guestport
|
||||
true
|
||||
end
|
||||
|
||||
adapters[opts[:adapter]] = adapter
|
||||
@vm.stubs(:network_adapters).returns(adapters)
|
||||
|
||||
@action.forward_port(name, opts)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,65 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class HaltActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Halt)
|
||||
@runner.stubs(:system).returns(linux_system(@vm))
|
||||
end
|
||||
|
||||
context "force?" do
|
||||
should "not force by default" do
|
||||
@action.options[:force] = nil
|
||||
assert !@action.force?
|
||||
end
|
||||
|
||||
should "force if specified" do
|
||||
@action.options[:force] = true
|
||||
assert @action.force?
|
||||
end
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@vm.stubs(:running?).returns(true)
|
||||
|
||||
@runner.system.stubs(:halt)
|
||||
@vm.stubs(:stop)
|
||||
@vm.stubs(:state).returns(:powered_off)
|
||||
end
|
||||
|
||||
should "invoke the 'halt' around callback" do
|
||||
@runner.expects(:invoke_around_callback).with(:halt).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "halt with the system and NOT force VM to stop if powered off" do
|
||||
@vm.expects(:state).with(true).returns(:powered_off)
|
||||
|
||||
@runner.system.expects(:halt).once
|
||||
@vm.expects(:stop).never
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "halt with the system and force VM to stop if NOT powered off" do
|
||||
@vm.expects(:state).with(true).returns(:running)
|
||||
|
||||
@runner.system.expects(:halt).once
|
||||
@vm.expects(:stop).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "not call halt on the system if forcing" do
|
||||
@action.stubs(:force).returns(true)
|
||||
@runner.system.expects(:halt).never
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "raise an ActionException if VM is not running" do
|
||||
@vm.stubs(:running?).returns(false)
|
||||
@vm.expects(:stop).never
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.execute!
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,45 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ImportActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @import = mock_action(Vagrant::Actions::VM::Import)
|
||||
|
||||
@ovf_file = "foo"
|
||||
@box = mock("box")
|
||||
@box.stubs(:ovf_file).returns(@ovf_file)
|
||||
@runner.env.stubs(:box).returns(@box)
|
||||
|
||||
VirtualBox::VM.stubs(:import)
|
||||
|
||||
@import.stubs(:complete_progress)
|
||||
end
|
||||
|
||||
should "run in a busy block" do
|
||||
Vagrant::Busy.expects(:busy).once
|
||||
@import.execute!
|
||||
end
|
||||
|
||||
should "invoke an around callback around the import" do
|
||||
@runner.expects(:invoke_around_callback).with(:import).once
|
||||
@import.execute!
|
||||
end
|
||||
|
||||
should "call import on VirtualBox::VM with the proper base" do
|
||||
VirtualBox::VM.expects(:import).once.with(@ovf_file).returns("foo")
|
||||
assert_nothing_raised { @import.execute! }
|
||||
end
|
||||
|
||||
should "raise an exception if import is nil" do
|
||||
@runner.expects(:vm).returns(nil)
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@import.execute!
|
||||
}
|
||||
end
|
||||
|
||||
should "set the resulting VM as the VM of the Vagrant VM object" do
|
||||
new_vm = mock("new_vm")
|
||||
@runner.expects(:vm=).with(new_vm).once
|
||||
VirtualBox::VM.expects(:import).returns(new_vm).returns("foo")
|
||||
@import.execute!
|
||||
end
|
||||
end
|
|
@ -1,106 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class MoveHardDriveActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::MoveHardDrive)
|
||||
@hd_location = "/foo"
|
||||
|
||||
@mock_vm.env.config.vm.stubs(:hd_location).returns(@hd_location)
|
||||
end
|
||||
|
||||
|
||||
should "be able to identifiy a hard drive within the storage controllers" do
|
||||
hd = mock('hd')
|
||||
hd_image = mock('hd_image')
|
||||
hd_image.expects(:is_a?).returns(true)
|
||||
hd.expects(:image).returns(hd_image)
|
||||
|
||||
dvd = mock('dvd')
|
||||
controller = mock('controller')
|
||||
controller.expects(:devices).returns([hd, dvd])
|
||||
|
||||
@vm.expects(:storage_controllers).once.returns([controller])
|
||||
assert_equal @action.find_hard_drive, hd
|
||||
end
|
||||
|
||||
context "execution" do
|
||||
should "error and exit if the vm is not powered off" do
|
||||
@mock_vm.expects(:powered_off?).returns(false)
|
||||
@action.expects(:error_and_exit).with(:vm_power_off_to_move_hd).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "move the hard drive if vm is powered off" do
|
||||
@mock_vm.expects(:powered_off?).returns(true)
|
||||
@action.expects(:error_and_exit).never
|
||||
@action.expects(:destroy_drive_after).once
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "new image path" do
|
||||
setup do
|
||||
@hd = mock("hd")
|
||||
@image = mock("image")
|
||||
@filename = "foo"
|
||||
@hd.stubs(:image).returns(@image)
|
||||
@image.stubs(:filename).returns(@filename)
|
||||
@action.stubs(:hard_drive).returns(@hd)
|
||||
end
|
||||
|
||||
should "be the configured hd location and the existing hard drive filename" do
|
||||
joined = File.join(@mock_vm.env.config.vm.hd_location, @filename)
|
||||
assert_equal joined, @action.new_image_path
|
||||
end
|
||||
end
|
||||
|
||||
context "cloning and attaching new image" do
|
||||
setup do
|
||||
@hd = mock("hd")
|
||||
@image = mock("image")
|
||||
@hd.stubs(:image).returns(@image)
|
||||
@action.stubs(:hard_drive).returns(@hd)
|
||||
@new_image_path = "foo"
|
||||
@action.stubs(:new_image_path).returns(@new_image_path)
|
||||
end
|
||||
|
||||
should "clone to the new path" do
|
||||
new_image = mock("new_image")
|
||||
@image.expects(:clone).with(@new_image_path, Vagrant.config.vm.disk_image_format, true).returns(new_image).once
|
||||
@hd.expects(:image=).with(new_image).once
|
||||
@vm.expects(:save).once
|
||||
@action.clone_and_attach
|
||||
end
|
||||
end
|
||||
|
||||
context "destroying the old image" do
|
||||
setup do
|
||||
@hd = mock("hd")
|
||||
@action.stubs(:hard_drive).returns(@hd)
|
||||
end
|
||||
|
||||
should "yield the block, and destroy the old image after" do
|
||||
image = mock("image")
|
||||
image.stubs(:filename).returns("foo")
|
||||
destroy_seq = sequence("destroy_seq")
|
||||
@hd.expects(:image).returns(image).in_sequence(destroy_seq)
|
||||
@hd.expects(:foo).once.in_sequence(destroy_seq)
|
||||
image.expects(:destroy).with(true).once.in_sequence(destroy_seq)
|
||||
|
||||
@action.destroy_drive_after { @hd.foo }
|
||||
end
|
||||
|
||||
# Ensures that the image is not destroyed in an "ensure" block
|
||||
should "not destroy the image if an exception is raised" do
|
||||
image = mock("image")
|
||||
image.expects(:destroy).never
|
||||
@hd.expects(:image).returns(image)
|
||||
|
||||
assert_raises(Exception) do
|
||||
@action.destroy_drive_after do
|
||||
raise Exception.new("FOO")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,291 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class NetworkTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Network)
|
||||
@runner.stubs(:system).returns(linux_system(@vm))
|
||||
|
||||
@interfaces = []
|
||||
VirtualBox::Global.global.host.stubs(:network_interfaces).returns(@interfaces)
|
||||
end
|
||||
|
||||
def mock_interface(options=nil)
|
||||
options = {
|
||||
:interface_type => :host_only,
|
||||
:name => "foo"
|
||||
}.merge(options || {})
|
||||
|
||||
interface = mock("interface")
|
||||
options.each do |k,v|
|
||||
interface.stubs(k).returns(v)
|
||||
end
|
||||
|
||||
@interfaces << interface
|
||||
interface
|
||||
end
|
||||
|
||||
context "preparing" do
|
||||
should "verify no bridge collisions for each network enabled" do
|
||||
@runner.env.config.vm.network("foo")
|
||||
@action.expects(:verify_no_bridge_collision).once.with() do |options|
|
||||
assert_equal "foo", options[:ip]
|
||||
true
|
||||
end
|
||||
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
|
||||
context "before destroy" do
|
||||
setup do
|
||||
@network_adapters = []
|
||||
@vm.stubs(:network_adapters).returns(@network_adapters)
|
||||
end
|
||||
|
||||
def stub_interface(length=5)
|
||||
interface = mock("interface")
|
||||
adapter = mock("adapter")
|
||||
adapter.stubs(:host_interface_object).returns(interface)
|
||||
interface.stubs(:attached_vms).returns(Array.new(length))
|
||||
|
||||
@network_adapters << adapter
|
||||
interface
|
||||
end
|
||||
|
||||
should "destroy only the unused network interfaces" do
|
||||
stub_interface(5)
|
||||
stub_interface(7)
|
||||
results = [stub_interface(1), stub_interface(1)]
|
||||
|
||||
results.each do |result|
|
||||
result.expects(:destroy).once
|
||||
end
|
||||
|
||||
@action.before_destroy
|
||||
end
|
||||
end
|
||||
|
||||
context "before boot" do
|
||||
setup do
|
||||
@action.stubs(:enable_network?).returns(false)
|
||||
end
|
||||
|
||||
should "do nothing if network should not be enabled" do
|
||||
@action.expects(:assign_network).never
|
||||
@action.before_boot
|
||||
end
|
||||
|
||||
should "assign the network if host only networking is enabled" do
|
||||
@action.stubs(:enable_network?).returns(true)
|
||||
@action.expects(:assign_network).once
|
||||
@action.before_boot
|
||||
end
|
||||
end
|
||||
|
||||
context "after boot" do
|
||||
setup do
|
||||
@runner.env.config.vm.network("foo")
|
||||
@action.stubs(:enable_network?).returns(true)
|
||||
end
|
||||
|
||||
should "prepare the host only network, then enable them" do
|
||||
run_seq = sequence("run")
|
||||
@runner.system.expects(:prepare_host_only_network).once.in_sequence(run_seq)
|
||||
@runner.system.expects(:enable_host_only_network).once.in_sequence(run_seq)
|
||||
@action.after_boot
|
||||
end
|
||||
|
||||
should "do nothing if network is not enabled" do
|
||||
@action.stubs(:enable_network?).returns(false)
|
||||
@runner.system.expects(:prepare_host_only_network).never
|
||||
@action.after_boot
|
||||
end
|
||||
end
|
||||
|
||||
context "checking if network is enabled" do
|
||||
should "return true if the network options are set" do
|
||||
@runner.env.config.vm.network("foo")
|
||||
assert @action.enable_network?
|
||||
end
|
||||
|
||||
should "return false if the network was not set" do
|
||||
assert !@action.enable_network?
|
||||
end
|
||||
end
|
||||
|
||||
context "assigning the network" do
|
||||
setup do
|
||||
@network_name = "foo"
|
||||
@action.stubs(:network_name).returns(@network_name)
|
||||
|
||||
@network_adapters = []
|
||||
@vm.stubs(:network_adapters).returns(@network_adapters)
|
||||
|
||||
@options = {
|
||||
:ip => "foo",
|
||||
:adapter => 7
|
||||
}
|
||||
|
||||
@runner.env.config.vm.network(@options[:ip], @options)
|
||||
end
|
||||
|
||||
should "setup the specified network adapter" do
|
||||
adapter = mock("adapter")
|
||||
@network_adapters[@options[:adapter]] = adapter
|
||||
|
||||
adapter.expects(:enabled=).with(true).once
|
||||
adapter.expects(:attachment_type=).with(:host_only).once
|
||||
adapter.expects(:host_interface=).with(@network_name).once
|
||||
adapter.expects(:save).once
|
||||
|
||||
@action.assign_network
|
||||
end
|
||||
end
|
||||
|
||||
context "verify no bridge collision" do
|
||||
setup do
|
||||
@action.stubs(:matching_network?).returns(false)
|
||||
@options = { :ip => :foo, :netmask => :bar, :name => nil }
|
||||
end
|
||||
|
||||
should "do nothing if everything is okay" do
|
||||
mock_interface
|
||||
|
||||
assert_nothing_raised { @action.verify_no_bridge_collision(@options) }
|
||||
end
|
||||
|
||||
should "raise an exception if a collision is found" do
|
||||
mock_interface(:interface_type => :bridged)
|
||||
@action.stubs(:matching_network?).returns(true)
|
||||
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.verify_no_bridge_collision(@options)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context "network name" do
|
||||
setup do
|
||||
@action.stubs(:matching_network?).returns(false)
|
||||
|
||||
@options = { :ip => :foo, :netmask => :bar, :name => nil }
|
||||
end
|
||||
|
||||
should "return the network which matches" do
|
||||
result = mock("result")
|
||||
interface = mock_interface(:name => result)
|
||||
|
||||
@action.expects(:matching_network?).with(interface, @options).returns(true)
|
||||
assert_equal result, @action.network_name(@options)
|
||||
end
|
||||
|
||||
should "ignore non-host only interfaces" do
|
||||
@options[:name] = "foo"
|
||||
mock_interface(:name => @options[:name],
|
||||
:interface_type => :bridged)
|
||||
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.network_name(@options)
|
||||
}
|
||||
end
|
||||
|
||||
should "return the network which matches the name if given" do
|
||||
@options[:name] = "foo"
|
||||
|
||||
interface = mock_interface(:name => @options[:name])
|
||||
assert_equal @options[:name], @action.network_name(@options)
|
||||
end
|
||||
|
||||
should "error and exit if the given network name is not found" do
|
||||
@options[:name] = "foo"
|
||||
|
||||
@interfaces.expects(:create).never
|
||||
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.network_name(@options)
|
||||
}
|
||||
end
|
||||
|
||||
should "create a network for the IP and netmask" do
|
||||
result = mock("result")
|
||||
network_ip = :foo
|
||||
|
||||
interface = mock_interface(:name => result)
|
||||
interface.expects(:enable_static).with(network_ip, @options[:netmask])
|
||||
@interfaces.expects(:create).returns(interface)
|
||||
@action.expects(:network_ip).with(@options[:ip], @options[:netmask]).once.returns(network_ip)
|
||||
|
||||
assert_equal result, @action.network_name(@options)
|
||||
end
|
||||
end
|
||||
|
||||
context "checking for a matching network" do
|
||||
setup do
|
||||
@interface = mock("interface")
|
||||
@interface.stubs(:network_mask).returns("foo")
|
||||
@interface.stubs(:ip_address).returns("192.168.0.1")
|
||||
|
||||
@options = {
|
||||
:netmask => "foo",
|
||||
:ip => "baz"
|
||||
}
|
||||
end
|
||||
|
||||
should "return false if the netmasks don't match" do
|
||||
@options[:netmask] = "bar"
|
||||
assert @interface.network_mask != @options[:netmask] # sanity
|
||||
assert !@action.matching_network?(@interface, @options)
|
||||
end
|
||||
|
||||
should "return true if the netmasks yield the same IP" do
|
||||
tests = [["255.255.255.0", "192.168.0.1", "192.168.0.45"],
|
||||
["255.255.0.0", "192.168.45.1", "192.168.28.7"]]
|
||||
|
||||
tests.each do |netmask, interface_ip, guest_ip|
|
||||
@options[:netmask] = netmask
|
||||
@options[:ip] = guest_ip
|
||||
@interface.stubs(:network_mask).returns(netmask)
|
||||
@interface.stubs(:ip_address).returns(interface_ip)
|
||||
|
||||
assert @action.matching_network?(@interface, @options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "applying the netmask" do
|
||||
should "return the proper result" do
|
||||
tests = {
|
||||
["192.168.0.1","255.255.255.0"] => [192,168,0,0],
|
||||
["192.168.45.10","255.255.255.0"] => [192,168,45,0]
|
||||
}
|
||||
|
||||
tests.each do |k,v|
|
||||
assert_equal v, @action.apply_netmask(*k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "splitting an IP" do
|
||||
should "return the proper result" do
|
||||
tests = {
|
||||
"192.168.0.1" => [192,168,0,1]
|
||||
}
|
||||
|
||||
tests.each do |k,v|
|
||||
assert_equal v, @action.split_ip(k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "network IP" do
|
||||
should "return the proper result" do
|
||||
tests = {
|
||||
["192.168.0.45", "255.255.255.0"] => "192.168.0.1"
|
||||
}
|
||||
|
||||
tests.each do |args, result|
|
||||
assert_equal result, @action.network_ip(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,254 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class PackageActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Package)
|
||||
end
|
||||
|
||||
context "initialization" do
|
||||
def get_action(output, include_files)
|
||||
runner, vm, action = mock_action(Vagrant::Actions::VM::Package, {
|
||||
:output => output,
|
||||
:include => include_files
|
||||
})
|
||||
return action
|
||||
end
|
||||
|
||||
should "make out_path 'package' by default if nil is given" do
|
||||
action = get_action(nil, [])
|
||||
assert_equal "package", action.out_path
|
||||
end
|
||||
|
||||
should "make include files an empty array by default" do
|
||||
action = get_action("foo", nil)
|
||||
assert action.include_files.is_a?(Array)
|
||||
assert action.include_files.empty?
|
||||
end
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@action.stubs(:compress)
|
||||
end
|
||||
|
||||
should "compress" do
|
||||
package_seq = sequence("package_seq")
|
||||
@action.expects(:compress).in_sequence(package_seq)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "out path" do
|
||||
should "be the specified output file if given" do
|
||||
result = mock("result")
|
||||
@action.options[:output] = result
|
||||
assert_equal result, @action.out_path
|
||||
end
|
||||
|
||||
should "default to 'package'" do
|
||||
@action.options[:output] = nil
|
||||
assert_equal "package", @action.out_path
|
||||
end
|
||||
end
|
||||
|
||||
context "include files" do
|
||||
should "specified array if given" do
|
||||
@action.options[:include] = [1,2,3]
|
||||
assert_equal @action.options[:include], @action.include_files
|
||||
end
|
||||
|
||||
should "be an empty array by default" do
|
||||
@action.options[:include] = nil
|
||||
assert_equal [], @action.include_files
|
||||
end
|
||||
end
|
||||
|
||||
context "tar path" do
|
||||
should "be the temporary directory with the name and extension attached" do
|
||||
pwd = "foo"
|
||||
FileUtils.stubs(:pwd).returns(pwd)
|
||||
assert_equal File.join(pwd, "#{@action.out_path}#{@runner.env.config.package.extension}"), @action.tar_path
|
||||
end
|
||||
end
|
||||
|
||||
context "temp path" do
|
||||
setup do
|
||||
@export = mock("export")
|
||||
@action.expects(:export_action).returns(@export)
|
||||
end
|
||||
|
||||
should "use the export action's temp dir" do
|
||||
path = mock("path")
|
||||
@export.expects(:temp_dir).returns(path)
|
||||
@action.temp_path
|
||||
end
|
||||
end
|
||||
|
||||
context "copying include files" do
|
||||
setup do
|
||||
@include_files = []
|
||||
@action.stubs(:include_files).returns(@include_files)
|
||||
|
||||
@temp_path = "foo"
|
||||
@action.stubs(:temp_path).returns(@temp_path)
|
||||
end
|
||||
|
||||
should "do nothing if no include files are specified" do
|
||||
assert @action.include_files.empty?
|
||||
FileUtils.expects(:mkdir_p).never
|
||||
FileUtils.expects(:cp).never
|
||||
@action.copy_include_files
|
||||
end
|
||||
|
||||
should "create the include directory and copy files to it" do
|
||||
include_dir = File.join(@action.temp_path, "include")
|
||||
copy_seq = sequence("copy_seq")
|
||||
FileUtils.expects(:mkdir_p).with(include_dir).once.in_sequence(copy_seq)
|
||||
|
||||
5.times do |i|
|
||||
file = mock("f#{i}")
|
||||
@include_files << file
|
||||
FileUtils.expects(:cp).with(file, include_dir).in_sequence(copy_seq)
|
||||
end
|
||||
|
||||
@action.copy_include_files
|
||||
end
|
||||
end
|
||||
|
||||
context "creating vagrantfile" do
|
||||
setup do
|
||||
@temp_path = "foo"
|
||||
@action.stubs(:temp_path).returns(@temp_path)
|
||||
|
||||
@network_adapter = mock("nic")
|
||||
@network_adapter.stubs(:mac_address).returns("mac_address")
|
||||
@vm.stubs(:network_adapters).returns([@network_adapter])
|
||||
end
|
||||
|
||||
should "write the rendered vagrantfile to temp_path Vagrantfile" do
|
||||
f = mock("file")
|
||||
rendered = mock("rendered")
|
||||
File.expects(:open).with(File.join(@action.temp_path, "Vagrantfile"), "w").yields(f)
|
||||
Vagrant::Util::TemplateRenderer.expects(:render).returns(rendered).with("package_Vagrantfile", {
|
||||
:base_mac => @runner.vm.network_adapters.first.mac_address
|
||||
})
|
||||
f.expects(:write).with(rendered)
|
||||
|
||||
@action.create_vagrantfile
|
||||
end
|
||||
end
|
||||
|
||||
context "compression" do
|
||||
setup do
|
||||
@tar_path = "foo"
|
||||
@action.stubs(:tar_path).returns(@tar_path)
|
||||
|
||||
@temp_path = "foo"
|
||||
@action.stubs(:temp_path).returns(@temp_path)
|
||||
|
||||
@include_files = []
|
||||
@action.stubs(:include_files).returns(@include_files)
|
||||
|
||||
@pwd = "bar"
|
||||
FileUtils.stubs(:pwd).returns(@pwd)
|
||||
FileUtils.stubs(:cd)
|
||||
|
||||
@file = mock("file")
|
||||
File.stubs(:open).yields(@file)
|
||||
|
||||
@output = mock("output")
|
||||
@tar = Archive::Tar::Minitar
|
||||
Archive::Tar::Minitar::Output.stubs(:open).yields(@output)
|
||||
@tar.stubs(:pack_file)
|
||||
|
||||
@action.stubs(:copy_include_files)
|
||||
@action.stubs(:create_vagrantfile)
|
||||
end
|
||||
|
||||
should "open the tar file with the tar path properly" do
|
||||
File.expects(:open).with(@tar_path, Vagrant::Util::Platform.tar_file_options).once
|
||||
@action.compress
|
||||
end
|
||||
|
||||
should "open tar file" do
|
||||
Archive::Tar::Minitar::Output.expects(:open).with(@file).once
|
||||
@action.compress
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# Methods below this comment test the block yielded by Minitar open
|
||||
#----------------------------------------------------------------
|
||||
should "cd to the directory and append the directory" do
|
||||
@files = []
|
||||
compress_seq = sequence("compress_seq")
|
||||
|
||||
FileUtils.expects(:pwd).once.returns(@pwd).in_sequence(compress_seq)
|
||||
@action.expects(:copy_include_files).once.in_sequence(compress_seq)
|
||||
@action.expects(:create_vagrantfile).once.in_sequence(compress_seq)
|
||||
FileUtils.expects(:cd).with(@temp_path).in_sequence(compress_seq)
|
||||
Dir.expects(:glob).returns(@files).in_sequence(compress_seq)
|
||||
|
||||
5.times do |i|
|
||||
file = mock("file#{i}")
|
||||
@tar.expects(:pack_file).with(file, @output).once.in_sequence(compress_seq)
|
||||
@files << file
|
||||
end
|
||||
|
||||
FileUtils.expects(:cd).with(@pwd).in_sequence(compress_seq)
|
||||
@action.compress
|
||||
end
|
||||
|
||||
should "pop back to the current directory even if an exception is raised" do
|
||||
cd_seq = sequence("cd_seq")
|
||||
FileUtils.expects(:cd).with(@temp_path).raises(Exception).in_sequence(cd_seq)
|
||||
FileUtils.expects(:cd).with(@pwd).in_sequence(cd_seq)
|
||||
|
||||
assert_raises(Exception) {
|
||||
@action.compress
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context "preparing the action" do
|
||||
context "checking include files" do
|
||||
setup do
|
||||
@include_files = ['fooiest', 'booiest']
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Package, {
|
||||
:include => @include_files
|
||||
})
|
||||
@runner.stubs(:find_action).returns("foo")
|
||||
end
|
||||
|
||||
should "check that all the include files exist" do
|
||||
@include_files.each do |file|
|
||||
File.expects(:exists?).with(file).returns(true)
|
||||
end
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "raise an exception if the output file already exists" do
|
||||
File.expects(:exist?).with(@action.tar_path).returns(false)
|
||||
assert_raises(Vagrant::Actions::ActionException) { @action.prepare }
|
||||
end
|
||||
|
||||
should "raise an exception when an include file does not exist" do
|
||||
File.expects(:exists?).once.returns(false)
|
||||
assert_raises(Vagrant::Actions::ActionException) { @action.prepare }
|
||||
end
|
||||
end
|
||||
|
||||
context "loading export reference" do
|
||||
should "find and store a reference to the export action" do
|
||||
@export = mock("export")
|
||||
@runner.expects(:find_action).with(Vagrant::Actions::VM::Export).once.returns(@export)
|
||||
@action.prepare
|
||||
assert @export.equal?(@action.export_action)
|
||||
end
|
||||
|
||||
should "raise an exception if the export action couldn't be found" do
|
||||
@runner.expects(:find_action).with(Vagrant::Actions::VM::Export).once.returns(nil)
|
||||
assert_raises(Vagrant::Actions::ActionException) { @action.prepare }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,99 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ProvisionActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Provision)
|
||||
end
|
||||
|
||||
context "initialization" do
|
||||
should "have a nil provisioner by default" do
|
||||
assert_nil @action.provisioner
|
||||
end
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
should "do nothing if the provisioner is nil" do
|
||||
@action.expects(:provisioner).returns(nil)
|
||||
assert_nothing_raised { @action.execute! }
|
||||
end
|
||||
|
||||
should "call `provision!` on the provisioner" do
|
||||
provisioner = mock("provisioner")
|
||||
provisioner.expects(:provision!).once
|
||||
@action.expects(:provisioner).twice.returns(provisioner)
|
||||
@action.execute!
|
||||
end
|
||||
end
|
||||
|
||||
context "preparing" do
|
||||
context "with a nil provisioner" do
|
||||
setup do
|
||||
@runner.env.config.vm.provisioner = nil
|
||||
end
|
||||
|
||||
should "not set a provisioner if set to nil" do
|
||||
@action.prepare
|
||||
assert_nil @action.provisioner
|
||||
end
|
||||
end
|
||||
|
||||
context "with a Class provisioner" do
|
||||
setup do
|
||||
@instance = mock("instance")
|
||||
@instance.stubs(:is_a?).with(Vagrant::Provisioners::Base).returns(true)
|
||||
@instance.stubs(:prepare)
|
||||
@klass = mock("klass")
|
||||
@klass.stubs(:is_a?).with(Class).returns(true)
|
||||
@klass.stubs(:new).with(@runner).returns(@instance)
|
||||
|
||||
@runner.env.config.vm.provisioner = @klass
|
||||
end
|
||||
|
||||
should "set the provisioner to an instantiation of the class" do
|
||||
@klass.expects(:new).with(@runner).once.returns(@instance)
|
||||
assert_nothing_raised { @action.prepare }
|
||||
assert_equal @instance, @action.provisioner
|
||||
end
|
||||
|
||||
should "call prepare on the instance" do
|
||||
@instance.expects(:prepare).once
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "raise an exception if the class is not a subclass of the provisioner base" do
|
||||
@instance.expects(:is_a?).with(Vagrant::Provisioners::Base).returns(false)
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.prepare
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context "with a Symbol provisioner" do
|
||||
def provisioner_expectation(symbol, provisioner)
|
||||
@runner.env.config.vm.provisioner = symbol
|
||||
|
||||
instance = mock("instance")
|
||||
instance.expects(:prepare).once
|
||||
provisioner.expects(:new).with(@runner).returns(instance)
|
||||
assert_nothing_raised { @action.prepare }
|
||||
assert_equal instance, @action.provisioner
|
||||
end
|
||||
|
||||
should "raise an ActionException if its an unknown symbol" do
|
||||
@runner.env.config.vm.provisioner = :this_will_never_exist
|
||||
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.prepare
|
||||
}
|
||||
end
|
||||
|
||||
should "set :chef_solo to the ChefSolo provisioner" do
|
||||
provisioner_expectation(:chef_solo, Vagrant::Provisioners::ChefSolo)
|
||||
end
|
||||
|
||||
should "set :chef_server to the ChefServer provisioner" do
|
||||
provisioner_expectation(:chef_server, Vagrant::Provisioners::ChefServer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,46 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ReloadActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Reload)
|
||||
end
|
||||
|
||||
context "sub-actions" do
|
||||
setup do
|
||||
@default_order = [Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Network, Vagrant::Actions::VM::Boot]
|
||||
@vm.stubs(:running?).returns(false)
|
||||
end
|
||||
|
||||
def setup_action_expectations
|
||||
default_seq = sequence("default_seq")
|
||||
@default_order.each do |action|
|
||||
@runner.expects(:add_action).with(action).once.in_sequence(default_seq)
|
||||
end
|
||||
end
|
||||
|
||||
should "do the proper actions by default" do
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "halt if the VM is running" do
|
||||
@vm.expects(:running?).returns(true)
|
||||
@default_order.unshift(Vagrant::Actions::VM::Halt)
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "add in the provisioning step if enabled" do
|
||||
env = mock_environment do |config|
|
||||
# Dummy provisioner to test
|
||||
config.vm.provisioner = "foo"
|
||||
end
|
||||
|
||||
@runner.stubs(:env).returns(env)
|
||||
|
||||
@default_order.push(Vagrant::Actions::VM::Provision)
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class ResumeActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Resume)
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@vm.stubs(:saved?).returns(true)
|
||||
end
|
||||
|
||||
should "save the state of the VM" do
|
||||
@runner.expects(:start).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "raise an ActionException if the VM is not saved" do
|
||||
@vm.expects(:saved?).returns(false)
|
||||
@vm.expects(:start).never
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.execute!
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,211 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class SharedFoldersActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::SharedFolders)
|
||||
@runner.stubs(:system).returns(linux_system(@vm))
|
||||
end
|
||||
|
||||
def stub_shared_folders
|
||||
env = mock_environment do |config|
|
||||
config.vm.shared_folders.clear
|
||||
|
||||
if block_given?
|
||||
yield config
|
||||
else
|
||||
folders = [%w{foo fooguest foohost}, %w{bar barguest barhost}]
|
||||
folders.each do |data|
|
||||
config.vm.share_folder(*data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@runner.stubs(:env).returns(env)
|
||||
env.config.vm.shared_folders
|
||||
end
|
||||
|
||||
context "before boot" do
|
||||
should "clear folders and create metadata, in order" do
|
||||
before_seq = sequence("before")
|
||||
@action.expects(:clear_shared_folders).once.in_sequence(before_seq)
|
||||
@action.expects(:create_metadata).once.in_sequence(before_seq)
|
||||
@action.before_boot
|
||||
end
|
||||
end
|
||||
|
||||
context "after boot" do
|
||||
should "mount folders then setup unison" do
|
||||
seq = sequence("after")
|
||||
@action.expects(:mount_shared_folders).once.in_sequence(seq)
|
||||
@action.expects(:setup_unison).once.in_sequence(seq)
|
||||
@action.after_boot
|
||||
end
|
||||
end
|
||||
|
||||
context "collecting shared folders" do
|
||||
setup do
|
||||
File.stubs(:expand_path).returns("baz")
|
||||
end
|
||||
|
||||
should "return a hash of the shared folders" do
|
||||
data = {
|
||||
"foo" => %W[bar baz],
|
||||
"bar" => %W[foo baz]
|
||||
}
|
||||
|
||||
stub_shared_folders do |config|
|
||||
data.each do |name, value|
|
||||
config.vm.share_folder(name, *value)
|
||||
end
|
||||
end
|
||||
|
||||
result = @action.shared_folders
|
||||
assert_equal data.length, result.length
|
||||
data.each do |name, value|
|
||||
guest, host = value
|
||||
assert_equal guest, result[name][:guestpath]
|
||||
assert_equal host, result[name][:hostpath]
|
||||
end
|
||||
end
|
||||
|
||||
should "append sync suffix if sync enabled to a folder" do
|
||||
name = "foo"
|
||||
guest = "bar"
|
||||
host = "baz"
|
||||
|
||||
stub_shared_folders do |config|
|
||||
config.vm.share_folder(name, guest, host, :sync => true)
|
||||
end
|
||||
|
||||
result = @action.shared_folders
|
||||
assert_equal "#{guest}#{@runner.env.config.unison.folder_suffix}", result[name][:guestpath]
|
||||
assert_equal guest, result[name][:original][:guestpath]
|
||||
end
|
||||
|
||||
should "not destroy original hash" do
|
||||
@folders = stub_shared_folders do |config|
|
||||
config.vm.share_folder("foo", "bar", "baz", :sync => true)
|
||||
end
|
||||
|
||||
folder = @folders["foo"].dup
|
||||
|
||||
@action.shared_folders
|
||||
assert_equal folder, @runner.env.config.vm.shared_folders["foo"]
|
||||
end
|
||||
end
|
||||
|
||||
context "unison shared folders" do
|
||||
setup do
|
||||
@folders = stub_shared_folders do |config|
|
||||
config.vm.share_folder("foo", "bar", "baz", :sync => true)
|
||||
config.vm.share_folder("bar", "foo", "baz")
|
||||
end
|
||||
end
|
||||
|
||||
should "only return the folders marked for syncing" do
|
||||
result = @action.unison_folders
|
||||
assert_equal 1, result.length
|
||||
assert result.has_key?("foo")
|
||||
assert !result.has_key?("bar")
|
||||
end
|
||||
end
|
||||
|
||||
context "clearing shared folders" do
|
||||
setup do
|
||||
@shared_folder = mock("shared_folder")
|
||||
@shared_folders = [@shared_folder]
|
||||
@vm.stubs(:shared_folders).returns(@shared_folders)
|
||||
end
|
||||
|
||||
should "call destroy on each shared folder then reload" do
|
||||
destroy_seq = sequence("destroy")
|
||||
@shared_folders.each do |sf|
|
||||
sf.expects(:destroy).once.in_sequence(destroy_seq)
|
||||
end
|
||||
|
||||
@runner.expects(:reload!).once.in_sequence(destroy_seq)
|
||||
@action.clear_shared_folders
|
||||
end
|
||||
|
||||
should "do nothing if no shared folders existed" do
|
||||
@shared_folders.clear
|
||||
@runner.expects(:reload!).never
|
||||
@action.clear_shared_folders
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up shared folder metadata" do
|
||||
setup do
|
||||
stub_shared_folders
|
||||
end
|
||||
|
||||
should "add all shared folders to the VM" do
|
||||
shared_folders = []
|
||||
data = %W[foo bar]
|
||||
shared_folders.expects(:<<).times(data.length).with() do |sf|
|
||||
hostpath = File.expand_path("#{sf.name}host", @runner.env.root_path)
|
||||
assert data.include?(sf.name)
|
||||
assert_equal hostpath, sf.host_path
|
||||
true
|
||||
end
|
||||
|
||||
@vm.stubs(:shared_folders).returns(shared_folders)
|
||||
@vm.expects(:save).once
|
||||
|
||||
@action.create_metadata
|
||||
end
|
||||
end
|
||||
|
||||
context "mounting the shared folders" do
|
||||
setup do
|
||||
@folders = stub_shared_folders
|
||||
@ssh = mock("ssh")
|
||||
@runner.ssh.stubs(:execute).yields(@ssh)
|
||||
@runner.system.stubs(:mount_shared_folder)
|
||||
end
|
||||
|
||||
should "mount all shared folders to the VM" do
|
||||
mount_seq = sequence("mount_seq")
|
||||
@folders.each do |name, data|
|
||||
@runner.system.expects(:mount_shared_folder).with(@ssh, name, data[:guestpath]).in_sequence(mount_seq)
|
||||
end
|
||||
|
||||
@action.mount_shared_folders
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up unison" do
|
||||
setup do
|
||||
@ssh = mock("ssh")
|
||||
@runner.ssh.stubs(:execute).yields(@ssh)
|
||||
|
||||
@folders = stub_shared_folders do |config|
|
||||
config.vm.share_folder("foo", "bar", "baz", :sync => true)
|
||||
config.vm.share_folder("bar", "foo", "baz")
|
||||
end
|
||||
end
|
||||
|
||||
should "do nothing if unison folders is empty" do
|
||||
@action.stubs(:unison_folders).returns({})
|
||||
@runner.ssh.expects(:execute).never
|
||||
@action.setup_unison
|
||||
end
|
||||
|
||||
should "prepare unison then create for each folder" do
|
||||
seq = sequence("unison seq")
|
||||
@runner.system.expects(:prepare_unison).with(@ssh).once.in_sequence(seq)
|
||||
@action.unison_folders.each do |name, data|
|
||||
if data[:sync]
|
||||
@runner.system.expects(:create_unison).with do |ssh, opts|
|
||||
assert_equal @ssh, ssh
|
||||
assert_equal data, opts
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@action.setup_unison
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,73 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class StartActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Start)
|
||||
|
||||
@action.options[:provision] = true
|
||||
end
|
||||
|
||||
context "sub-actions" do
|
||||
setup do
|
||||
@runner.stubs(:created?).returns(false)
|
||||
@vm.stubs(:saved?).returns(true)
|
||||
File.stubs(:file?).returns(true)
|
||||
File.stubs(:exist?).returns(true)
|
||||
@default_order = [Vagrant::Actions::VM::Boot]
|
||||
end
|
||||
|
||||
def setup_action_expectations
|
||||
default_seq = sequence("default_seq")
|
||||
@default_order.flatten.each do |action|
|
||||
@runner.expects(:add_action).with(action, @action.options).once.in_sequence(default_seq)
|
||||
end
|
||||
end
|
||||
|
||||
should "do the proper actions by default" do
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "add customize to the beginning if its not saved" do
|
||||
@vm.expects(:saved?).returns(false)
|
||||
@default_order.unshift([Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Network])
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "add do additional if VM is not created yet" do
|
||||
@runner.stubs(:vm).returns(nil)
|
||||
@default_order.unshift([Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Network])
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "add provisioning if its enabled and not saved" do
|
||||
@vm.env.config.vm.provisioner = :chef_solo
|
||||
|
||||
@runner.stubs(:vm).returns(nil)
|
||||
@default_order.unshift([Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Network])
|
||||
@default_order << Vagrant::Actions::VM::Provision
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
|
||||
context "provision?" do
|
||||
should "return false if no provisioner is set" do
|
||||
@vm.env.config.vm.provisioner = nil
|
||||
assert !@action.provision?
|
||||
end
|
||||
|
||||
should "return true if a provisioner is set" do
|
||||
@vm.env.config.vm.provisioner = :chef_solo
|
||||
assert @action.provision?
|
||||
end
|
||||
|
||||
should "return false if provisioning is specifically disabled" do
|
||||
@vm.env.config.vm.provisioner = :chef_solo
|
||||
@action.options[:provision] = false
|
||||
assert !@action.provision?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class SuspendActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Suspend)
|
||||
end
|
||||
|
||||
context "executing" do
|
||||
setup do
|
||||
@vm.stubs(:running?).returns(true)
|
||||
end
|
||||
|
||||
should "save the state of the VM" do
|
||||
@vm.expects(:save_state).once
|
||||
@action.execute!
|
||||
end
|
||||
|
||||
should "raise an ActionException if the VM is not running" do
|
||||
@vm.expects(:running?).returns(false)
|
||||
@vm.expects(:save_state).never
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.execute!
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,96 +0,0 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
||||
|
||||
class UpActionTest < Test::Unit::TestCase
|
||||
setup do
|
||||
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Up)
|
||||
end
|
||||
|
||||
context "sub-actions" do
|
||||
setup do
|
||||
@runner.stubs(:created?).returns(false)
|
||||
|
||||
File.stubs(:file?).returns(true)
|
||||
File.stubs(:exist?).returns(true)
|
||||
@default_order = [Vagrant::Actions::VM::Import, Vagrant::Actions::VM::Start]
|
||||
|
||||
@dotfile_path = "foo"
|
||||
@runner.env.stubs(:dotfile_path).returns(@dotfile_path)
|
||||
end
|
||||
|
||||
def setup_action_expectations
|
||||
default_seq = sequence("default_seq")
|
||||
@default_order.each do |action|
|
||||
@runner.expects(:add_action).with(action, @action.options).once.in_sequence(default_seq)
|
||||
end
|
||||
end
|
||||
|
||||
should "raise an ActionException if a dotfile exists but is not a file" do
|
||||
File.expects(:file?).with(@runner.env.dotfile_path).returns(false)
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
@action.prepare
|
||||
}
|
||||
end
|
||||
|
||||
should "not raise an ActionException if dotfile doesn't exist" do
|
||||
setup_action_expectations
|
||||
File.stubs(:exist?).returns(false)
|
||||
assert_nothing_raised { @action.prepare }
|
||||
end
|
||||
|
||||
should "not raise an ActionException if dotfile exists but is a file" do
|
||||
File.stubs(:file?).returns(true)
|
||||
File.stubs(:exist?).returns(true)
|
||||
setup_action_expectations
|
||||
assert_nothing_raised { @action.prepare }
|
||||
end
|
||||
|
||||
should "do the proper actions by default" do
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
|
||||
should "add in the action to move hard drive if config is set" do
|
||||
env = mock_environment do |config|
|
||||
File.expects(:directory?).with("foo").returns(true)
|
||||
config.vm.hd_location = "foo"
|
||||
end
|
||||
|
||||
@runner.stubs(:env).returns(env)
|
||||
env.stubs(:dotfile_path).returns(@dotfile_path)
|
||||
|
||||
@default_order.insert(0, Vagrant::Actions::VM::MoveHardDrive)
|
||||
setup_action_expectations
|
||||
@action.prepare
|
||||
end
|
||||
end
|
||||
|
||||
context "callbacks" do
|
||||
should "call update dotfile and mac address setup after import" do
|
||||
boot_seq = sequence("boot")
|
||||
@action.expects(:update_dotfile).once.in_sequence(boot_seq)
|
||||
@action.expects(:setup_mac_address).once.in_sequence(boot_seq)
|
||||
@action.expects(:check_guest_additions).once.in_sequence(boot_seq)
|
||||
@action.after_import
|
||||
end
|
||||
end
|
||||
|
||||
context "updating the dotfile" do
|
||||
should "call update dotfile on the VM's environment" do
|
||||
@runner.stubs(:uuid)
|
||||
@runner.env.expects(:update_dotfile).once
|
||||
@action.update_dotfile
|
||||
end
|
||||
end
|
||||
|
||||
context "setting up MAC address" do
|
||||
should "match the mac address with the base" do
|
||||
nic = mock("nic")
|
||||
nic.expects(:mac_address=).once
|
||||
|
||||
@vm.expects(:network_adapters).returns([nic]).once
|
||||
@vm.expects(:save).once
|
||||
|
||||
@action.setup_mac_address
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,7 +9,7 @@ class FileDownloaderTest < Test::Unit::TestCase
|
|||
context "preparing" do
|
||||
should "raise an exception if the file does not exist" do
|
||||
File.expects(:file?).with(@uri).returns(false)
|
||||
assert_raises(Vagrant::Actions::ActionException) {
|
||||
assert_raises(Vagrant::Action::ActionException) {
|
||||
@downloader.prepare(@uri)
|
||||
}
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue