Goodbye, Actions

This commit is contained in:
Mitchell Hashimoto 2010-07-08 21:35:31 -07:00
parent 13a46ac1bd
commit f558304b50
56 changed files with 3 additions and 3979 deletions

View File

@ -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!

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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