diff --git a/lib/vagrant/actions/box/download.rb b/lib/vagrant/actions/box/download.rb index 0e307a39a..89115727f 100644 --- a/lib/vagrant/actions/box/download.rb +++ b/lib/vagrant/actions/box/download.rb @@ -51,7 +51,7 @@ module Vagrant def with_tempfile logger.info "Creating tempfile for storing box file..." - Tempfile.open(BASENAME, Env.tmp_path) do |tempfile| + Tempfile.open(BASENAME, @runner.env.tmp_path) do |tempfile| yield tempfile end end diff --git a/lib/vagrant/actions/vm/boot.rb b/lib/vagrant/actions/vm/boot.rb index 69b98003e..ff28793d1 100644 --- a/lib/vagrant/actions/vm/boot.rb +++ b/lib/vagrant/actions/vm/boot.rb @@ -3,7 +3,7 @@ module Vagrant module VM class Boot < Base def prepare - Vagrant.config.vm.share_folder("vagrant-root", Vagrant.config.vm.project_directory, Env.root_path) + @runner.env.config.vm.share_folder("vagrant-root", @runner.env.config.vm.project_directory, @runner.env.root_path) end def execute! @@ -27,10 +27,10 @@ module Vagrant def wait_for_boot(sleeptime=5) logger.info "Waiting for VM to boot..." - Vagrant.config[:ssh][:max_tries].to_i.times do |i| + @runner.env.config.ssh.max_tries.to_i.times do |i| logger.info "Trying to connect (attempt ##{i+1} of #{Vagrant.config[:ssh][:max_tries]})..." - if Vagrant::SSH.up? + if @runner.env.ssh.up? logger.info "VM booted and ready for use!" return true end diff --git a/lib/vagrant/actions/vm/customize.rb b/lib/vagrant/actions/vm/customize.rb index b9035b18c..04847cca7 100644 --- a/lib/vagrant/actions/vm/customize.rb +++ b/lib/vagrant/actions/vm/customize.rb @@ -6,7 +6,7 @@ module Vagrant logger.info "Running any VM customizations..." # Run the customization procs over the VM - Vagrant.config.vm.run_procs!(@runner.vm) + @runner.env.config.vm.run_procs!(@runner.vm) # Save the vm @runner.vm.save(true) diff --git a/lib/vagrant/actions/vm/destroy.rb b/lib/vagrant/actions/vm/destroy.rb index d30d78f41..cd7a34d23 100644 --- a/lib/vagrant/actions/vm/destroy.rb +++ b/lib/vagrant/actions/vm/destroy.rb @@ -15,7 +15,7 @@ module Vagrant end def depersist - Env.depersist_vm(@runner) + @runner.env.depersist_vm end end end diff --git a/lib/vagrant/actions/vm/export.rb b/lib/vagrant/actions/vm/export.rb index 603884254..38d6bee4b 100644 --- a/lib/vagrant/actions/vm/export.rb +++ b/lib/vagrant/actions/vm/export.rb @@ -21,14 +21,14 @@ module Vagrant end def setup_temp_dir - @temp_dir = File.join(Env.tmp_path, Time.now.to_i.to_s) + @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, Vagrant.config.vm.box_ovf) + File.join(temp_dir, @runner.env.config.vm.box_ovf) end def export diff --git a/lib/vagrant/actions/vm/forward_ports.rb b/lib/vagrant/actions/vm/forward_ports.rb index 70b3fc4c1..c1517f911 100644 --- a/lib/vagrant/actions/vm/forward_ports.rb +++ b/lib/vagrant/actions/vm/forward_ports.rb @@ -7,7 +7,7 @@ module Vagrant next if !vm.running? || vm.uuid == @runner.uuid vm.forwarded_ports.each do |fp| - Vagrant.config.vm.forwarded_ports.each do |name, options| + @runner.env.config.vm.forwarded_ports.each do |name, options| if fp.hostport.to_s == options[:hostport].to_s raise ActionException.new(:vm_port_collision, :name => name, :hostport => fp.hostport.to_s, :guestport => options[:guestport].to_s) end @@ -29,7 +29,7 @@ module Vagrant def forward_ports logger.info "Forwarding ports..." - Vagrant.config.vm.forwarded_ports.each do |name, options| + @runner.env.config.vm.forwarded_ports.each do |name, options| logger.info "Forwarding \"#{name}\": #{options[:guestport]} => #{options[:hostport]}" port = VirtualBox::ForwardedPort.new port.name = name diff --git a/lib/vagrant/actions/vm/import.rb b/lib/vagrant/actions/vm/import.rb index 48fe5f31e..9a0c11ce9 100644 --- a/lib/vagrant/actions/vm/import.rb +++ b/lib/vagrant/actions/vm/import.rb @@ -5,9 +5,9 @@ module Vagrant def execute! @runner.invoke_around_callback(:import) do Busy.busy do - logger.info "Importing base VM (#{Vagrant::Env.box.ovf_file})..." + logger.info "Importing base VM (#{@runner.env.box.ovf_file})..." # Use the first argument passed to the action - @runner.vm = VirtualBox::VM.import(Vagrant::Env.box.ovf_file) + @runner.vm = VirtualBox::VM.import(@runner.env.box.ovf_file) raise ActionException.new(:virtualbox_import_failure) unless @runner.vm end end diff --git a/lib/vagrant/actions/vm/package.rb b/lib/vagrant/actions/vm/package.rb index 49edea5eb..aea5a3b1a 100644 --- a/lib/vagrant/actions/vm/package.rb +++ b/lib/vagrant/actions/vm/package.rb @@ -29,7 +29,7 @@ module Vagrant end def tar_path - File.join(FileUtils.pwd, "#{out_path}#{Vagrant.config.package.extension}") + File.join(FileUtils.pwd, "#{out_path}#{@runner.env.config.package.extension}") end def temp_path diff --git a/lib/vagrant/actions/vm/provision.rb b/lib/vagrant/actions/vm/provision.rb index 2a94618ab..591f68e22 100644 --- a/lib/vagrant/actions/vm/provision.rb +++ b/lib/vagrant/actions/vm/provision.rb @@ -19,7 +19,7 @@ module Vagrant end if provisioner.is_a?(Class) - @provisioner = provisioner.new + @provisioner = provisioner.new(@runner.env) 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 @@ -30,7 +30,7 @@ module Vagrant provisioner_klass = mapping[provisioner] raise ActionException.new(:provisioner_unknown_type, :provisioner => provisioner.to_s) if provisioner_klass.nil? - @provisioner = provisioner_klass.new + @provisioner = provisioner_klass.new(@runner.env) end logger.info "Provisioning enabled with #{@provisioner.class}" diff --git a/lib/vagrant/actions/vm/reload.rb b/lib/vagrant/actions/vm/reload.rb index 1c3bb08e2..22463dbbf 100644 --- a/lib/vagrant/actions/vm/reload.rb +++ b/lib/vagrant/actions/vm/reload.rb @@ -5,7 +5,7 @@ module Vagrant def prepare steps = [Customize, ForwardPorts, SharedFolders, Boot] steps.unshift(Halt) if @runner.vm.running? - steps << Provision if !Vagrant.config.vm.provisioner.nil? + steps << Provision if !@runner.env.config.vm.provisioner.nil? steps.each do |action_klass| @runner.add_action(action_klass) diff --git a/lib/vagrant/actions/vm/shared_folders.rb b/lib/vagrant/actions/vm/shared_folders.rb index 62c1c1f1f..a89b56cbb 100644 --- a/lib/vagrant/actions/vm/shared_folders.rb +++ b/lib/vagrant/actions/vm/shared_folders.rb @@ -3,7 +3,7 @@ module Vagrant module VM class SharedFolders < Base def shared_folders - Vagrant.config.vm.shared_folders.inject([]) do |acc, data| + @runner.env.config.vm.shared_folders.inject([]) do |acc, data| name, value = data acc << [name, File.expand_path(value[:hostpath]), value[:guestpath]] end @@ -17,7 +17,7 @@ module Vagrant def after_boot logger.info "Mounting shared folders..." - Vagrant::SSH.execute do |ssh| + @runner.env.ssh.execute do |ssh| shared_folders.each do |name, hostpath, guestpath| logger.info "-- #{name}: #{guestpath}" ssh.exec!("sudo mkdir -p #{guestpath}") @@ -57,8 +57,8 @@ module Vagrant # Determine the permission string to attach to the mount command perms = [] - perms << "uid=#{Vagrant.config.vm.shared_folder_uid}" - perms << "gid=#{Vagrant.config.vm.shared_folder_gid}" + perms << "uid=#{@runner.env.config.vm.shared_folder_uid}" + perms << "gid=#{@runner.env.config.vm.shared_folder_gid}" perms = " -o #{perms.join(",")}" if !perms.empty? attempts = 0 diff --git a/lib/vagrant/actions/vm/up.rb b/lib/vagrant/actions/vm/up.rb index 933088f8d..6c9542085 100644 --- a/lib/vagrant/actions/vm/up.rb +++ b/lib/vagrant/actions/vm/up.rb @@ -4,15 +4,15 @@ module Vagrant class Up < Base def prepare # If the dotfile is not a file, raise error - if File.exist?(Env.dotfile_path) && !File.file?(Env.dotfile_path) - raise ActionException.new(:dotfile_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, Customize, ForwardPorts, SharedFolders, Boot] - steps << Provision if !Vagrant.config.vm.provisioner.nil? - steps.insert(0, MoveHardDrive) if Vagrant.config.vm.hd_location + steps << Provision if !@runner.env.config.vm.provisioner.nil? + steps.insert(0, MoveHardDrive) if @runner.env.config.vm.hd_location steps.each do |action_klass| @runner.add_action(action_klass) @@ -26,12 +26,12 @@ module Vagrant def persist logger.info "Persisting the VM UUID (#{@runner.uuid})..." - Env.persist_vm(@runner) + @runner.env.persist_vm end def setup_mac_address logger.info "Matching MAC addresses..." - @runner.vm.nics.first.macaddress = Vagrant.config[:vm][:base_mac] + @runner.vm.nics.first.macaddress = @runner.env.config.vm.base_mac @runner.vm.save(true) end end diff --git a/lib/vagrant/active_list.rb b/lib/vagrant/active_list.rb index 2979cded3..50d16a8c0 100644 --- a/lib/vagrant/active_list.rb +++ b/lib/vagrant/active_list.rb @@ -6,61 +6,68 @@ module Vagrant @@list = nil - class <] - def list(reload = false) - return @@list unless @@list.nil? || reload + # The environment this active list belongs to + attr_accessor :env - @@list ||= [] - return @@list unless File.file?(path) - File.open(path, "r") do |f| - @@list = JSON.parse(f.read) - end + # Creates the instance of the ActiveList, with the given environment + # if specified + def initialize(env=nil) + @env = env + end - @@list + # Parses and returns the list of UUIDs from the active VM + # JSON file. This will cache the result, which can be reloaded + # by setting the `reload` parameter to true. + # + # @return [Array] + def list(reload=false) + return @list unless @list.nil? || reload + + @list ||= [] + return @list unless File.file?(path) + File.open(path, "r") do |f| + @list = JSON.parse(f.read) end - # Returns an array of {Vagrant::VM} objects which are currently - # active. - def vms - list.collect { |uuid| Vagrant::VM.find(uuid) }.compact - end + @list + end - # Returns an array of UUIDs filtered so each is verified to exist. - def filtered_list - vms.collect { |vm| vm.uuid } - end + # Returns an array of {Vagrant::VM} objects which are currently + # active. + def vms + list.collect { |uuid| Vagrant::VM.find(uuid) }.compact + end - # Adds a virtual environment to the list of active virtual machines - def add(vm) - list << vm.uuid - list.uniq! - save - end + # Returns an array of UUIDs filtered so each is verified to exist. + def filtered_list + vms.collect { |vm| vm.uuid } + end - # Remove a virtual environment from the list of active virtual machines - def remove(vm) - vm = vm.uuid if vm.is_a?(Vagrant::VM) - list.delete(vm) - save - end + # Adds a virtual environment to the list of active virtual machines + def add(vm) + list << vm.uuid + list.uniq! + save + end - # Persists the list down to the JSON file. - def save - File.open(path, "w+") do |f| - f.write(filtered_list.to_json) - end - end + # Remove a virtual environment from the list of active virtual machines + def remove(vm) + vm = vm.uuid if vm.is_a?(Vagrant::VM) + list.delete(vm) + save + end - # Returns the path to the JSON file which holds the UUIDs of the - # active virtual machines managed by Vagrant. - def path - File.join(Env.home_path, FILENAME) + # Persists the list down to the JSON file. + def save + File.open(path, "w+") do |f| + f.write(filtered_list.to_json) end end + + # Returns the path to the JSON file which holds the UUIDs of the + # active virtual machines managed by Vagrant. + def path + File.join(env.home_path, FILENAME) + end end end \ No newline at end of file diff --git a/lib/vagrant/box.rb b/lib/vagrant/box.rb index bbc63b96d..e4a265c20 100644 --- a/lib/vagrant/box.rb +++ b/lib/vagrant/box.rb @@ -51,16 +51,21 @@ module Vagrant # only be used internally. attr_accessor :temp_path + # The environment which this box belongs to. Although this could + # actually be many environments, this points to the environment + # of a specific instance. + attr_accessor :env + class <] - def all + def all(env) results = [] - Dir.open(Env.boxes_path) do |dir| + Dir.open(env.boxes_path) do |dir| dir.each do |d| - next if d == "." || d == ".." || !File.directory?(File.join(Env.boxes_path, d)) + next if d == "." || d == ".." || !File.directory?(File.join(env.boxes_path, d)) results << d.to_s end end @@ -74,9 +79,9 @@ module Vagrant # # @param [String] name The name of the box # @return [Box] Instance of {Box} representing the box found - def find(name) - return nil unless File.directory?(directory(name)) - new(name) + def find(env, name) + return nil unless File.directory?(directory(env, name)) + new(env, name) end # Adds a new box with given name from the given URI. This method @@ -85,10 +90,11 @@ module Vagrant # # @param [String] name The name of the box # @param [String] uri URI to the box file - def add(name, uri) + def add(env, name, uri) box = new box.name = name box.uri = uri + box.env = env box.add end @@ -98,8 +104,8 @@ module Vagrant # # @param [String] name Name of the box whose directory you're interested in. # @return [String] Full path to the box directory. - def directory(name) - File.join(Env.boxes_path, name) + def directory(env, name) + File.join(env.boxes_path, name) end end @@ -109,8 +115,9 @@ module Vagrant # # **Note:** This method does not actually _create_ the box, but merely # returns a new, abstract representation of it. To add a box, see {#add}. - def initialize(name=nil) + def initialize(env=nil, name=nil) @name = name + @env = env end # Returns path to the OVF file of the box. The OVF file is an open @@ -139,7 +146,7 @@ module Vagrant # # @return [String] def directory - self.class.directory(self.name) + self.class.directory(env, self.name) end end end \ No newline at end of file diff --git a/lib/vagrant/commands.rb b/lib/vagrant/commands.rb index 4274b6d43..e77bdfd2e 100644 --- a/lib/vagrant/commands.rb +++ b/lib/vagrant/commands.rb @@ -12,7 +12,7 @@ module Vagrant # begin using vagrant. The configuration file contains some documentation # to get you started. def init(default_box=nil) - rootfile_path = File.join(Dir.pwd, Env::ROOTFILE_NAME) + rootfile_path = File.join(Dir.pwd, Environment::ROOTFILE_NAME) if File.exist?(rootfile_path) error_and_exit(:rootfile_already_exists) end @@ -20,7 +20,7 @@ module Vagrant # Copy over the rootfile template into this directory default_box ||= "base" File.open(rootfile_path, 'w+') do |f| - f.write(TemplateRenderer.render(Env::ROOTFILE_NAME, :default_box => default_box)) + f.write(TemplateRenderer.render(Environment::ROOTFILE_NAME, :default_box => default_box)) end end @@ -28,27 +28,27 @@ module Vagrant # useful information such as whether or not the environment is created # and if its running, suspended, etc. def status - Env.load! + env = Environment.load! wrap_output do - if !Env.persisted_vm + if !env.vm puts <<-msg The environment has not yet been created. Run `vagrant up` to create the environment. msg else additional_msg = "" - if Env.persisted_vm.vm.running? + if env.vm.vm.running? additional_msg = <<-msg To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run a `vagrant up`. msg - elsif Env.persisted_vm.vm.saved? + elsif env.vm.vm.saved? additional_msg = <<-msg To resume this VM, simply run `vagrant up`. msg - elsif Env.persisted_vm.vm.powered_off? + elsif env.vm.vm.powered_off? additional_msg = <<-msg To restart this VM, simply run `vagrant up`. msg @@ -61,7 +61,7 @@ msg puts <<-msg The environment has been created. The status of the current environment's -virtual machine is: "#{Env.persisted_vm.vm.state}."#{additional_msg} +virtual machine is: "#{env.vm.vm.state}."#{additional_msg} msg end end @@ -72,14 +72,14 @@ msg # provisioning the instance with chef. {up} also starts the instance, # running it in the background. def up - Env.load! + env = Environment.load! - if Env.persisted_vm + if env.vm logger.info "VM already created. Starting VM if its not already running..." - Env.persisted_vm.start + env.vm.start else - Env.require_box - VM.execute!(Actions::VM::Up) + env.require_box + env.create_vm.execute!(Actions::VM::Up) end end @@ -90,9 +90,9 @@ msg # This command requires that an instance already be brought up with # `vagrant up`. def down - Env.load! - Env.require_persisted_vm - Env.persisted_vm.destroy + env = Environment.load! + env.require_persisted_vm + env.vm.destroy end # Reload the environment. This is almost equivalent to the {up} command @@ -101,9 +101,9 @@ msg # VM, updates the metadata (shared folders, forwarded ports), restarts # the VM, and then reruns the provisioning if enabled. def reload - Env.load! - Env.require_persisted_vm - Env.persisted_vm.execute!(Actions::VM::Reload) + env = Environment.load! + env.require_persisted_vm + env.vm.execute!(Actions::VM::Reload) end # SSH into the vagrant instance. This will setup an SSH connection into @@ -113,9 +113,9 @@ msg # This command requires that an instance already be brought up with # `vagrant up`. def ssh - Env.load! - Env.require_persisted_vm - SSH.connect + env = Environment.load! + env.require_persisted_vm + env.ssh.connect end # Halts a running vagrant instance. This forcibly halts the instance; @@ -125,9 +125,9 @@ msg # This command requires than an instance already be brought up with # `vagrant up`. def halt - Env.load! - Env.require_persisted_vm - Env.persisted_vm.execute!(Actions::VM::Halt) + env = Environment.load! + env.require_persisted_vm + env.vm.execute!(Actions::VM::Halt) end # Suspend a running vagrant instance. This suspends the instance, saving @@ -137,9 +137,9 @@ msg # This command requires that an instance already be brought up with # `vagrant up`. def suspend - Env.load! - Env.require_persisted_vm - Env.persisted_vm.suspend + env = Environment.load! + env.require_persisted_vm + env.vm.suspend end # Resume a running vagrant instance. This resumes an already suspended @@ -148,20 +148,20 @@ msg # This command requires that an instance already be brought up with # `vagrant up`. def resume - Env.load! - Env.require_persisted_vm - Env.persisted_vm.resume + env = Environment.load! + env.require_persisted_vm + env.vm.resume end # Export and package the current vm # # This command requires that an instance be powered off def package(out_path=nil, include_files=[]) - Env.load! - Env.require_persisted_vm - error_and_exit(:vm_power_off_to_package) unless Env.persisted_vm.powered_off? + env = Environment.load! + env.require_persisted_vm + error_and_exit(:vm_power_off_to_package) unless env.vm.powered_off? - Env.persisted_vm.package(out_path, include_files) + env.vm.package(out_path, include_files) end # Manages the `vagrant box` command, allowing the user to add @@ -169,7 +169,7 @@ msg # which action to take and calls the respective action method # (see {box_add} and {box_remove}) def box(argv) - Env.load! + env = Environment.load! sub_commands = ["list", "add", "remove"] @@ -177,12 +177,12 @@ msg error_and_exit(:command_box_invalid) end - send("box_#{argv[0]}", *argv[1..-1]) + send("box_#{argv[0]}", env, *argv[1..-1]) end # Lists all added boxes - def box_list - boxes = Box.all.sort + def box_list(env) + boxes = Box.all(env).sort wrap_output do if !boxes.empty? @@ -197,13 +197,13 @@ msg end # Adds a box to the local filesystem, given a URI. - def box_add(name, path) - Box.add(name, path) + def box_add(env, name, path) + Box.add(env, name, path) end # Removes a box. - def box_remove(name) - box = Box.find(name) + def box_remove(env, name) + box = Box.find(env, name) if box.nil? error_and_exit(:box_remove_doesnt_exist) return # for tests @@ -211,13 +211,6 @@ msg box.destroy end - - private - - def act_on_vm(&block) - yield Env.persisted_vm - Env.persisted_vm.execute! - end end end end diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index 903ca6c7b..b5028e1d8 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -9,17 +9,20 @@ module Vagrant @@config = nil class << self - def reset! + def reset!(env=nil) @@config = nil proc_stack.clear + + # Reset the configuration to the specified environment + config(env) end def configures(key, klass) config.class.configures(key, klass) end - def config - @@config ||= Config::Top.new + def config(env=nil) + @@config ||= Config::Top.new(env) end def run(&block) @@ -29,12 +32,15 @@ module Vagrant def execute! run_procs!(config) config.loaded! + config end end end class Config class Base + attr_accessor :env + def [](key) send(key) end @@ -61,7 +67,7 @@ module Vagrant attr_accessor :private_key_path def private_key_path - File.expand_path(@private_key_path, Env.root_path) + File.expand_path(@private_key_path, env.root_path) end end @@ -107,11 +113,11 @@ module Vagrant end def shared_folder_uid - @shared_folder_uid || Vagrant.config.ssh.username + @shared_folder_uid || env.config.ssh.username end def shared_folder_gid - @shared_folder_gid || Vagrant.config.ssh.username + @shared_folder_gid || env.config.ssh.username end def customize(&block) @@ -154,12 +160,15 @@ module Vagrant configures :vm, VMConfig configures :vagrant, VagrantConfig - def initialize + def initialize(env=nil) self.class.configures_list.each do |key, klass| - instance_variable_set("@#{key}".to_sym, klass.new) + config = klass.new + config.env = env + instance_variable_set("@#{key}".to_sym, config) end @loaded = false + @env = env end def loaded? diff --git a/lib/vagrant/env.rb b/lib/vagrant/env.rb deleted file mode 100644 index 58412f92a..000000000 --- a/lib/vagrant/env.rb +++ /dev/null @@ -1,156 +0,0 @@ -module Vagrant - class Env - ROOTFILE_NAME = "Vagrantfile" - HOME_SUBDIRS = ["tmp", "boxes"] - - # Initialize class variables used - @@persisted_vm = nil - @@root_path = nil - @@box = nil - - extend Vagrant::Util - - class << self - def box; @@box; end - def persisted_vm; @@persisted_vm; end - def root_path; @@root_path; end - def dotfile_path;File.join(root_path, Vagrant.config.vagrant.dotfile_name); end - def home_path; File.expand_path(Vagrant.config.vagrant.home); end - def tmp_path; File.join(home_path, "tmp"); end - def boxes_path; File.join(home_path, "boxes"); end - - def load! - load_root_path! - load_config! - load_home_directory! - load_box! - load_config! - check_virtualbox! - load_vm! - end - - def check_virtualbox! - version = VirtualBox::Command.version - if version.nil? - error_and_exit(:virtualbox_not_detected) - elsif version.to_f < 3.1 - error_and_exit(:virtualbox_invalid_version, :version => version.to_s) - end - - if !VirtualBox::Global.vboxconfig? - error_and_exit(:virtualbox_xml_not_detected) - end - end - - def load_config! - # Prepare load paths for config files - load_paths = [File.join(PROJECT_ROOT, "config", "default.rb")] - load_paths << File.join(box.directory, ROOTFILE_NAME) if box - load_paths << File.join(home_path, ROOTFILE_NAME) if Vagrant.config.vagrant.home - load_paths << File.join(root_path, ROOTFILE_NAME) if root_path - - # Then clear out the old data - Config.reset! - - load_paths.each do |path| - if File.exist?(path) - logger.info "Loading config from #{path}..." - load path - end - end - - # Execute the configurations - Config.execute! - end - - def load_home_directory! - home_dir = File.expand_path(Vagrant.config.vagrant.home) - - dirs = HOME_SUBDIRS.collect { |path| File.join(home_dir, path) } - dirs.unshift(home_dir) - - dirs.each do |dir| - next if File.directory?(dir) - - logger.info "Creating home directory since it doesn't exist: #{dir}" - FileUtils.mkdir_p(dir) - end - end - - def load_box! - return unless root_path - - @@box = Box.find(Vagrant.config.vm.box) if Vagrant.config.vm.box - end - - def load_vm! - return if !root_path || !File.file?(dotfile_path) - - File.open(dotfile_path) do |f| - @@persisted_vm = Vagrant::VM.find(f.read) - end - rescue Errno::ENOENT - @@persisted_vm = nil - end - - def persist_vm(vm) - # Save to the dotfile for this project - File.open(dotfile_path, 'w+') do |f| - f.write(vm.uuid) - end - - # Also add to the global store - ActiveList.add(vm) - end - - def depersist_vm(vm) - # Delete the dotfile if it exists - File.delete(dotfile_path) if File.exist?(dotfile_path) - - # Remove from the global store - ActiveList.remove(vm) - end - - def load_root_path!(path=nil) - path = Pathname.new(File.expand_path(path || Dir.pwd)) - - # Stop if we're at the root. - return false if path.root? - - file = "#{path}/#{ROOTFILE_NAME}" - if File.exist?(file) - @@root_path = path.to_s - return true - end - - load_root_path!(path.parent) - end - - def require_root_path - if !root_path - error_and_exit(:rootfile_not_found) - end - end - - def require_box - require_root_path - - if !box - if !Vagrant.config.vm.box - error_and_exit(:box_not_specified) - else - error_and_exit(:box_specified_doesnt_exist, :box_name => Vagrant.config.vm.box) - end - end - end - - def require_persisted_vm - require_root_path - - if !persisted_vm - error_and_exit(:environment_not_created) - end - end - end - end -end diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb new file mode 100644 index 000000000..7eebdc2b7 --- /dev/null +++ b/lib/vagrant/environment.rb @@ -0,0 +1,254 @@ +module Vagrant + # Represents a single Vagrant environment. This class is responsible + # for loading all of the Vagrantfile's for the given environment and + # storing references to the various instances. + class Environment + ROOTFILE_NAME = "Vagrantfile" + HOME_SUBDIRS = ["tmp", "boxes"] + + include Util + + attr_accessor :cwd + attr_reader :root_path + attr_reader :config + attr_reader :box + attr_reader :vm + attr_reader :ssh + attr_reader :active_list + + #--------------------------------------------------------------- + # Class Methods + #--------------------------------------------------------------- + class < version.to_s) + end + + if !VirtualBox::Global.vboxconfig? + error_and_exit(:virtualbox_xml_not_detected) + end + end + end + + def initialize(cwd=nil) + @cwd = cwd + end + + #--------------------------------------------------------------- + # Path Helpers + #--------------------------------------------------------------- + + # Specifies the "current working directory" for this environment. + # This is vital in determining the root path and therefore the + # dotfile, rootpath vagrantfile, etc. This defaults to the + # actual cwd (`Dir.pwd`). + def cwd + @cwd || Dir.pwd + end + + # The path to the `dotfile`, which contains the persisted UUID of + # the VM if it exists. + def dotfile_path + File.join(root_path, config.vagrant.dotfile_name) + end + + # The path to the home directory, which is usually in `~/.vagrant/~ + def home_path + config ? config.vagrant.home : nil + end + + # The path to the Vagrant tmp directory + def tmp_path + File.join(home_path, "tmp") + end + + # The path to the Vagrant boxes directory + def boxes_path + File.join(home_path, "boxes") + end + + #--------------------------------------------------------------- + # Load Methods + #--------------------------------------------------------------- + + # Loads this entire environment, setting up the instance variables + # such as `vm`, `config`, etc. on this environment. The order this + # method calls its other methods is very particular. + def load! + load_root_path! + load_config! + load_home_directory! + load_box! + load_config! + self.class.check_virtualbox! + load_vm! + load_ssh! + load_active_list! + self + end + + # Loads the root path of this environment, given the starting + # directory (the "cwd" of this environment for lack of better words). + # This method allows an environment in `/foo` to be detected from + # `/foo/bar` (similar to how git works in subdirectories) + def load_root_path!(path=nil) + path = Pathname.new(File.expand_path(path || cwd)) + + # Stop if we're at the root. + return false if path.root? + + file = "#{path}/#{ROOTFILE_NAME}" + if File.exist?(file) + @root_path = path.to_s + return true + end + + load_root_path!(path.parent) + end + + # Loads this environment's configuration and stores it in the {config} + # variable. The configuration loaded by this method is specified to + # this environment, meaning that it will use the given root directory + # to load the Vagrantfile into that context. + def load_config! + # Prepare load paths for config files + load_paths = [File.join(PROJECT_ROOT, "config", "default.rb")] + load_paths << File.join(box.directory, ROOTFILE_NAME) if box + load_paths << File.join(home_path, ROOTFILE_NAME) if home_path + load_paths << File.join(root_path, ROOTFILE_NAME) if root_path + + # Clear out the old data + Config.reset!(self) + + # Load each of the config files in order + load_paths.each do |path| + if File.exist?(path) + logger.info "Loading config from #{path}..." + load path + end + end + + # Execute the configuration stack and store the result + @config = Config.execute! + end + + # Loads the home directory path and creates the necessary subdirectories + # within the home directory if they're not already created. + def load_home_directory! + # Setup the array of necessary home directories + dirs = HOME_SUBDIRS.collect { |subdir| File.join(home_path, subdir) } + dirs.unshift(home_path) + + # Go through each required directory, creating it if it doesn't exist + dirs.each do |dir| + next if File.directory?(dir) + + logger.info "Creating home directory since it doesn't exist: #{dir}" + FileUtils.mkdir_p(dir) + end + end + + # Loads the specified box for this environment. + def load_box! + return unless root_path + + @box = Box.find(self, config.vm.box) if config.vm.box + end + + # Loads the persisted VM (if it exists) for this environment. + def load_vm! + return if !root_path || !File.file?(dotfile_path) + + File.open(dotfile_path) do |f| + @vm = Vagrant::VM.find(f.read) + @vm.env = self if @vm + end + rescue Errno::ENOENT + @vm = nil + end + + # Loads/initializes the SSH object + def load_ssh! + @ssh = SSH.new(self) + end + + # Loads the activelist for this environment + def load_active_list! + @active_list = ActiveList.new(self) + end + + #--------------------------------------------------------------- + # Methods to manage VM + #--------------------------------------------------------------- + + # Sets the VM to a new VM. This is not too useful but is used + # in {Command.up}. This will very likely be refactored at a later + # time. + def create_vm + @vm = VM.new + @vm.env = self + @vm + end + + # Persists this environment's VM to the dotfile so it can be + # re-loaded at a later time. + def persist_vm + # Save to the dotfile for this project + File.open(dotfile_path, 'w+') do |f| + f.write(vm.uuid) + end + + # Also add to the global store + active_list.add(vm) + end + + # Removes this environment's VM from the dotfile. + def depersist_vm + # Delete the dotfile if it exists + File.delete(dotfile_path) if File.exist?(dotfile_path) + + # Remove from the global store + active_list.remove(vm) + end + + #--------------------------------------------------------------- + # Methods to check for properties and error + #--------------------------------------------------------------- + + def require_root_path + error_and_exit(:rootfile_not_found) if !root_path + end + + def require_box + require_root_path + + if !box + if !Vagrant.config.vm.box + error_and_exit(:box_not_specified) + else + error_and_exit(:box_specified_doesnt_exist, :box_name => Vagrant.config.vm.box) + end + end + end + + def require_persisted_vm + require_root_path + + error_and_exit(:environment_not_created) if !vm + end + end +end \ No newline at end of file diff --git a/lib/vagrant/provisioners/base.rb b/lib/vagrant/provisioners/base.rb index cb7a650cf..063322e55 100644 --- a/lib/vagrant/provisioners/base.rb +++ b/lib/vagrant/provisioners/base.rb @@ -7,6 +7,13 @@ module Vagrant class Base include Vagrant::Util + # The environment which this is being provisioned in + attr_reader :env + + def initialize(env) + @env = env + end + # This is the method called to "prepare" the provisioner. This is called # before any actions are run by the action runner (see {Vagrant::Actions::Runner}). # This can be used to setup shared folders, forward ports, etc. Whatever is diff --git a/lib/vagrant/provisioners/chef.rb b/lib/vagrant/provisioners/chef.rb index 6bab1dc43..6e3a575df 100644 --- a/lib/vagrant/provisioners/chef.rb +++ b/lib/vagrant/provisioners/chef.rb @@ -71,9 +71,9 @@ module Vagrant def chown_provisioning_folder logger.info "Setting permissions on chef provisioning folder..." - SSH.execute do |ssh| - ssh.exec!("sudo mkdir -p #{Vagrant.config.chef.provisioning_path}") - ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}") + env.ssh.execute do |ssh| + ssh.exec!("sudo mkdir -p #{env.config.chef.provisioning_path}") + ssh.exec!("sudo chown #{env.config.ssh.username} #{env.config.chef.provisioning_path}") end end @@ -82,8 +82,8 @@ module Vagrant # Set up initial configuration data = { - :config => Vagrant.config, - :directory => Vagrant.config.vm.project_directory, + :config => env.config, + :directory => env.config.vm.project_directory, } # And wrap it under the "vagrant" namespace @@ -91,11 +91,11 @@ module Vagrant # Merge with the "extra data" which isn't put under the # vagrant namespace by default - data.merge!(Vagrant.config.chef.json) + data.merge!(env.config.chef.json) json = data.to_json - SSH.upload!(StringIO.new(json), File.join(Vagrant.config.chef.provisioning_path, "dna.json")) + env.ssh.upload!(StringIO.new(json), File.join(env.config.chef.provisioning_path, "dna.json")) end end end diff --git a/lib/vagrant/provisioners/chef_server.rb b/lib/vagrant/provisioners/chef_server.rb index ece6e6bba..7f7053600 100644 --- a/lib/vagrant/provisioners/chef_server.rb +++ b/lib/vagrant/provisioners/chef_server.rb @@ -4,13 +4,13 @@ module Vagrant # with a chef server. class ChefServer < Chef def prepare - if Vagrant.config.chef.validation_key_path.nil? + if env.config.chef.validation_key_path.nil? raise Actions::ActionException.new(:chef_server_validation_key_required) - elsif !File.file?(Vagrant.config.chef.validation_key_path) + elsif !File.file?(validation_key_path) raise Actions::ActionException.new(:chef_server_validation_key_doesnt_exist) end - if Vagrant.config.chef.chef_server_url.nil? + if env.config.chef.chef_server_url.nil? raise Actions::ActionException.new(:chef_server_url_required) end end @@ -26,16 +26,16 @@ module Vagrant def create_client_key_folder logger.info "Creating folder to hold client key..." - path = Pathname.new(Vagrant.config.chef.client_key_path) + path = Pathname.new(env.config.chef.client_key_path) - SSH.execute do |ssh| + env.ssh.execute do |ssh| ssh.exec!("sudo mkdir -p #{path.dirname}") end end def upload_validation_key logger.info "Uploading chef client validation key..." - SSH.upload!(validation_key_path, guest_validation_key_path) + env.ssh.upload!(validation_key_path, guest_validation_key_path) end def setup_config @@ -43,11 +43,11 @@ module Vagrant log_level :info log_location STDOUT ssl_verify_mode :verify_none -chef_server_url "#{Vagrant.config.chef.chef_server_url}" +chef_server_url "#{env.config.chef.chef_server_url}" -validation_client_name "#{Vagrant.config.chef.validation_client_name}" +validation_client_name "#{env.config.chef.validation_client_name}" validation_key "#{guest_validation_key_path}" -client_key "#{Vagrant.config.chef.client_key_path}" +client_key "#{env.config.chef.client_key_path}" file_store_path "/srv/chef/file_store" file_cache_path "/srv/chef/cache" @@ -58,13 +58,13 @@ Mixlib::Log::Formatter.show_time = true solo logger.info "Uploading chef-client configuration script..." - SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "client.rb")) + env.ssh.upload!(StringIO.new(solo_file), File.join(env.config.chef.provisioning_path, "client.rb")) end def run_chef_client logger.info "Running chef-client..." - SSH.execute do |ssh| - ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-client -c client.rb -j dna.json") do |channel, data, stream| + env.ssh.execute do |ssh| + ssh.exec!("cd #{env.config.chef.provisioning_path} && sudo chef-client -c client.rb -j dna.json") do |channel, data, stream| # TODO: Very verbose. It would be easier to save the data and only show it during # an error, or when verbosity level is set high logger.info("#{stream}: #{data}") @@ -73,11 +73,11 @@ solo end def validation_key_path - File.expand_path(Vagrant.config.chef.validation_key_path, Env.root_path) + File.expand_path(env.config.chef.validation_key_path, env.root_path) end def guest_validation_key_path - File.join(Vagrant.config.chef.provisioning_path, "validation.pem") + File.join(@env.config.chef.provisioning_path, "validation.pem") end end end diff --git a/lib/vagrant/provisioners/chef_solo.rb b/lib/vagrant/provisioners/chef_solo.rb index df68c6a4c..828af3cfd 100644 --- a/lib/vagrant/provisioners/chef_solo.rb +++ b/lib/vagrant/provisioners/chef_solo.rb @@ -15,24 +15,24 @@ module Vagrant def share_cookbook_folders host_cookbook_paths.each_with_index do |cookbook, i| - Vagrant.config.vm.share_folder("vagrant-chef-solo-#{i}", cookbook_path(i), cookbook) + env.config.vm.share_folder("vagrant-chef-solo-#{i}", cookbook_path(i), cookbook) end end def setup_solo_config solo_file = <<-solo -file_cache_path "#{Vagrant.config.chef.provisioning_path}" +file_cache_path "#{env.config.chef.provisioning_path}" cookbook_path #{cookbooks_path} solo logger.info "Uploading chef-solo configuration script..." - SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb")) + env.ssh.upload!(StringIO.new(solo_file), File.join(env.config.chef.provisioning_path, "solo.rb")) end def run_chef_solo logger.info "Running chef-solo..." - SSH.execute do |ssh| - ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream| + env.ssh.execute do |ssh| + ssh.exec!("cd #{env.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream| # TODO: Very verbose. It would be easier to save the data and only show it during # an error, or when verbosity level is set high logger.info("#{stream}: #{data}") @@ -41,14 +41,14 @@ solo end def host_cookbook_paths - cookbooks = Vagrant.config.chef.cookbooks_path + cookbooks = env.config.chef.cookbooks_path cookbooks = [cookbooks] unless cookbooks.is_a?(Array) - cookbooks.collect! { |cookbook| File.expand_path(cookbook, Env.root_path) } + cookbooks.collect! { |cookbook| File.expand_path(cookbook, env.root_path) } return cookbooks end def cookbook_path(i) - File.join(Vagrant.config.chef.provisioning_path, "cookbooks-#{i}") + File.join(env.config.chef.provisioning_path, "cookbooks-#{i}") end def cookbooks_path diff --git a/lib/vagrant/ssh.rb b/lib/vagrant/ssh.rb index 1252422c4..50d52c621 100644 --- a/lib/vagrant/ssh.rb +++ b/lib/vagrant/ssh.rb @@ -1,77 +1,104 @@ module Vagrant + # Manages SSH access to a specific environment. Allows an environment to + # replace the process with SSH itself, run a specific set of commands, + # upload files, or even check if a host is up. class SSH include Vagrant::Util - class << self - def connect(opts={}) - options = {} - [:host, :username, :private_key_path].each do |param| - options[param] = opts[param] || Vagrant.config.ssh.send(param) - end + # Reference back up to the environment which this SSH object belongs + # to + attr_accessor :env - check_key_permissions(options[:private_key_path]) - Kernel.exec "ssh -p #{port(opts)} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip + def initialize(environment) + @env = environment + end + + # Connects to the environment's virtual machine, replacing the ruby + # process with an SSH process. This method optionally takes a hash + # of options which override the configuration values. + def connect(opts={}) + options = {} + [:host, :username, :private_key_path].each do |param| + options[param] = opts[param] || env.config.ssh.send(param) end - def execute(opts={}) - Net::SSH.start(Vagrant.config.ssh.host, - Vagrant.config[:ssh][:username], - opts.merge( :port => port, - :keys => [Vagrant.config.ssh.private_key_path])) do |ssh| - yield ssh - end - end + check_key_permissions(options[:private_key_path]) + Kernel.exec "ssh -p #{port(opts)} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip + end - def upload!(from, to) - execute do |ssh| - scp = Net::SCP.new(ssh) - scp.upload!(from, to) - end + # Opens an SSH connection to this environment's virtual machine and yields + # a Net::SSH object which can be used to execute remote commands. + def execute(opts={}) + Net::SSH.start(env.config.ssh.host, + env.config[:ssh][:username], + opts.merge( :port => port, + :keys => [env.config.ssh.private_key_path])) do |ssh| + yield ssh end + end - def up? - check_thread = Thread.new do - begin - Thread.current[:result] = false - execute(:timeout => Vagrant.config.ssh.timeout) do |ssh| - Thread.current[:result] = true - end - rescue Errno::ECONNREFUSED, Net::SSH::Disconnect - # False, its defaulted above + # Uploads a file from `from` to `to`. `from` is expected to be a filename + # or StringIO, and `to` is expected to be a path. This method simply forwards + # the arguments to `Net::SCP#upload!` so view that for more information. + def upload!(from, to) + execute do |ssh| + scp = Net::SCP.new(ssh) + scp.upload!(from, to) + end + end + + # Checks if this environment's machine is up (i.e. responding to SSH). + # + # @return [Boolean] + def up? + check_thread = Thread.new do + begin + Thread.current[:result] = false + execute(:timeout => env.config.ssh.timeout) do |ssh| + Thread.current[:result] = true end + rescue Errno::ECONNREFUSED, Net::SSH::Disconnect + # False, its defaulted above end - - check_thread.join(Vagrant.config.ssh.timeout) - return check_thread[:result] - rescue Net::SSH::AuthenticationFailed - error_and_exit(:vm_ssh_auth_failed) end - def port(opts={}) - opts[:port] || Vagrant.config.vm.forwarded_ports[Vagrant.config.ssh.forwarded_port_key][:hostport] + check_thread.join(env.config.ssh.timeout) + return check_thread[:result] + rescue Net::SSH::AuthenticationFailed + error_and_exit(:vm_ssh_auth_failed) + end + + # Checks the file permissions for the private key, resetting them + # if needed, or on failure erroring. + def check_key_permissions(key_path) + # TODO: This only works on unix based systems for now. Windows + # systems will need to be investigated further. + stat = File.stat(key_path) + + if stat.owned? && file_perms(key_path) != "600" + logger.info "Permissions on private key incorrect, fixing..." + File.chmod(0600, key_path) + + error_and_exit(:ssh_bad_permissions, :key_path => key_path) if file_perms(key_path) != "600" end + rescue Errno::EPERM + # This shouldn't happen since we verify we own the file, but just + # in case. + error_and_exit(:ssh_bad_permissions, :key_path => key_path) + end - def check_key_permissions(key_path) - # TODO: This only works on unix based systems for now. Windows - # systems will need to be investigated further. - stat = File.stat(key_path) + # Returns the file permissions of a given file. This is fairly unix specific + # and probably doesn't belong in this class. Will be refactored out later. + def file_perms(path) + perms = sprintf("%o", File.stat(path).mode) + perms.reverse[0..2].reverse + end - if stat.owned? && file_perms(key_path) != "600" - logger.info "Permissions on private key incorrect, fixing..." - File.chmod(0600, key_path) - - error_and_exit(:ssh_bad_permissions, :key_path => key_path) if file_perms(key_path) != "600" - end - rescue Errno::EPERM - # This shouldn't happen since we verify we own the file, but just - # in case. - error_and_exit(:ssh_bad_permissions, :key_path => key_path) - end - - def file_perms(path) - perms = sprintf("%o", File.stat(path).mode) - perms.reverse[0..2].reverse - end + # Returns the port which is either given in the options hash or taken from + # the config by finding it in the forwarded ports hash based on the + # `config.ssh.forwarded_port_key` + def port(opts={}) + opts[:port] || env.config.vm.forwarded_ports[env.config.ssh.forwarded_port_key][:hostport] end end end diff --git a/lib/vagrant/vm.rb b/lib/vagrant/vm.rb index 5265353c2..000698ee3 100644 --- a/lib/vagrant/vm.rb +++ b/lib/vagrant/vm.rb @@ -2,6 +2,7 @@ module Vagrant class VM < Actions::Runner include Vagrant::Util + attr_accessor :env attr_accessor :vm attr_accessor :from diff --git a/templates/errors.yml b/templates/errors.yml index f01c48d0e..5f711dfbc 100644 --- a/templates/errors.yml +++ b/templates/errors.yml @@ -28,7 +28,7 @@ \nvagrant box list" :dotfile_error: "The dotfile which Vagrant uses to store the UUID of the project's \nvirtual machine already exists and is not a file! The dotfile is - \ncurrently configured to be `<%= Vagrant::Env.dotfile_path %>` + \ncurrently configured to be `<%= env.dotfile_path %>` \nTo change this value, please see `config.vagrant.dotfile_name` @@ -41,16 +41,16 @@ :environment_not_created: "The task you're trying to run requires that the vagrant environment \nalready be created, but unfortunately this vagrant still appears to \nhave no box! You can setup the environment by setting up your - \n<%= Vagrant::Env::ROOTFILE_NAME %> and running `vagrant up`" + \n<%= Vagrant::Environment::ROOTFILE_NAME %> and running `vagrant up`" :package_include_file_doesnt_exist: "File specified to include: '<%= filename %>' does not exist!" :package_requires_export: "Package must be used in conjunction with export." :provisioner_invalid_class: "Provisioners must be an instance of Vagrant::Provisioners::Base" :provisioner_unknown_type: "Unknown provisioner type: <%= provisioner %>" -:rootfile_already_exists: "It looks like this directory is already setup for vagrant! (A <%= Vagrant::Env::ROOTFILE_NAME %> +:rootfile_already_exists: "It looks like this directory is already setup for vagrant! (A <%= Vagrant::Environment::ROOTFILE_NAME %> \nalready exists.)" -:rootfile_not_found: "A `<%= Vagrant::Env::ROOTFILE_NAME %>` was not found! This file is required for vagrant to run +:rootfile_not_found: "A `<%= Vagrant::Environment::ROOTFILE_NAME %>` was not found! This file is required for vagrant to run \nsince it describes the expected environment that vagrant is supposed - \nto manage. Please create a `<%= Vagrant::Env::ROOTFILE_NAME %>` and place it in your project + \nto manage. Please create a `<%= Vagrant::Environment::ROOTFILE_NAME %>` and place it in your project \nroot." :ssh_bad_permissions: "The private key to connect to this box via SSH has invalid permissions \nset on it. The permissions of the private key should be set to 0600, otherwise SSH will diff --git a/test/test_helper.rb b/test/test_helper.rb index 9196b3aba..ba780bff7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -18,6 +18,60 @@ require 'contest' require 'mocha' class Test::Unit::TestCase + # Mocks an environment, setting it up with the given config. + def mock_environment + environment = Vagrant::Environment.new + + Vagrant::Config.reset!(environment) + + Vagrant::Config.run do |config| + config.vagrant.dotfile_name = ".vagrant" + + config.ssh.username = "foo" + config.ssh.password = "bar" + config.ssh.host = "baz" + config.ssh.forwarded_port_key = "ssh" + config.ssh.max_tries = 10 + config.ssh.timeout = 10 + config.ssh.private_key_path = '~/foo' + + config.vm.box = "foo" + config.vm.box_ovf = "box.ovf" + config.vm.base_mac = "42" + config.vm.project_directory = "/vagrant" + config.vm.disk_image_format = 'VMDK' + config.vm.forward_port("ssh", 22, 2222) + config.vm.shared_folder_uid = nil + config.vm.shared_folder_gid = nil + + config.package.name = 'vagrant' + config.package.extension = '.box' + + # Chef + config.chef.chef_server_url = "http://localhost:4000" + config.chef.validation_key_path = "validation.pem" + config.chef.client_key_path = "/zoo/foo/bar.pem" + config.chef.cookbooks_path = "cookbooks" + config.chef.provisioning_path = "/tmp/vagrant-chef" + config.chef.json = { + :recipes => ["vagrant_main"] + } + + config.vagrant.home = '~/.home' + end + + if block_given? + Vagrant::Config.run do |config| + yield config + end + end + + config = Vagrant::Config.execute! + + environment.instance_variable_set(:@config, config) + environment + end + # Clears the previous config and sets up the new config def mock_config Vagrant::Config.reset! @@ -85,6 +139,7 @@ class Test::Unit::TestCase 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, vm, action] end diff --git a/test/vagrant/actions/box/download_test.rb b/test/vagrant/actions/box/download_test.rb index 63ed9ffd3..a416563bb 100644 --- a/test/vagrant/actions/box/download_test.rb +++ b/test/vagrant/actions/box/download_test.rb @@ -8,7 +8,7 @@ class DownloadBoxActionTest < Test::Unit::TestCase @runner.stubs(:temp_path=) mock_config - Vagrant::Env.stubs(:tmp_path).returns("foo") + @runner.env.stubs(:tmp_path).returns("foo") end context "preparing" do @@ -81,7 +81,7 @@ class DownloadBoxActionTest < Test::Unit::TestCase context "tempfile" do should "create a tempfile in the vagrant tmp directory" do - Tempfile.expects(:open).with(Vagrant::Actions::Box::Download::BASENAME, Vagrant::Env.tmp_path).once + Tempfile.expects(:open).with(Vagrant::Actions::Box::Download::BASENAME, @runner.env.tmp_path).once @action.with_tempfile end diff --git a/test/vagrant/actions/box/unpackage_test.rb b/test/vagrant/actions/box/unpackage_test.rb index 80fca672e..ff5141bec 100644 --- a/test/vagrant/actions/box/unpackage_test.rb +++ b/test/vagrant/actions/box/unpackage_test.rb @@ -7,7 +7,7 @@ class UnpackageBoxActionTest < Test::Unit::TestCase @runner.stubs(:temp_path).returns("bar") mock_config - Vagrant::Env.stubs(:boxes_path).returns("bar") + @runner.env.stubs(:boxes_path).returns("bar") end context "executing" do diff --git a/test/vagrant/actions/vm/boot_test.rb b/test/vagrant/actions/vm/boot_test.rb index 740349fd7..77a8d3ad8 100644 --- a/test/vagrant/actions/vm/boot_test.rb +++ b/test/vagrant/actions/vm/boot_test.rb @@ -2,14 +2,14 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper') class BootActionTest < Test::Unit::TestCase setup do - @mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Boot) - @mock_vm.stubs(:invoke_callback) + @runner, @vm, @action = mock_action(Vagrant::Actions::VM::Boot) + @runner.stubs(:invoke_callback) mock_config end context "preparing" do should "add the root shared folder" do - Vagrant.config.vm.expects(:share_folder).with("vagrant-root", Vagrant.config.vm.project_directory, Vagrant::Env.root_path).once + @runner.env.config.vm.expects(:share_folder).with("vagrant-root", @runner.env.config.vm.project_directory, @runner.env.root_path).once @action.prepare end end @@ -17,7 +17,7 @@ class BootActionTest < Test::Unit::TestCase context "execution" do should "invoke the 'boot' around callback" do boot_seq = sequence("boot_seq") - @mock_vm.expects(:invoke_around_callback).with(:boot).once.in_sequence(boot_seq).yields + @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! @@ -42,13 +42,13 @@ class BootActionTest < Test::Unit::TestCase context "waiting for boot" do should "repeatedly ping the SSH port and return false with no response" do seq = sequence('pings') - Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i - 1).returns(false).in_sequence(seq) - Vagrant::SSH.expects(:up?).once.returns(true).in_sequence(seq) + @runner.env.ssh.expects(:up?).times(@runner.env.config.ssh.max_tries.to_i - 1).returns(false).in_sequence(seq) + @runner.env.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 - Vagrant::SSH.expects(:up?).times(Vagrant.config[:ssh][:max_tries].to_i).returns(false) + @runner.env.ssh.expects(:up?).times(Vagrant.config.ssh.max_tries.to_i).returns(false) assert !@action.wait_for_boot(0) end end diff --git a/test/vagrant/actions/vm/customize_test.rb b/test/vagrant/actions/vm/customize_test.rb index 986593719..c9a4853c1 100644 --- a/test/vagrant/actions/vm/customize_test.rb +++ b/test/vagrant/actions/vm/customize_test.rb @@ -8,7 +8,7 @@ class CustomizeActionTest < Test::Unit::TestCase context "executing" do should "run the VM customization procs then save the VM" do - Vagrant.config.vm.expects(:run_procs!).with(@vm) + @runner.env.config.vm.expects(:run_procs!).with(@vm) @vm.expects(:save).with(true).once @action.execute! end diff --git a/test/vagrant/actions/vm/destroy_test.rb b/test/vagrant/actions/vm/destroy_test.rb index 4ce5aa0d6..e060e50ad 100644 --- a/test/vagrant/actions/vm/destroy_test.rb +++ b/test/vagrant/actions/vm/destroy_test.rb @@ -3,7 +3,6 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper') class DestroyActionTest < Test::Unit::TestCase setup do @runner, @vm, @action = mock_action(Vagrant::Actions::VM::Destroy) - mock_config end context "executing" do @@ -30,7 +29,7 @@ class DestroyActionTest < Test::Unit::TestCase context "depersisting" do should "call depersist_vm on Env" do - Vagrant::Env.expects(:depersist_vm).with(@runner).once + @runner.env.expects(:depersist_vm).once @action.depersist end end diff --git a/test/vagrant/actions/vm/export_test.rb b/test/vagrant/actions/vm/export_test.rb index 4ff1092b7..1228a9fcd 100644 --- a/test/vagrant/actions/vm/export_test.rb +++ b/test/vagrant/actions/vm/export_test.rb @@ -21,9 +21,9 @@ class ExportActionTest < Test::Unit::TestCase Time.stubs(:now).returns(@time_now) @tmp_path = "foo" - Vagrant::Env.stubs(:tmp_path).returns(@tmp_path) + @runner.env.stubs(:tmp_path).returns(@tmp_path) - @temp_dir = File.join(Vagrant::Env.tmp_path, @time_now) + @temp_dir = File.join(@runner.env.tmp_path, @time_now) FileUtils.stubs(:mkpath) end @@ -45,7 +45,7 @@ class ExportActionTest < Test::Unit::TestCase end should "be the temporary directory joined with the OVF filename" do - assert_equal File.join(@temp_dir, Vagrant.config.vm.box_ovf), @action.ovf_path + assert_equal File.join(@temp_dir, @runner.env.config.vm.box_ovf), @action.ovf_path end end diff --git a/test/vagrant/actions/vm/forward_ports_test.rb b/test/vagrant/actions/vm/forward_ports_test.rb index 7dbfd3e83..fa73a6846 100644 --- a/test/vagrant/actions/vm/forward_ports_test.rb +++ b/test/vagrant/actions/vm/forward_ports_test.rb @@ -20,10 +20,12 @@ class ForwardPortsActionTest < Test::Unit::TestCase vms = [@vm] VirtualBox::VM.stubs(:all).returns(vms) - mock_config do |config| + @env = mock_environment do |config| config.vm.forwarded_ports.clear config.vm.forward_port("ssh", 22, 2222) end + + @mock_vm.stubs(:env).returns(@env) end should "ignore vms which aren't running" do @@ -71,7 +73,7 @@ class ForwardPortsActionTest < Test::Unit::TestCase should "create a port forwarding for the VM" do forwarded_ports = mock("forwarded_ports") - Vagrant.config.vm.forwarded_ports.each do |name, opts| + @mock_vm.env.config.vm.forwarded_ports.each do |name, opts| forwarded_ports.expects(:<<).with do |port| assert_equal name, port.name assert_equal opts[:hostport], port.hostport diff --git a/test/vagrant/actions/vm/import_test.rb b/test/vagrant/actions/vm/import_test.rb index 5416e0968..c06803ba4 100644 --- a/test/vagrant/actions/vm/import_test.rb +++ b/test/vagrant/actions/vm/import_test.rb @@ -2,12 +2,12 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper') class ImportActionTest < Test::Unit::TestCase setup do - @mock_vm, @vm, @import = mock_action(Vagrant::Actions::VM::Import) + @runner, @vm, @import = mock_action(Vagrant::Actions::VM::Import) @ovf_file = "foo" @box = mock("box") @box.stubs(:ovf_file).returns(@ovf_file) - Vagrant::Env.stubs(:box).returns(@box) + @runner.env.stubs(:box).returns(@box) VirtualBox::VM.stubs(:import) end @@ -18,7 +18,7 @@ class ImportActionTest < Test::Unit::TestCase end should "invoke an around callback around the import" do - @mock_vm.expects(:invoke_around_callback).with(:import).once + @runner.expects(:invoke_around_callback).with(:import).once @import.execute! end @@ -28,7 +28,7 @@ class ImportActionTest < Test::Unit::TestCase end should "raise an exception if import is nil" do - @mock_vm.expects(:vm).returns(nil) + @runner.expects(:vm).returns(nil) assert_raises(Vagrant::Actions::ActionException) { @import.execute! } @@ -36,7 +36,7 @@ class ImportActionTest < Test::Unit::TestCase should "set the resulting VM as the VM of the Vagrant VM object" do new_vm = mock("new_vm") - @mock_vm.expects(:vm=).with(new_vm).once + @runner.expects(:vm=).with(new_vm).once VirtualBox::VM.expects(:import).returns(new_vm).returns("foo") @import.execute! end diff --git a/test/vagrant/actions/vm/package_test.rb b/test/vagrant/actions/vm/package_test.rb index b633d3a65..1325622ea 100644 --- a/test/vagrant/actions/vm/package_test.rb +++ b/test/vagrant/actions/vm/package_test.rb @@ -41,7 +41,7 @@ class PackageActionTest < Test::Unit::TestCase 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}#{Vagrant.config.package.extension}"), @action.tar_path + assert_equal File.join(pwd, "#{@action.out_path}#{@runner.env.config.package.extension}"), @action.tar_path end end diff --git a/test/vagrant/actions/vm/provision_test.rb b/test/vagrant/actions/vm/provision_test.rb index 630296634..468dc4f64 100644 --- a/test/vagrant/actions/vm/provision_test.rb +++ b/test/vagrant/actions/vm/provision_test.rb @@ -47,7 +47,7 @@ class ProvisionActionTest < Test::Unit::TestCase @instance.stubs(:prepare) @klass = mock("klass") @klass.stubs(:is_a?).with(Class).returns(true) - @klass.stubs(:new).returns(@instance) + @klass.stubs(:new).with(@runner.env).returns(@instance) mock_config do |config| config.vm.provisioner = @klass @@ -55,7 +55,7 @@ class ProvisionActionTest < Test::Unit::TestCase end should "set the provisioner to an instantiation of the class" do - @klass.expects(:new).once.returns(@instance) + @klass.expects(:new).with(@runner.env).once.returns(@instance) assert_nothing_raised { @action.prepare } assert_equal @instance, @action.provisioner end @@ -81,7 +81,7 @@ class ProvisionActionTest < Test::Unit::TestCase instance = mock("instance") instance.expects(:prepare).once - provisioner.expects(:new).returns(instance) + provisioner.expects(:new).with(@runner.env).returns(instance) assert_nothing_raised { @action.prepare } assert_equal instance, @action.provisioner end diff --git a/test/vagrant/actions/vm/reload_test.rb b/test/vagrant/actions/vm/reload_test.rb index 20a039e3f..b2d77fef1 100644 --- a/test/vagrant/actions/vm/reload_test.rb +++ b/test/vagrant/actions/vm/reload_test.rb @@ -32,11 +32,13 @@ class ReloadActionTest < Test::Unit::TestCase end should "add in the provisioning step if enabled" do - mock_config do |config| + 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 diff --git a/test/vagrant/actions/vm/shared_folders_test.rb b/test/vagrant/actions/vm/shared_folders_test.rb index 8a818c9f4..424a09779 100644 --- a/test/vagrant/actions/vm/shared_folders_test.rb +++ b/test/vagrant/actions/vm/shared_folders_test.rb @@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper') class SharedFoldersActionTest < Test::Unit::TestCase setup do - @mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::SharedFolders) + @runner, @vm, @action = mock_action(Vagrant::Actions::VM::SharedFolders) mock_config end @@ -27,11 +27,13 @@ class SharedFoldersActionTest < Test::Unit::TestCase end should "convert the vagrant config values into an array" do - mock_config do |config| + env = mock_environment do |config| config.vm.shared_folders.clear config.vm.share_folder("foo", "bar", "baz") end + @runner.expects(:env).returns(env) + result = [["foo", "baz", "bar"]] assert_equal result, @action.shared_folders end @@ -39,11 +41,13 @@ class SharedFoldersActionTest < Test::Unit::TestCase should "expand the path of the host folder" do File.expects(:expand_path).with("baz").once.returns("expanded_baz") - mock_config do |config| + env = mock_environment do |config| config.vm.shared_folders.clear config.vm.share_folder("foo", "bar", "baz") end + @runner.expects(:env).returns(env) + result = [["foo", "expanded_baz", "bar"]] assert_equal result, @action.shared_folders end @@ -62,7 +66,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase sf.expects(:destroy).once.in_sequence(destroy_seq) end - @mock_vm.expects(:reload!).once.in_sequence(destroy_seq) + @runner.expects(:reload!).once.in_sequence(destroy_seq) @action.clear_shared_folders end end @@ -95,9 +99,9 @@ class SharedFoldersActionTest < Test::Unit::TestCase @folders.each do |name, hostpath, guestpath| ssh.expects(:exec!).with("sudo mkdir -p #{guestpath}").in_sequence(mount_seq) @action.expects(:mount_folder).with(ssh, name, guestpath).in_sequence(mount_seq) - ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{guestpath}").in_sequence(mount_seq) + ssh.expects(:exec!).with("sudo chown #{@runner.env.config.ssh.username} #{guestpath}").in_sequence(mount_seq) end - Vagrant::SSH.expects(:execute).yields(ssh) + @runner.env.ssh.expects(:execute).yields(ssh) @action.after_boot end @@ -119,7 +123,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase end should "execute the proper mount command" do - @ssh.expects(:exec!).with("sudo mount -t vboxsf -o uid=#{Vagrant.config.ssh.username},gid=#{Vagrant.config.ssh.username} #{@name} #{@guestpath}").returns(@success_return) + @ssh.expects(:exec!).with("sudo mount -t vboxsf -o uid=#{@runner.env.config.ssh.username},gid=#{@runner.env.config.ssh.username} #{@name} #{@guestpath}").returns(@success_return) mount_folder end @@ -158,11 +162,13 @@ class SharedFoldersActionTest < Test::Unit::TestCase should "add uid AND gid to mount" do uid = "foo" gid = "bar" - mock_config do |config| + env = mock_environment do |config| config.vm.shared_folder_uid = uid config.vm.shared_folder_gid = gid end + @runner.expects(:env).twice.returns(env) + @ssh.expects(:exec!).with("sudo mount -t vboxsf -o uid=#{uid},gid=#{gid} #{@name} #{@guestpath}").returns(@success_return) mount_folder end diff --git a/test/vagrant/actions/vm/up_test.rb b/test/vagrant/actions/vm/up_test.rb index 9fa7a42b4..bbdcc2aac 100644 --- a/test/vagrant/actions/vm/up_test.rb +++ b/test/vagrant/actions/vm/up_test.rb @@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper') class UpActionTest < Test::Unit::TestCase setup do - @mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Up) + @runner, @vm, @action = mock_action(Vagrant::Actions::VM::Up) mock_config end @@ -11,17 +11,20 @@ class UpActionTest < Test::Unit::TestCase File.stubs(:file?).returns(true) File.stubs(:exist?).returns(true) @default_order = [Vagrant::Actions::VM::Import, Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot] + + @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| - @mock_vm.expects(:add_action).with(action).once.in_sequence(default_seq) + @runner.expects(:add_action).with(action).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(Vagrant::Env.dotfile_path).returns(false) + File.expects(:file?).with(@runner.env.dotfile_path).returns(false) assert_raises(Vagrant::Actions::ActionException) { @action.prepare } @@ -46,21 +49,27 @@ class UpActionTest < Test::Unit::TestCase end should "add in the provisioning step if enabled" do - mock_config do |config| + env = mock_environment do |config| config.vm.provisioner = "foo" end + @runner.stubs(:env).returns(env) + env.stubs(:dotfile_path).returns(@dotfile_path) + @default_order.push(Vagrant::Actions::VM::Provision) setup_action_expectations @action.prepare end should "add in the action to move hard drive if config is set" do - mock_config do |config| + 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 @@ -78,8 +87,8 @@ class UpActionTest < Test::Unit::TestCase context "persisting" do should "persist the VM with Env" do - @mock_vm.stubs(:uuid) - Vagrant::Env.expects(:persist_vm).with(@mock_vm).once + @runner.stubs(:uuid) + @runner.env.expects(:persist_vm).once @action.persist end end diff --git a/test/vagrant/active_list_test.rb b/test/vagrant/active_list_test.rb index 9c9bb3a8e..79043bcac 100644 --- a/test/vagrant/active_list_test.rb +++ b/test/vagrant/active_list_test.rb @@ -3,167 +3,188 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper') class ActiveListTest < Test::Unit::TestCase setup do mock_config + + @env = mock_environment + @list = Vagrant::ActiveList.new(@env) end - context "class methods" do - context "loading" do - should "load if reload is given" do - File.stubs(:file?).returns(true) - File.expects(:open).once - Vagrant::ActiveList.list(true) - end - - should "not load if the active json file doesn't exist" do - File.expects(:file?).with(Vagrant::ActiveList.path).returns(false) - File.expects(:open).never - assert_equal [], Vagrant::ActiveList.list(true) - end - - should "parse the JSON by reading the file" do - file = mock("file") - data = mock("data") - result = mock("result") - File.expects(:file?).returns(true) - File.expects(:open).with(Vagrant::ActiveList.path, 'r').once.yields(file) - file.expects(:read).returns(data) - JSON.expects(:parse).with(data).returns(result) - assert_equal result, Vagrant::ActiveList.list(true) - end - - should "not load if reload flag is false and already loaded" do - File.expects(:file?).once.returns(false) - result = Vagrant::ActiveList.list(true) - assert result.equal?(Vagrant::ActiveList.list) - assert result.equal?(Vagrant::ActiveList.list) - assert result.equal?(Vagrant::ActiveList.list) - end + context "initializing" do + should "set the environment to nil if not specified" do + assert_nothing_raised { + list = Vagrant::ActiveList.new + assert list.env.nil? + } end - context "vms" do - setup do - @list = ["foo", "bar"] - Vagrant::ActiveList.stubs(:list).returns(@list) - end + should "set the environment to the given parameter if specified" do + env = mock("env") + list = Vagrant::ActiveList.new(env) + assert_equal env, list.env + end + end - should "return the list, but with each value as a VM" do - new_seq = sequence("new") - results = [] - @list.each do |item| - result = mock("result-#{item}") - Vagrant::VM.expects(:find).with(item).returns(result).in_sequence(new_seq) - results << result - end - - assert_equal results, Vagrant::ActiveList.vms - end - - should "compact out the nil values" do - Vagrant::VM.stubs(:find).returns(nil) - results = Vagrant::ActiveList.vms - assert results.empty? - end + context "listing" do + setup do + @path = "foo" + @list.stubs(:path).returns(@path) end - context "filtered list" do - should "return a list of UUIDs from the VMs" do - vms = [] - result = [] - 5.times do |i| - vm = mock("vm#{i}") - vm.expects(:uuid).returns(i) - result << i - vms << vm - end - - Vagrant::ActiveList.stubs(:vms).returns(vms) - assert_equal result, Vagrant::ActiveList.filtered_list - end + should "load if reload is given" do + File.stubs(:file?).returns(true) + File.expects(:open).once + @list.list(true) end - context "adding a VM to the list" do - setup do - @list = [] - Vagrant::ActiveList.stubs(:list).returns(@list) - Vagrant::ActiveList.stubs(:save) - - @uuid = "foo" - @vm = mock("vm") - @vm.stubs(:uuid).returns(@uuid) - end - - should "add the VMs UUID to the list" do - Vagrant::ActiveList.add(@vm) - assert_equal [@uuid], @list - end - - should "uniq the array so multiples never exist" do - @list << @uuid - assert_equal 1, @list.length - Vagrant::ActiveList.add(@vm) - assert_equal 1, @list.length - end - - should "save after adding" do - save_seq = sequence('save') - @list.expects(:<<).in_sequence(save_seq) - Vagrant::ActiveList.expects(:save).in_sequence(save_seq) - Vagrant::ActiveList.add(@vm) - end + should "not load if the active json file doesn't exist" do + File.expects(:file?).with(@list.path).returns(false) + File.expects(:open).never + assert_equal [], @list.list(true) end - context "deleting a VM from the list" do - setup do - @list = ["bar"] - Vagrant::ActiveList.stubs(:list).returns(@list) - Vagrant::ActiveList.stubs(:save) - - @uuid = "bar" - @vm = mock("vm") - @vm.stubs(:uuid).returns(@uuid) - @vm.stubs(:is_a?).with(Vagrant::VM).returns(true) - end - - should "delete the uuid from the list of a VM" do - Vagrant::ActiveList.remove(@vm) - assert @list.empty? - end - - should "delete just the string if a string is given" do - @list << "zoo" - Vagrant::ActiveList.remove("zoo") - assert !@list.include?("zoo") - end - - should "save after removing" do - save_seq = sequence('save') - @list.expects(:delete).in_sequence(save_seq) - Vagrant::ActiveList.expects(:save).in_sequence(save_seq) - Vagrant::ActiveList.remove(@vm) - end + should "parse the JSON by reading the file" do + file = mock("file") + data = mock("data") + result = mock("result") + File.expects(:file?).returns(true) + File.expects(:open).with(@list.path, 'r').once.yields(file) + file.expects(:read).returns(data) + JSON.expects(:parse).with(data).returns(result) + assert_equal result, @list.list(true) end - context "saving" do - setup do - @filtered = ["zoo"] - Vagrant::ActiveList.stubs(:filtered_list).returns(@filtered) - end + should "not load if reload flag is false and already loaded" do + File.expects(:file?).once.returns(false) + result = @list.list(true) + assert result.equal?(@list.list) + assert result.equal?(@list.list) + assert result.equal?(@list.list) + end + end - should "open the JSON path and save to it" do - file = mock("file") - File.expects(:open).with(Vagrant::ActiveList.path, "w+").yields(file) - file.expects(:write).with(@filtered.to_json) - Vagrant::ActiveList.save - end + context "vms" do + setup do + @the_list = ["foo", "bar"] + @list.stubs(:list).returns(@the_list) end - context "path" do - setup do - Vagrant::Env.stubs(:home_path).returns("foo") + should "return the list, but with each value as a VM" do + new_seq = sequence("new") + results = [] + @the_list.each do |item| + result = mock("result-#{item}") + Vagrant::VM.expects(:find).with(item).returns(result).in_sequence(new_seq) + results << result end - should "return the active file within the home path" do - assert_equal File.join(Vagrant::Env.home_path, Vagrant::ActiveList::FILENAME), Vagrant::ActiveList.path + assert_equal results, @list.vms + end + + should "compact out the nil values" do + Vagrant::VM.stubs(:find).returns(nil) + results = @list.vms + assert results.empty? + end + end + + context "filtered list" do + should "return a list of UUIDs from the VMs" do + vms = [] + result = [] + 5.times do |i| + vm = mock("vm#{i}") + vm.expects(:uuid).returns(i) + result << i + vms << vm end + + @list.stubs(:vms).returns(vms) + assert_equal result, @list.filtered_list + end + end + + context "adding a VM to the list" do + setup do + @the_list = [] + @list.stubs(:list).returns(@the_list) + @list.stubs(:save) + + @uuid = "foo" + @vm = mock("vm") + @vm.stubs(:uuid).returns(@uuid) + end + + should "add the VMs UUID to the list" do + @list.add(@vm) + assert_equal [@uuid], @the_list + end + + should "uniq the array so multiples never exist" do + @the_list << @uuid + assert_equal 1, @the_list.length + @list.add(@vm) + assert_equal 1, @the_list.length + end + + should "save after adding" do + save_seq = sequence('save') + @the_list.expects(:<<).in_sequence(save_seq) + @list.expects(:save).in_sequence(save_seq) + @list.add(@vm) + end + end + + context "deleting a VM from the list" do + setup do + @the_list = ["bar"] + @list.stubs(:list).returns(@the_list) + @list.stubs(:save) + + @uuid = "bar" + @vm = mock("vm") + @vm.stubs(:uuid).returns(@uuid) + @vm.stubs(:is_a?).with(Vagrant::VM).returns(true) + end + + should "delete the uuid from the list of a VM" do + @list.remove(@vm) + assert @the_list.empty? + end + + should "delete just the string if a string is given" do + @the_list << "zoo" + @list.remove("zoo") + assert !@the_list.include?("zoo") + end + + should "save after removing" do + save_seq = sequence('save') + @the_list.expects(:delete).in_sequence(save_seq) + @list.expects(:save).in_sequence(save_seq) + @list.remove(@vm) + end + end + + context "saving" do + setup do + @filtered = ["zoo"] + @list.stubs(:filtered_list).returns(@filtered) + end + + should "open the JSON path and save to it" do + file = mock("file") + File.expects(:open).with(@list.path, "w+").yields(file) + file.expects(:write).with(@filtered.to_json) + @list.save + end + end + + context "path" do + setup do + @env.stubs(:home_path).returns("foo") + end + + should "return the active file within the home path" do + assert_equal File.join(@env.home_path, Vagrant::ActiveList::FILENAME), @list.path end end end diff --git a/test/vagrant/box_test.rb b/test/vagrant/box_test.rb index 8a0d20a7d..559e83f27 100644 --- a/test/vagrant/box_test.rb +++ b/test/vagrant/box_test.rb @@ -2,36 +2,40 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper') class BoxTest < Test::Unit::TestCase context "class methods" do + setup do + @env = mock_environment + end + context "listing all boxes" do setup do Dir.stubs(:open) File.stubs(:directory?).returns(true) @boxes_path = "foo" - Vagrant::Env.stubs(:boxes_path).returns(@boxes_path) + @env.stubs(:boxes_path).returns(@boxes_path) end should "open the boxes directory" do - Dir.expects(:open).with(Vagrant::Env.boxes_path) - Vagrant::Box.all + Dir.expects(:open).with(@env.boxes_path) + Vagrant::Box.all(@env) end should "return an array" do - result = Vagrant::Box.all + result = Vagrant::Box.all(@env) assert result.is_a?(Array) end should "not return the '.' and '..' directories" do dir = [".", "..", "..", ".", ".."] Dir.expects(:open).yields(dir) - result = Vagrant::Box.all + result = Vagrant::Box.all(@env) assert result.empty? end should "return the other directories" do dir = [".", "foo", "bar", "baz"] Dir.expects(:open).yields(dir) - result = Vagrant::Box.all + result = Vagrant::Box.all(@env) assert_equal ["foo", "bar", "baz"], result end @@ -44,7 +48,7 @@ class BoxTest < Test::Unit::TestCase File.expects(:directory?).with(File.join(@boxes_path, dir)).returns(files[index]).in_sequence(dir_sequence) end - result = Vagrant::Box.all + result = Vagrant::Box.all(@env) assert_equal ["foo"], result end end @@ -53,20 +57,27 @@ class BoxTest < Test::Unit::TestCase setup do @dir = "foo" @name = "bar" - Vagrant::Box.stubs(:directory).with(@name).returns(@dir) + Vagrant::Box.stubs(:directory).with(@env, @name).returns(@dir) end should "return nil if the box doesn't exist" do File.expects(:directory?).with(@dir).once.returns(false) - assert_nil Vagrant::Box.find(@name) + assert_nil Vagrant::Box.find(@env, @name) end should "return a box object with the proper name set" do File.expects(:directory?).with(@dir).once.returns(true) - result = Vagrant::Box.find(@name) + result = Vagrant::Box.find(@env, @name) assert result assert_equal @name, result.name end + + should "return a box object with the proper env set" do + File.expects(:directory?).with(@dir).once.returns(true) + result = Vagrant::Box.find(@env, @name) + assert result + assert_equal @env, result.env + end end context "adding" do @@ -79,20 +90,21 @@ class BoxTest < Test::Unit::TestCase box = mock("box") box.expects(:name=).with(@name) box.expects(:uri=).with(@uri) + box.expects(:env=).with(@env) box.expects(:add).once Vagrant::Box.expects(:new).returns(box) - Vagrant::Box.add(@name, @uri) + Vagrant::Box.add(@env, @name, @uri) end end context "box directory" do setup do @name = "foo" - @box_dir = File.join(Vagrant::Env.boxes_path, @name) + @box_dir = File.join(@env.boxes_path, @name) end should "return the boxes_path joined with the name" do - assert_equal @box_dir, Vagrant::Box.directory(@name) + assert_equal @box_dir, Vagrant::Box.directory(@env, @name) end end end @@ -114,7 +126,7 @@ class BoxTest < Test::Unit::TestCase should "return the boxes_path joined with the name" do result = mock("object") - Vagrant::Box.expects(:directory).with(@box.name).returns(result) + Vagrant::Box.expects(:directory).with(@box.env, @box.name).returns(result) assert result.equal?(@box.directory) end end diff --git a/test/vagrant/commands_test.rb b/test/vagrant/commands_test.rb index 3139ca34a..40415951d 100644 --- a/test/vagrant/commands_test.rb +++ b/test/vagrant/commands_test.rb @@ -2,12 +2,13 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper') class CommandsTest < Test::Unit::TestCase setup do - Vagrant::Env.stubs(:load!) - @persisted_vm = mock("persisted_vm") @persisted_vm.stubs(:execute!) - Vagrant::Env.stubs(:persisted_vm).returns(@persisted_vm) - Vagrant::Env.stubs(:require_persisted_vm) + + @env = mock_environment + @env.stubs(:vm).returns(@persisted_vm) + @env.stubs(:require_persisted_vm) + Vagrant::Environment.stubs(:load!).returns(@env) end context "init" do @@ -15,7 +16,7 @@ class CommandsTest < Test::Unit::TestCase @file = mock("file") @file.stubs(:write) File.stubs(:open).yields(@file) - @rootfile_path = File.join(Dir.pwd, Vagrant::Env::ROOTFILE_NAME) + @rootfile_path = File.join(Dir.pwd, Vagrant::Environment::ROOTFILE_NAME) Vagrant::Util::TemplateRenderer.stubs(:render) end @@ -37,42 +38,45 @@ class CommandsTest < Test::Unit::TestCase should "use the given base box if given" do box = "zooo" - Vagrant::Util::TemplateRenderer.expects(:render).with(Vagrant::Env::ROOTFILE_NAME, :default_box => box) + Vagrant::Util::TemplateRenderer.expects(:render).with(Vagrant::Environment::ROOTFILE_NAME, :default_box => box) Vagrant::Commands.init(box) end should "use the default `base` if no box is given" do - Vagrant::Util::TemplateRenderer.expects(:render).with(Vagrant::Env::ROOTFILE_NAME, :default_box => "base") + Vagrant::Util::TemplateRenderer.expects(:render).with(Vagrant::Environment::ROOTFILE_NAME, :default_box => "base") Vagrant::Commands.init end end context "up" do setup do - Vagrant::Env.stubs(:persisted_vm).returns(nil) - Vagrant::VM.stubs(:execute!) - Vagrant::Env.stubs(:require_box) + @new_vm = mock("vm") + @new_vm.stubs(:execute!) + + @env.stubs(:vm).returns(nil) + @env.stubs(:require_box) + @env.stubs(:create_vm).returns(@new_vm) end should "require load the environment" do - Vagrant::Env.expects(:load!).once + Vagrant::Environment.expects(:load!).once.returns(@env) Vagrant::Commands.up end should "require a box" do - Vagrant::Env.expects(:require_box).once + @env.expects(:require_box).once Vagrant::Commands.up end should "call the up action on VM if it doesn't exist" do - Vagrant::VM.expects(:execute!).with(Vagrant::Actions::VM::Up).once + @new_vm.expects(:execute!).with(Vagrant::Actions::VM::Up).once Vagrant::Commands.up end should "call start on the persisted vm if it exists" do - Vagrant::Env.stubs(:persisted_vm).returns(@persisted_vm) + @env.stubs(:vm).returns(@persisted_vm) @persisted_vm.expects(:start).once - Vagrant::VM.expects(:execute!).never + @env.expects(:create_vm).never Vagrant::Commands.up end end @@ -82,8 +86,13 @@ class CommandsTest < Test::Unit::TestCase @persisted_vm.stubs(:destroy) end + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.down + end + should "require a persisted VM" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.down end @@ -94,8 +103,13 @@ class CommandsTest < Test::Unit::TestCase end context "reload" do + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.reload + end + should "require a persisted VM" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.reload end @@ -107,23 +121,33 @@ class CommandsTest < Test::Unit::TestCase context "ssh" do setup do - Vagrant::SSH.stubs(:connect) + @env.ssh.stubs(:connect) + end + + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.ssh end should "require a persisted VM" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.ssh end should "connect to SSH" do - Vagrant::SSH.expects(:connect).once + @env.ssh.expects(:connect).once Vagrant::Commands.ssh end end context "halt" do + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.halt + end + should "require a persisted VM" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.halt end @@ -139,8 +163,13 @@ class CommandsTest < Test::Unit::TestCase @persisted_vm.stubs(:saved?).returns(false) end + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.suspend + end + should "require a persisted VM" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.suspend end @@ -156,8 +185,13 @@ class CommandsTest < Test::Unit::TestCase @persisted_vm.stubs(:saved?).returns(true) end + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.resume + end + should "require a persisted VM" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.resume end @@ -173,8 +207,13 @@ class CommandsTest < Test::Unit::TestCase @persisted_vm.stubs(:powered_off?).returns(true) end + should "load the current environment" do + Vagrant::Environment.expects(:load!).once.returns(@env) + Vagrant::Commands.package + end + should "require a persisted vm" do - Vagrant::Env.expects(:require_persisted_vm).once + @env.expects(:require_persisted_vm).once Vagrant::Commands.package end @@ -212,7 +251,7 @@ class CommandsTest < Test::Unit::TestCase end should "load the environment" do - Vagrant::Env.expects(:load!).once + Vagrant::Environment.expects(:load!).once.returns(@env) Vagrant::Commands.box(["add"]) end @@ -232,7 +271,7 @@ class CommandsTest < Test::Unit::TestCase end should "forward any additional arguments" do - Vagrant::Commands.expects(:box_add).with(1,2,3).once + Vagrant::Commands.expects(:box_add).with(@env, 1,2,3).once Vagrant::Commands.box(["add",1,2,3]) end end @@ -248,8 +287,8 @@ class CommandsTest < Test::Unit::TestCase should "call all on box and sort the results" do @all = mock("all") @all.expects(:sort).returns(@boxes) - Vagrant::Box.expects(:all).returns(@all) - Vagrant::Commands.box_list + Vagrant::Box.expects(:all).with(@env).returns(@all) + Vagrant::Commands.box_list(@env) end end @@ -260,8 +299,8 @@ class CommandsTest < Test::Unit::TestCase end should "execute the add action with the name and path" do - Vagrant::Box.expects(:add).with(@name, @path).once - Vagrant::Commands.box_add(@name, @path) + Vagrant::Box.expects(:add).with(@env, @name, @path).once + Vagrant::Commands.box_add(@env, @name, @path) end end @@ -273,14 +312,14 @@ class CommandsTest < Test::Unit::TestCase should "error and exit if the box doesn't exist" do Vagrant::Box.expects(:find).returns(nil) Vagrant::Commands.expects(:error_and_exit).with(:box_remove_doesnt_exist).once - Vagrant::Commands.box_remove(@name) + Vagrant::Commands.box_remove(@env, @name) end should "call destroy on the box if it exists" do @box = mock("box") - Vagrant::Box.expects(:find).with(@name).returns(@box) + Vagrant::Box.expects(:find).with(@env, @name).returns(@box) @box.expects(:destroy).once - Vagrant::Commands.box_remove(@name) + Vagrant::Commands.box_remove(@env, @name) end end end diff --git a/test/vagrant/config_test.rb b/test/vagrant/config_test.rb index 47db91909..1fadb94d9 100644 --- a/test/vagrant/config_test.rb +++ b/test/vagrant/config_test.rb @@ -2,10 +2,14 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper') class ConfigTest < Test::Unit::TestCase context "the ssh config" do + setup do + @env = mock_environment + @env.stubs(:root_path).returns("foo") + end + should "expand any path when requesting the value" do - Vagrant::Env.stubs(:root_path).returns('foo') - File.stubs(:expand_path).with(Vagrant.config.ssh[:private_key_path], 'foo').returns('success') - assert Vagrant.config.ssh.private_key_path, 'success' + result = File.expand_path(@env.config.ssh[:private_key_path], @env.root_path) + assert_equal result, @env.config.ssh.private_key_path end end @@ -40,6 +44,12 @@ class ConfigTest < Test::Unit::TestCase Vagrant::Config.reset! assert Vagrant::Config.proc_stack.empty? end + + should "reload the config object based on the given environment" do + env = mock("env") + Vagrant::Config.expects(:config).with(env).once + Vagrant::Config.reset!(env) + end end context "accessing configuration" do @@ -78,6 +88,12 @@ class ConfigTest < Test::Unit::TestCase Vagrant::Config.execute! assert Vagrant::Config.config.loaded? end + + should "return the configuration on execute!" do + Vagrant::Config.run {} + result = Vagrant::Config.execute! + assert result.equal?(Vagrant.config) + end end context "base class" do @@ -138,21 +154,25 @@ class ConfigTest < Test::Unit::TestCase end should "initialize each configurer and set it to its key" do + env = mock('env') + 5.times do |i| key = "key#{i}" klass = mock("klass#{i}") instance = mock("instance#{i}") + instance.expects(:env=).with(env) klass.expects(:new).returns(instance) @configures_list << [key, klass] end - Vagrant::Config::Top.new + Vagrant::Config::Top.new(env) end should "allow reading via methods" do key = "my_foo_bar_key" klass = mock("klass") instance = mock("instance") + instance.stubs(:env=) klass.expects(:new).returns(instance) Vagrant::Config::Top.configures(key, klass) @@ -196,12 +216,9 @@ class ConfigTest < Test::Unit::TestCase context "VM configuration" do setup do - @config = Vagrant::Config::VMConfig.new - @username = "bob" - - mock_config do |config| - config.ssh.username = @username - end + @env = mock_environment + @config = @env.config.vm + @env.config.ssh.username = @username end should "include the stacked proc runner module" do diff --git a/test/vagrant/env_test.rb b/test/vagrant/env_test.rb deleted file mode 100644 index c25f64099..000000000 --- a/test/vagrant/env_test.rb +++ /dev/null @@ -1,427 +0,0 @@ -require File.join(File.dirname(__FILE__), '..', 'test_helper') - -class EnvTest < Test::Unit::TestCase - def mock_persisted_vm(returnvalue="foovm") - filemock = mock("filemock") - filemock.expects(:read).returns("foo") - Vagrant::VM.expects(:find).with("foo").returns(returnvalue) - File.expects(:open).with(Vagrant::Env.dotfile_path).once.yields(filemock) - File.expects(:file?).with(Vagrant::Env.dotfile_path).once.returns(true) - Vagrant::Env.load_vm! - end - - setup do - mock_config - Vagrant::Box.stubs(:find).returns("foo") - end - - context "checking virtualbox version" do - setup do - VirtualBox::Command.stubs(:version).returns("3.1.4") - VirtualBox::Global.stubs(:vboxconfig?).returns(true) - end - - should "not error and exit if everything is good" do - VirtualBox::Command.expects(:version).returns("3.1.4") - VirtualBox::Global.expects(:vboxconfig?).returns(true) - Vagrant::Env.expects(:error_and_exit).never - Vagrant::Env.check_virtualbox! - end - - should "error and exit if VirtualBox is not installed or detected" do - Vagrant::Env.expects(:error_and_exit).with(:virtualbox_not_detected).once - VirtualBox::Command.expects(:version).returns(nil) - Vagrant::Env.check_virtualbox! - end - - should "error and exit if VirtualBox is lower than version 3.1" do - version = "3.0.12r1041" - Vagrant::Env.expects(:error_and_exit).with(:virtualbox_invalid_version, :version => version.to_s).once - VirtualBox::Command.expects(:version).returns(version) - Vagrant::Env.check_virtualbox! - end - - should "error and exit if the the vboxconfig is not set" do - VirtualBox::Global.expects(:vboxconfig?).returns(false) - Vagrant::Env.expects(:error_and_exit).with(:virtualbox_xml_not_detected).once - Vagrant::Env.check_virtualbox! - end - end - - context "requiring a VM" do - setup do - Vagrant::Env.stubs(:require_root_path) - Vagrant::Env.stubs(:error_and_exit) - end - - should "require root path" do - Vagrant::Env.expects(:require_root_path).once - Vagrant::Env.require_persisted_vm - end - - should "error and exit if no persisted VM was found" do - assert_nil Vagrant::Env.persisted_vm - Vagrant::Env.expects(:error_and_exit).with(:environment_not_created).once - Vagrant::Env.require_persisted_vm - end - - should "return and continue if persisted VM is found" do - mock_persisted_vm - Vagrant::Env.expects(:error_and_exit).never - Vagrant::Env.require_persisted_vm - end - end - - context "loading home directory" do - setup do - @home_dir = File.expand_path(Vagrant.config.vagrant.home) - - File.stubs(:directory?).returns(true) - FileUtils.stubs(:mkdir_p) - end - - should "create each directory if it doesn't exist" do - create_seq = sequence("create_seq") - File.stubs(:directory?).returns(false) - Vagrant::Env::HOME_SUBDIRS.each do |subdir| - FileUtils.expects(:mkdir_p).with(File.join(@home_dir, subdir)).in_sequence(create_seq) - end - - Vagrant::Env.load_home_directory! - end - - should "not create directories if they exist" do - File.stubs(:directory?).returns(true) - FileUtils.expects(:mkdir_p).never - Vagrant::Env.load_home_directory! - end - end - - context "loading config" do - setup do - @root_path = "/foo" - Vagrant::Env.stubs(:root_path).returns(@root_path) - Vagrant::Env.stubs(:box).returns(nil) - File.stubs(:exist?).returns(false) - Vagrant::Config.stubs(:execute!) - Vagrant::Config.stubs(:reset!) - end - - should "reset the configuration object" do - Vagrant::Config.expects(:reset!).once - Vagrant::Env.load_config! - end - - should "load from the project root" do - File.expects(:exist?).with(File.join(PROJECT_ROOT, "config", "default.rb")).once - Vagrant::Env.load_config! - end - - should "load from the root path" do - File.expects(:exist?).with(File.join(@root_path, Vagrant::Env::ROOTFILE_NAME)).once - Vagrant::Env.load_config! - end - - should "load from the home directory" do - File.expects(:exist?).with(File.join(Vagrant::Env.home_path, Vagrant::Env::ROOTFILE_NAME)).once - Vagrant::Env.load_config! - end - - should "not load from the home directory if the home config is nil" do - mock_config do |config| - config.vagrant.home = nil - end - - File.expects(:exist?).with(File.join(Vagrant::Env.home_path, Vagrant::Env::ROOTFILE_NAME)).never - Vagrant::Env.load_config! - end - - should "not load from the root path if nil" do - Vagrant::Env.stubs(:root_path).returns(nil) - File.expects(:exist?).with(File.join(@root_path, Vagrant::Env::ROOTFILE_NAME)).never - Vagrant::Env.load_config! - end - - should "not load from the box directory if it is nil" do - Vagrant::Env.expects(:box).once.returns(nil) - Vagrant::Env.load_config! - end - - should "load from the box directory if it is not nil" do - dir = "foo" - box = mock("box") - box.stubs(:directory).returns(dir) - Vagrant::Env.expects(:box).twice.returns(box) - File.expects(:exist?).with(File.join(dir, Vagrant::Env::ROOTFILE_NAME)).once - Vagrant::Env.load_config! - end - - should "load the files only if exist? returns true" do - File.expects(:exist?).once.returns(true) - Vagrant::Env.expects(:load).once - Vagrant::Env.load_config! - end - - should "not load the files if exist? returns false" do - Vagrant::Env.expects(:load).never - Vagrant::Env.load_config! - end - - should "execute after loading" do - File.expects(:exist?).once.returns(true) - Vagrant::Env.expects(:load).once - Vagrant::Config.expects(:execute!).once - Vagrant::Env.load_config! - end - end - - context "initial load" do - should "load! should load the config and set the persisted_uid" do - call_seq = sequence("call_sequence") - Vagrant::Env.expects(:load_root_path!).once.in_sequence(call_seq) - Vagrant::Env.expects(:load_config!).once.in_sequence(call_seq) - Vagrant::Env.expects(:load_home_directory!).once.in_sequence(call_seq) - Vagrant::Env.expects(:load_box!).once.in_sequence(call_seq) - Vagrant::Env.expects(:load_config!).once.in_sequence(call_seq) - Vagrant::Env.expects(:check_virtualbox!).once.in_sequence(call_seq) - Vagrant::Env.expects(:load_vm!).once.in_sequence(call_seq) - Vagrant::Env.load! - end - end - - context "persisting the VM into a file" do - setup do - @vm = mock("vm") - @vm.stubs(:uuid).returns("foo") - - File.stubs(:open) - Vagrant::ActiveList.stubs(:add) - end - - should "should save it to the dotfile path" do - filemock = mock("filemock") - filemock.expects(:write).with(@vm.uuid) - File.expects(:open).with(Vagrant::Env.dotfile_path, 'w+').once.yields(filemock) - Vagrant::Env.persist_vm(@vm) - end - - should "add the VM to the activelist" do - Vagrant::ActiveList.expects(:add).with(@vm) - Vagrant::Env.persist_vm(@vm) - end - end - - context "depersisting the VM" do - setup do - File.stubs(:exist?).returns(false) - File.stubs(:delete) - - Vagrant::ActiveList.stubs(:remove) - - @dotfile_path = "foo" - Vagrant::Env.stubs(:dotfile_path).returns(@dotfile_path) - - @vm = mock("vm") - end - - should "remove the dotfile if it exists" do - File.expects(:exist?).with(Vagrant::Env.dotfile_path).returns(true) - File.expects(:delete).with(Vagrant::Env.dotfile_path).once - Vagrant::Env.depersist_vm(@vm) - end - - should "not remove the dotfile if it doesn't exist" do - File.expects(:exist?).returns(false) - File.expects(:delete).never - Vagrant::Env.depersist_vm(@vm) - end - - should "remove from the active list" do - Vagrant::ActiveList.expects(:remove).with(@vm) - Vagrant::Env.depersist_vm(@vm) - end - end - - context "loading the UUID out from the persisted file" do - setup do - File.stubs(:file?).returns(true) - end - - should "loading of the uuid from the dotfile" do - mock_persisted_vm - assert_equal 'foovm', Vagrant::Env.persisted_vm - end - - should "do nothing if the root path is nil" do - File.expects(:open).never - Vagrant::Env.stubs(:root_path).returns(nil) - Vagrant::Env.load_vm! - end - - should "do nothing if dotfile is not a file" do - File.expects(:file?).returns(false) - File.expects(:open).never - Vagrant::Env.load_vm! - end - - should "uuid should be nil if dotfile didn't exist" do - File.expects(:open).raises(Errno::ENOENT) - Vagrant::Env.load_vm! - assert_nil Vagrant::Env.persisted_vm - end - - should "should build up the dotfile out of the root path and the dotfile name" do - assert_equal File.join(Vagrant::Env.root_path, Vagrant.config.vagrant.dotfile_name), Vagrant::Env.dotfile_path - end - end - - context "loading the root path" do - should "default the path to the pwd if nil" do - @path = mock("path") - @path.stubs(:root?).returns(true) - Pathname.expects(:new).with(Dir.pwd).returns(@path) - Vagrant::Env.load_root_path!(nil) - end - - should "not default the path to pwd if its not nil" do - @path = mock("path") - @path.stubs(:to_s).returns("/") - File.expects(:expand_path).with(@path).returns("/") - Pathname.expects(:new).with("/").returns(@path) - @path.stubs(:root?).returns(true) - Vagrant::Env.load_root_path!(@path) - end - - should "should walk the parent directories looking for rootfile" do - paths = [ - Pathname.new("/foo/bar/baz"), - Pathname.new("/foo/bar"), - Pathname.new("/foo") - ] - - search_seq = sequence("search_seq") - paths.each do |path| - File.expects(:exist?).with("#{path}/#{Vagrant::Env::ROOTFILE_NAME}").returns(false).in_sequence(search_seq) - end - - assert !Vagrant::Env.load_root_path!(paths.first) - end - - should "return false if not found" do - path = Pathname.new("/") - assert !Vagrant::Env.load_root_path!(path) - end - - should "return false if not found on windows-style root" do - # TODO: Is there _any_ way to test this on unix machines? The - # expand path doesn't work [properly for the test] on unix machines. - if RUBY_PLATFORM.downcase.include?("mswin") - # Note the escaped back slash - path = Pathname.new("C:\\") - assert !Vagrant::Env.load_root_path!(path) - end - end - - should "should set the path for the rootfile" do - path = "/foo" - File.expects(:exist?).with("#{path}/#{Vagrant::Env::ROOTFILE_NAME}").returns(true) - - assert Vagrant::Env.load_root_path!(Pathname.new(path)) - assert_equal path, Vagrant::Env.root_path - end - end - - context "home directory paths" do - should "return the expanded config for `home_path`" do - assert_equal File.expand_path(Vagrant.config.vagrant.home), Vagrant::Env.home_path - end - - should "return the home_path joined with tmp for a tmp path" do - @home_path = "foo" - Vagrant::Env.stubs(:home_path).returns(@home_path) - assert_equal File.join(@home_path, "tmp"), Vagrant::Env.tmp_path - end - - should "return the boxes path" do - @home_path = "foo" - Vagrant::Env.stubs(:home_path).returns(@home_path) - assert_equal File.join(@home_path, "boxes"), Vagrant::Env.boxes_path - end - end - - context "loading box" do - setup do - @box = mock("box") - - Vagrant::Env.stubs(:load_config!) - Vagrant::Env.stubs(:root_path).returns("foo") - end - - should "do nothing if the root path is nil" do - Vagrant::Box.expects(:find).never - Vagrant::Env.stubs(:root_path).returns(nil) - Vagrant::Env.load_vm! - end - - should "not load the box if its not set" do - mock_config do |config| - config.vm.box = nil - end - - Vagrant::Box.expects(:find).never - Vagrant::Env.load_box! - end - - should "set the box to what is found by the Box class" do - Vagrant::Box.expects(:find).with(Vagrant.config.vm.box).once.returns(@box) - Vagrant::Env.load_box! - assert @box.equal?(Vagrant::Env.box) - end - end - - context "requiring boxes" do - setup do - Vagrant::Env.stubs(:require_root_path) - Vagrant::Env.stubs(:error_and_exit) - end - - should "require root path" do - Vagrant::Env.expects(:require_root_path).once - Vagrant::Env.require_box - end - - should "error and exit if no box is specified" do - mock_config do |config| - config.vm.box = nil - end - - Vagrant::Env.expects(:box).returns(nil) - Vagrant::Env.expects(:error_and_exit).once.with(:box_not_specified) - Vagrant::Env.require_box - end - - should "error and exit if box is specified but doesn't exist" do - mock_config do |config| - config.vm.box = "foo" - end - - Vagrant::Env.expects(:box).returns(nil) - Vagrant::Env.expects(:error_and_exit).once.with(:box_specified_doesnt_exist, :box_name => "foo") - Vagrant::Env.require_box - end - end - - context "requiring root_path" do - should "error and exit if no root_path is set" do - Vagrant::Env.expects(:root_path).returns(nil) - Vagrant::Env.expects(:error_and_exit).with(:rootfile_not_found).once - Vagrant::Env.require_root_path - end - - should "not error and exit if root_path is set" do - Vagrant::Env.expects(:root_path).returns("foo") - Vagrant::Env.expects(:error_and_exit).never - Vagrant::Env.require_root_path - end - end -end diff --git a/test/vagrant/environment_test.rb b/test/vagrant/environment_test.rb new file mode 100644 index 000000000..c0dbd5a12 --- /dev/null +++ b/test/vagrant/environment_test.rb @@ -0,0 +1,590 @@ +require File.join(File.dirname(__FILE__), '..', 'test_helper') + +class EnvironmentTest < Test::Unit::TestCase + setup do + mock_config + end + + context "class method check virtualbox version" do + setup do + VirtualBox::Command.stubs(:version).returns("3.1.4") + VirtualBox::Global.stubs(:vboxconfig?).returns(true) + end + + should "not error and exit if everything is good" do + VirtualBox::Command.expects(:version).returns("3.1.4") + VirtualBox::Global.expects(:vboxconfig?).returns(true) + Vagrant::Environment.expects(:error_and_exit).never + Vagrant::Environment.check_virtualbox! + end + + should "error and exit if VirtualBox is not installed or detected" do + Vagrant::Environment.expects(:error_and_exit).with(:virtualbox_not_detected).once + VirtualBox::Command.expects(:version).returns(nil) + Vagrant::Environment.check_virtualbox! + end + + should "error and exit if VirtualBox is lower than version 3.1" do + version = "3.0.12r1041" + Vagrant::Environment.expects(:error_and_exit).with(:virtualbox_invalid_version, :version => version.to_s).once + VirtualBox::Command.expects(:version).returns(version) + Vagrant::Environment.check_virtualbox! + end + + should "error and exit if the the vboxconfig is not set" do + VirtualBox::Global.expects(:vboxconfig?).returns(false) + Vagrant::Environment.expects(:error_and_exit).with(:virtualbox_xml_not_detected).once + Vagrant::Environment.check_virtualbox! + end + end + + context "class method load!" do + setup do + @cwd = mock('cwd') + + @env = mock('env') + @env.stubs(:load!).returns(@env) + end + + should "create the environment with given cwd, load it, and return it" do + Vagrant::Environment.expects(:new).with(@cwd).once.returns(@env) + @env.expects(:load!).returns(@env) + assert_equal @env, Vagrant::Environment.load!(@cwd) + end + + should "work without a given cwd" do + Vagrant::Environment.expects(:new).with(nil).returns(@env) + + assert_nothing_raised { + env = Vagrant::Environment.load! + assert_equal env, @env + } + end + end + + context "initialization" do + should "set the cwd if given" do + cwd = "foobarbaz" + env = Vagrant::Environment.new(cwd) + assert_equal cwd, env.cwd + end + + should "default to pwd if cwd is nil" do + env = Vagrant::Environment.new + assert_equal Dir.pwd, env.cwd + end + end + + context "paths" do + setup do + @env = mock_environment + end + + context "cwd" do + should "default to Dir.pwd" do + assert_equal Dir.pwd, @env.cwd + end + + should "return cwd if set" do + @env.cwd = "foo" + assert_equal "foo", @env.cwd + end + end + + context "dotfile path" do + setup do + @env.stubs(:root_path).returns("foo") + end + + should "build up the dotfile out of the root path and the dotfile name" do + assert_equal File.join(@env.root_path, @env.config.vagrant.dotfile_name), @env.dotfile_path + end + end + + context "home path" do + should "return nil if config is not yet loaded" do + @env.stubs(:config).returns(nil) + assert_nil @env.home_path + end + + should "return the home path if it loaded" do + assert_equal @env.config.vagrant.home, @env.home_path + end + end + + context "temp path" do + should "return the home path joined with 'tmp'" do + home_path = "foo" + @env.stubs(:home_path).returns(home_path) + assert_equal File.join("foo", "tmp"), @env.tmp_path + end + end + + context "boxes path" do + should "return the home path joined with 'tmp'" do + home_path = "foo" + @env.stubs(:home_path).returns(home_path) + assert_equal File.join("foo", "boxes"), @env.boxes_path + end + end + end + + context "loading" do + setup do + @env = mock_environment + end + + context "overall load method" do + should "load! should call proper sequence and return itself" do + call_seq = sequence("call_sequence") + @env.expects(:load_root_path!).once.in_sequence(call_seq) + @env.expects(:load_config!).once.in_sequence(call_seq) + @env.expects(:load_home_directory!).once.in_sequence(call_seq) + @env.expects(:load_box!).once.in_sequence(call_seq) + @env.expects(:load_config!).once.in_sequence(call_seq) + Vagrant::Environment.expects(:check_virtualbox!).once.in_sequence(call_seq) + @env.expects(:load_vm!).once.in_sequence(call_seq) + @env.expects(:load_ssh!).once.in_sequence(call_seq) + @env.expects(:load_active_list!).once.in_sequence(call_seq) + assert_equal @env, @env.load! + end + end + + context "loading the root path" do + setup do + @env.cwd = "/foo" + end + + should "default the path to the cwd instance var if nil" do + @path = mock("path") + @path.stubs(:root?).returns(true) + Pathname.expects(:new).with(@env.cwd).returns(@path) + @env.load_root_path!(nil) + end + + should "not default the path to pwd if its not nil" do + @path = mock("path") + @path.stubs(:to_s).returns("/") + File.expects(:expand_path).with(@path).returns("/") + Pathname.expects(:new).with("/").returns(@path) + @path.stubs(:root?).returns(true) + @env.load_root_path!(@path) + end + + should "should walk the parent directories looking for rootfile" do + paths = [ + Pathname.new("/foo/bar/baz"), + Pathname.new("/foo/bar"), + Pathname.new("/foo") + ] + + search_seq = sequence("search_seq") + paths.each do |path| + File.expects(:exist?).with("#{path}/#{Vagrant::Environment::ROOTFILE_NAME}").returns(false).in_sequence(search_seq) + end + + assert !@env.load_root_path!(paths.first) + end + + should "return false if not found" do + path = Pathname.new("/") + assert !@env.load_root_path!(path) + end + + should "return false if not found on windows-style root" do + # TODO: Is there _any_ way to test this on unix machines? The + # expand path doesn't work [properly for the test] on unix machines. + if RUBY_PLATFORM.downcase.include?("mswin") + # Note the escaped back slash + path = Pathname.new("C:\\") + assert !@env.load_root_path!(path) + end + end + + should "should set the path for the rootfile" do + path = "/foo" + File.expects(:exist?).with("#{path}/#{Vagrant::Environment::ROOTFILE_NAME}").returns(true) + + assert @env.load_root_path!(Pathname.new(path)) + assert_equal path, @env.root_path + end + end + + context "loading config" do + setup do + @root_path = "/foo" + @home_path = "/bar" + @env.stubs(:root_path).returns(@root_path) + @env.stubs(:home_path).returns(@home_path) + + File.stubs(:exist?).returns(false) + Vagrant::Config.stubs(:execute!) + Vagrant::Config.stubs(:reset!) + end + + should "reset the configuration object" do + Vagrant::Config.expects(:reset!).with(@env).once + @env.load_config! + end + + should "load from the project root" do + File.expects(:exist?).with(File.join(PROJECT_ROOT, "config", "default.rb")).once + @env.load_config! + end + + should "load from the root path" do + File.expects(:exist?).with(File.join(@root_path, Vagrant::Environment::ROOTFILE_NAME)).once + @env.load_config! + end + + should "not load from the root path if nil" do + @env.stubs(:root_path).returns(nil) + File.expects(:exist?).with(File.join(@root_path, Vagrant::Environment::ROOTFILE_NAME)).never + @env.load_config! + end + + should "load from the home directory" do + File.expects(:exist?).with(File.join(@env.home_path, Vagrant::Environment::ROOTFILE_NAME)).once + @env.load_config! + end + + should "not load from the home directory if the config is nil" do + @env.stubs(:home_path).returns(nil) + File.expects(:exist?).twice.returns(false) + @env.load_config! + end + + should "not load from the box directory if it is nil" do + @env.expects(:box).once.returns(nil) + File.expects(:exist?).twice.returns(false) + @env.load_config! + end + + should "load from the box directory if it is not nil" do + dir = "foo" + box = mock("box") + box.stubs(:directory).returns(dir) + @env.expects(:box).twice.returns(box) + File.expects(:exist?).with(File.join(dir, Vagrant::Environment::ROOTFILE_NAME)).once + @env.load_config! + end + + should "load the files only if exist? returns true" do + File.expects(:exist?).once.returns(true) + @env.expects(:load).once + @env.load_config! + end + + should "not load the files if exist? returns false" do + @env.expects(:load).never + @env.load_config! + end + + should "execute after loading and set result to environment config" do + result = mock("result") + File.expects(:exist?).once.returns(true) + @env.expects(:load).once + Vagrant::Config.expects(:execute!).once.returns(result) + @env.load_config! + assert_equal result, @env.config + end + end + + context "loading home directory" do + setup do + @env = mock_environment + @home_dir = File.expand_path(@env.config.vagrant.home) + + File.stubs(:directory?).returns(true) + FileUtils.stubs(:mkdir_p) + end + + should "create each directory if it doesn't exist" do + create_seq = sequence("create_seq") + File.stubs(:directory?).returns(false) + Vagrant::Environment::HOME_SUBDIRS.each do |subdir| + FileUtils.expects(:mkdir_p).with(File.join(@home_dir, subdir)).in_sequence(create_seq) + end + + @env.load_home_directory! + end + + should "not create directories if they exist" do + File.stubs(:directory?).returns(true) + FileUtils.expects(:mkdir_p).never + @env.load_home_directory! + end + end + + context "loading box" do + setup do + @box = mock("box") + @box.stubs(:env=) + + @env = mock_environment + @env.stubs(:root_path).returns("foo") + end + + should "do nothing if the root path is nil" do + Vagrant::Box.expects(:find).never + @env.stubs(:root_path).returns(nil) + @env.load_box! + end + + should "not load the box if its not set" do + @env = mock_environment do |config| + config.vm.box = nil + end + + Vagrant::Box.expects(:find).never + @env.load_box! + end + + should "set the box to what is found by the Box class" do + Vagrant::Box.expects(:find).with(@env, @env.config.vm.box).once.returns(@box) + @env.load_box! + assert @box.equal?(@env.box) + end + end + + context "loading the UUID out from the persisted dotfile" do + setup do + @env = mock_environment + @env.stubs(:root_path).returns("foo") + + File.stubs(:file?).returns(true) + end + + should "loading of the uuid from the dotfile" do + vm = mock("vm") + vm.expects(:env=).with(@env) + + filemock = mock("filemock") + filemock.expects(:read).returns("foo") + Vagrant::VM.expects(:find).with("foo").returns(vm) + File.expects(:open).with(@env.dotfile_path).once.yields(filemock) + File.expects(:file?).with(@env.dotfile_path).once.returns(true) + @env.load_vm! + + assert_equal vm, @env.vm + end + + should "not set the environment if the VM is nil" do + filemock = mock("filemock") + filemock.expects(:read).returns("foo") + Vagrant::VM.expects(:find).with("foo").returns(nil) + File.expects(:open).with(@env.dotfile_path).once.yields(filemock) + File.expects(:file?).with(@env.dotfile_path).once.returns(true) + + assert_nothing_raised { @env.load_vm! } + assert_nil @env.vm + end + + should "do nothing if the root path is nil" do + File.expects(:open).never + @env.stubs(:root_path).returns(nil) + @env.load_vm! + end + + should "do nothing if dotfile is not a file" do + File.expects(:file?).returns(false) + File.expects(:open).never + @env.load_vm! + end + + should "uuid should be nil if dotfile didn't exist" do + File.expects(:open).raises(Errno::ENOENT) + @env.load_vm! + assert_nil @env.vm + end + end + + context "loading SSH" do + setup do + @env = mock_environment + end + + should "initialize the SSH object with the given environment" do + ssh = mock("ssh") + Vagrant::SSH.expects(:new).with(@env).returns(ssh) + @env.load_ssh! + assert_equal ssh, @env.ssh + end + end + + context "loading the active list" do + setup do + @env = mock_environment + end + + should "initialize the ActiveList object with the given environment" do + active_list = mock("active_list") + Vagrant::ActiveList.expects(:new).with(@env).returns(active_list) + @env.load_active_list! + assert_equal active_list, @env.active_list + end + end + end + + context "requiring properties" do + setup do + @env = mock_environment + end + + context "requiring boxes" do + setup do + reconfig_environment + end + + def reconfig_environment + @env = mock_environment do |config| + yield config if block_given? + end + + @env.stubs(:require_root_path) + @env.stubs(:error_and_exit) + end + + should "require root path" do + @env.expects(:require_root_path).once + @env.require_box + end + + should "error and exit if no box is specified" do + reconfig_environment do |config| + config.vm.box = nil + end + + @env.expects(:box).returns(nil) + @env.expects(:error_and_exit).once.with(:box_not_specified) + @env.require_box + end + + should "error and exit if box is specified but doesn't exist" do + reconfig_environment do |config| + config.vm.box = "foo" + end + + @env.expects(:box).returns(nil) + @env.expects(:error_and_exit).once.with(:box_specified_doesnt_exist, :box_name => "foo") + @env.require_box + end + end + + context "requiring root_path" do + should "error and exit if no root_path is set" do + @env.expects(:root_path).returns(nil) + @env.expects(:error_and_exit).with(:rootfile_not_found).once + @env.require_root_path + end + + should "not error and exit if root_path is set" do + @env.expects(:root_path).returns("foo") + @env.expects(:error_and_exit).never + @env.require_root_path + end + end + + context "requiring a persisted VM" do + setup do + @env.stubs(:vm).returns("foo") + @env.stubs(:require_root_path) + end + + should "require a root path" do + @env.expects(:require_root_path).once + @env.expects(:error_and_exit).never + @env.require_persisted_vm + end + + should "error and exit if the VM is not set" do + @env.expects(:vm).returns(nil) + @env.expects(:error_and_exit).once + @env.require_persisted_vm + end + end + end + + context "managing VM" do + setup do + @env = mock_environment + + @dotfile_path = "foo" + @env.stubs(:dotfile_path).returns(@dotfile_path) + end + + def mock_vm + @vm = mock("vm") + @vm.stubs(:uuid).returns("foo") + @env.stubs(:vm).returns(@vm) + end + + context "creating a new VM" do + should "create a new VM" do + assert_nil @env.vm + @env.create_vm + assert !@env.vm.nil? + assert @env.vm.is_a?(Vagrant::VM) + end + + should "set the new VM's environment to the env" do + @env.create_vm + assert_equal @env, @env.vm.env + end + + should "return the new VM" do + result = @env.create_vm + assert result.is_a?(Vagrant::VM) + end + end + + context "persisting the VM into a file" do + setup do + mock_vm + + File.stubs(:open) + @env.active_list.stubs(:add) + end + + should "should save it to the dotfile path" do + filemock = mock("filemock") + filemock.expects(:write).with(@vm.uuid) + File.expects(:open).with(@env.dotfile_path, 'w+').once.yields(filemock) + @env.persist_vm + end + + should "add the VM to the activelist" do + @env.active_list.expects(:add).with(@vm) + @env.persist_vm + end + end + + context "depersisting the VM" do + setup do + mock_vm + + File.stubs(:exist?).returns(false) + File.stubs(:delete) + + @env.active_list.stubs(:remove) + end + + should "remove the dotfile if it exists" do + File.expects(:exist?).with(@env.dotfile_path).returns(true) + File.expects(:delete).with(@env.dotfile_path).once + @env.depersist_vm + end + + should "not remove the dotfile if it doesn't exist" do + File.expects(:exist?).returns(false) + File.expects(:delete).never + @env.depersist_vm + end + + should "remove from the active list" do + @env.active_list.expects(:remove).with(@vm) + @env.depersist_vm + end + end + end +end diff --git a/test/vagrant/provisioners/base_test.rb b/test/vagrant/provisioners/base_test.rb index 403665cc1..316d93cca 100644 --- a/test/vagrant/provisioners/base_test.rb +++ b/test/vagrant/provisioners/base_test.rb @@ -7,7 +7,13 @@ class BaseProvisionerTest < Test::Unit::TestCase context "base instance" do setup do - @base = Vagrant::Provisioners::Base.new + @env = mock_environment + @base = Vagrant::Provisioners::Base.new(@env) + end + + should "set the environment" do + base = Vagrant::Provisioners::Base.new(@env) + assert_equal @env, base.env end should "implement provision! which does nothing" do diff --git a/test/vagrant/provisioners/chef_server_test.rb b/test/vagrant/provisioners/chef_server_test.rb index 7212a3604..d2008dfab 100644 --- a/test/vagrant/provisioners/chef_server_test.rb +++ b/test/vagrant/provisioners/chef_server_test.rb @@ -2,10 +2,8 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper') class ChefServerProvisionerTest < Test::Unit::TestCase setup do - @action = Vagrant::Provisioners::ChefServer.new - - Vagrant::SSH.stubs(:execute) - Vagrant::SSH.stubs(:upload!) + @env = mock_environment + @action = Vagrant::Provisioners::ChefServer.new(@env) mock_config end @@ -29,56 +27,70 @@ class ChefServerProvisionerTest < Test::Unit::TestCase end should "not raise an exception if validation_key_path is set" do - mock_config do |config| + @env = mock_environment do |config| config.chef.validation_key_path = "7" end + @action.stubs(:env).returns(@env) + assert_nothing_raised { @action.prepare } end should "raise an exception if validation_key_path is nil" do - mock_config do |config| + @env = mock_environment do |config| config.chef.validation_key_path = nil end + @action.stubs(:env).returns(@env) + assert_raises(Vagrant::Actions::ActionException) { @action.prepare } end should "not raise an exception if validation_key_path does exist" do - mock_config do |config| + @env = mock_environment do |config| config.chef.validation_key_path = "7" end - File.expects(:file?).with(Vagrant.config.chef.validation_key_path).returns(true) + @action.stubs(:env).returns(@env) + @action.stubs(:validation_key_path).returns("9") + + File.expects(:file?).with(@action.validation_key_path).returns(true) assert_nothing_raised { @action.prepare } end should "raise an exception if validation_key_path doesn't exist" do - mock_config do |config| + @env = mock_environment do |config| config.chef.validation_key_path = "7" end - File.expects(:file?).with(Vagrant.config.chef.validation_key_path).returns(false) + @action.stubs(:env).returns(@env) + @action.stubs(:validation_key_path).returns("9") + + File.expects(:file?).with(@action.validation_key_path).returns(false) assert_raises(Vagrant::Actions::ActionException) { @action.prepare } end should "not raise an exception if chef_server_url is set" do - mock_config do |config| + @env = mock_environment do |config| config.chef.chef_server_url = "7" end + @action.stubs(:env).returns(@env) + assert_nothing_raised { @action.prepare } end should "raise an exception if chef_server_url is nil" do - mock_config do |config| + @env = mock_environment do |config| config.chef.chef_server_url = nil end + @action.stubs(:env).returns(@env) + assert_raises(Vagrant::Actions::ActionException) { @action.prepare } @@ -88,9 +100,7 @@ class ChefServerProvisionerTest < Test::Unit::TestCase context "creating the client key folder" do setup do @raw_path = "/foo/bar/baz.pem" - mock_config do |config| - config.chef.client_key_path = @raw_path - end + @env.config.chef.client_key_path = @raw_path @path = Pathname.new(@raw_path) end @@ -98,7 +108,7 @@ class ChefServerProvisionerTest < Test::Unit::TestCase should "create the folder using the dirname of the path" do ssh = mock("ssh") ssh.expects(:exec!).with("sudo mkdir -p #{@path.dirname}").once - Vagrant::SSH.expects(:execute).yields(ssh) + @env.ssh.expects(:execute).yields(ssh) @action.create_client_key_folder end end @@ -107,7 +117,7 @@ class ChefServerProvisionerTest < Test::Unit::TestCase should "upload the validation key to the provisioning path" do @action.expects(:validation_key_path).once.returns("foo") @action.expects(:guest_validation_key_path).once.returns("bar") - Vagrant::SSH.expects(:upload!).with("foo", "bar").once + @env.ssh.expects(:upload!).with("foo", "bar").once @action.upload_validation_key end end @@ -115,7 +125,7 @@ class ChefServerProvisionerTest < Test::Unit::TestCase context "the validation key path" do should "expand the configured key path" do result = mock("result") - File.expects(:expand_path).with(Vagrant.config.chef.validation_key_path, Vagrant::Env.root_path).once.returns(result) + File.expects(:expand_path).with(@env.config.chef.validation_key_path, @env.root_path).once.returns(result) assert_equal result, @action.validation_key_path end end @@ -123,7 +133,7 @@ class ChefServerProvisionerTest < Test::Unit::TestCase context "the guest validation key path" do should "be the provisioning path joined with validation.pem" do result = mock("result") - File.expects(:join).with(Vagrant.config.chef.provisioning_path, "validation.pem").once.returns(result) + File.expects(:join).with(@env.config.chef.provisioning_path, "validation.pem").once.returns(result) assert_equal result, @action.guest_validation_key_path end end @@ -131,6 +141,8 @@ class ChefServerProvisionerTest < Test::Unit::TestCase context "generating and uploading chef client configuration file" do setup do @action.stubs(:guest_validation_key_path).returns("foo") + + @env.ssh.stubs(:upload!) end should "upload properly generate the configuration file using configuration data" do @@ -138,11 +150,11 @@ class ChefServerProvisionerTest < Test::Unit::TestCase log_level :info log_location STDOUT ssl_verify_mode :verify_none -chef_server_url "#{Vagrant.config.chef.chef_server_url}" +chef_server_url "#{@env.config.chef.chef_server_url}" -validation_client_name "#{Vagrant.config.chef.validation_client_name}" +validation_client_name "#{@env.config.chef.validation_client_name}" validation_key "#{@action.guest_validation_key_path}" -client_key "#{Vagrant.config.chef.client_key_path}" +client_key "#{@env.config.chef.client_key_path}" file_store_path "/srv/chef/file_store" file_cache_path "/srv/chef/cache" @@ -158,8 +170,8 @@ config should "upload this file as client.rb to the provisioning folder" do StringIO.expects(:new).returns("foo") - File.expects(:join).with(Vagrant.config.chef.provisioning_path, "client.rb").once.returns("bar") - Vagrant::SSH.expects(:upload!).with("foo", "bar").once + File.expects(:join).with(@env.config.chef.provisioning_path, "client.rb").once.returns("bar") + @env.ssh.expects(:upload!).with("foo", "bar").once @action.setup_config end end @@ -167,8 +179,8 @@ config context "running chef client" do should "cd into the provisioning directory and run chef client" do ssh = mock("ssh") - ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-client -c client.rb -j dna.json").once - Vagrant::SSH.expects(:execute).yields(ssh) + ssh.expects(:exec!).with("cd #{@env.config.chef.provisioning_path} && sudo chef-client -c client.rb -j dna.json").once + @env.ssh.expects(:execute).yields(ssh) @action.run_chef_client end end diff --git a/test/vagrant/provisioners/chef_solo_test.rb b/test/vagrant/provisioners/chef_solo_test.rb index 9859ca771..2bc738e97 100644 --- a/test/vagrant/provisioners/chef_solo_test.rb +++ b/test/vagrant/provisioners/chef_solo_test.rb @@ -2,7 +2,8 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper') class ChefSoloProvisionerTest < Test::Unit::TestCase setup do - @action = Vagrant::Provisioners::ChefSolo.new + @env = mock_environment + @action = Vagrant::Provisioners::ChefSolo.new(@env) Vagrant::SSH.stubs(:execute) Vagrant::SSH.stubs(:upload!) @@ -37,7 +38,7 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase should "share each cookbook folder" do share_seq = sequence("share_seq") @host_cookbook_paths.each_with_index do |cookbook, i| - Vagrant.config.vm.expects(:share_folder).with("vagrant-chef-solo-#{i}", @action.cookbook_path(i), cookbook).in_sequence(share_seq) + @env.config.vm.expects(:share_folder).with("vagrant-chef-solo-#{i}", @action.cookbook_path(i), cookbook).in_sequence(share_seq) end @action.share_cookbook_folders @@ -45,38 +46,19 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase end context "host cookbooks paths" do - should "expand the path of the cookbooks relative to the environment root path" do - @cookbook = "foo" - @expanded = "bar" - File.expects(:expand_path).with(@cookbook, Vagrant::Env.root_path).returns(@expanded) - - mock_config do |config| - config.chef.cookbooks_path = @cookbook - end - - assert_equal [@expanded], @action.host_cookbook_paths - end - should "return as an array if was originally a string" do File.stubs(:expand_path).returns("foo") - - mock_config do |config| - config.chef.cookbooks_path = "foo" - end + @env.config.chef.cookbooks_path = "foo" assert_equal ["foo"], @action.host_cookbook_paths end should "return the array of cookbooks if its an array" do cookbooks = ["foo", "bar"] - mock_config do |config| - config.chef.cookbooks_path = cookbooks - end + @env.config.chef.cookbooks_path = cookbooks expand_seq = sequence('expand_seq') - cookbooks.each do |cookbook| - File.expects(:expand_path).with(cookbook, Vagrant::Env.root_path).returns(cookbook) - end + cookbooks.collect! { |cookbook| File.expand_path(cookbook, @env.root_path) } assert_equal cookbooks, @action.host_cookbook_paths end @@ -84,7 +66,7 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase context "cookbooks path" do should "return a proper path to a single cookbook" do - expected = File.join(Vagrant.config.chef.provisioning_path, "cookbooks-5") + expected = File.join(@env.config.chef.provisioning_path, "cookbooks-5") assert_equal expected, @action.cookbook_path(5) end @@ -93,28 +75,26 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase acc << @action.cookbook_path(i) end - mock_config do |config| - config.chef.cookbooks_path = @cookbooks - end - + @env.config.chef.cookbooks_path = @cookbooks assert_equal @cookbooks.to_json, @action.cookbooks_path end should "return a single string representation if cookbook paths is single" do @cookbooks = @action.cookbook_path(0) - mock_config do |config| - config.chef.cookbooks_path = @cookbooks - end - + @env.config.chef.cookbooks_path = @cookbooks assert_equal @cookbooks.to_json, @action.cookbooks_path end end context "generating and uploading chef solo configuration file" do + setup do + @env.ssh.stubs(:upload!) + end + should "upload properly generate the configuration file using configuration data" do expected_config = <<-config -file_cache_path "#{Vagrant.config.chef.provisioning_path}" +file_cache_path "#{@env.config.chef.provisioning_path}" cookbook_path #{@action.cookbooks_path} config @@ -125,8 +105,8 @@ config should "upload this file as solo.rb to the provisioning folder" do @action.expects(:cookbooks_path).returns("cookbooks") StringIO.expects(:new).returns("foo") - File.expects(:join).with(Vagrant.config.chef.provisioning_path, "solo.rb").once.returns("bar") - Vagrant::SSH.expects(:upload!).with("foo", "bar").once + File.expects(:join).with(@env.config.chef.provisioning_path, "solo.rb").once.returns("bar") + @env.ssh.expects(:upload!).with("foo", "bar").once @action.setup_solo_config end end @@ -134,8 +114,8 @@ config context "running chef solo" do should "cd into the provisioning directory and run chef solo" do ssh = mock("ssh") - ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json").once - Vagrant::SSH.expects(:execute).yields(ssh) + ssh.expects(:exec!).with("cd #{@env.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json").once + @env.ssh.expects(:execute).yields(ssh) @action.run_chef_solo end end diff --git a/test/vagrant/provisioners/chef_test.rb b/test/vagrant/provisioners/chef_test.rb index 916dabc46..8b3057a77 100644 --- a/test/vagrant/provisioners/chef_test.rb +++ b/test/vagrant/provisioners/chef_test.rb @@ -2,7 +2,8 @@ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper') class ChefProvisionerTest < Test::Unit::TestCase setup do - @action = Vagrant::Provisioners::Chef.new + @env = mock_environment + @action = Vagrant::Provisioners::Chef.new(@env) Vagrant::SSH.stubs(:execute) Vagrant::SSH.stubs(:upload!) @@ -69,16 +70,16 @@ class ChefProvisionerTest < Test::Unit::TestCase should "create and chown the folder to the ssh user" do ssh_seq = sequence("ssh_seq") ssh = mock("ssh") - ssh.expects(:exec!).with("sudo mkdir -p #{Vagrant.config.chef.provisioning_path}").once.in_sequence(ssh_seq) - ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}").once.in_sequence(ssh_seq) - Vagrant::SSH.expects(:execute).yields(ssh) + ssh.expects(:exec!).with("sudo mkdir -p #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq) + ssh.expects(:exec!).with("sudo chown #{@env.config.ssh.username} #{@env.config.chef.provisioning_path}").once.in_sequence(ssh_seq) + @env.ssh.expects(:execute).yields(ssh) @action.chown_provisioning_folder end end context "generating and uploading json" do def assert_json - Vagrant::SSH.expects(:upload!).with do |json, path| + @env.ssh.expects(:upload!).with do |json, path| data = JSON.parse(json.read) yield data true @@ -88,7 +89,7 @@ class ChefProvisionerTest < Test::Unit::TestCase end should "merge in the extra json specified in the config" do - Vagrant.config.chef.json = { :foo => "BAR" } + @env.config.chef.json = { :foo => "BAR" } assert_json do |data| assert_equal "BAR", data["foo"] end @@ -96,20 +97,20 @@ class ChefProvisionerTest < Test::Unit::TestCase should "add the directory as a special case to the JSON" do assert_json do |data| - assert_equal Vagrant.config.vm.project_directory, data["vagrant"]["directory"] + assert_equal @env.config.vm.project_directory, data["vagrant"]["directory"] end end should "add the config to the JSON" do assert_json do |data| - assert_equal Vagrant.config.vm.project_directory, data["vagrant"]["config"]["vm"]["project_directory"] + assert_equal @env.config.vm.project_directory, data["vagrant"]["config"]["vm"]["project_directory"] end end should "upload a StringIO to dna.json" do StringIO.expects(:new).with(anything).returns("bar") - File.expects(:join).with(Vagrant.config.chef.provisioning_path, "dna.json").once.returns("baz") - Vagrant::SSH.expects(:upload!).with("bar", "baz").once + File.expects(:join).with(@env.config.chef.provisioning_path, "dna.json").once.returns("baz") + @env.ssh.expects(:upload!).with("bar", "baz").once @action.setup_json end end diff --git a/test/vagrant/ssh_test.rb b/test/vagrant/ssh_test.rb index 50251e896..b20fb934e 100644 --- a/test/vagrant/ssh_test.rb +++ b/test/vagrant/ssh_test.rb @@ -5,139 +5,161 @@ class SshTest < Test::Unit::TestCase mock_config end - context "connecting to SSH" do + def mock_ssh + @env = mock_environment do |config| + yield config if block_given? + end + + @ssh = Vagrant::SSH.new(@env) + end + + context "connecting to external SSH" do setup do - Vagrant::SSH.stubs(:check_key_permissions) + mock_ssh + @ssh.stubs(:check_key_permissions) end should "check key permissions prior to exec" do exec_seq = sequence("exec_seq") - Vagrant::SSH.expects(:check_key_permissions).with(Vagrant.config.ssh.private_key_path).once.in_sequence(exec_seq) + @ssh.expects(:check_key_permissions).with(@env.config.ssh.private_key_path).once.in_sequence(exec_seq) Kernel.expects(:exec).in_sequence(exec_seq) - Vagrant::SSH.connect + @ssh.connect end should "call exec with defaults when no options are supplied" do - ssh = Vagrant.config.ssh - ssh_exec_expect(Vagrant::SSH.port, - Vagrant.config.ssh.private_key_path, - Vagrant.config.ssh.username, - Vagrant.config.ssh.host) - Vagrant::SSH.connect + ssh_exec_expect(@ssh.port, + @env.config.ssh.private_key_path, + @env.config.ssh.username, + @env.config.ssh.host) + @ssh.connect end should "call exec with supplied params" do args = {:username => 'bar', :private_key_path => 'baz', :host => 'bak', :port => 'bag'} ssh_exec_expect(args[:port], args[:private_key_path], args[:username], args[:host]) - Vagrant::SSH.connect(args) + @ssh.connect(args) end def ssh_exec_expect(port, key_path, uname, host) - Kernel.expects(:exec).with() do |arg| + Kernel.expects(:exec).with() do |arg| assert arg =~ /^ssh/ assert arg =~ /-p #{port}/ assert arg =~ /-i #{key_path}/ assert arg =~ /#{uname}@#{host}/ - # TODO options not tested for as they may be removed, they may be removed + # TODO options not tested for as they may be removed true end end end context "executing ssh commands" do + setup do + mock_ssh + end + should "call net::ssh.start with the proper names" do Net::SSH.expects(:start).once.with() do |host, username, opts| - assert_equal Vagrant.config.ssh.host, host - assert_equal Vagrant.config.ssh.username, username - assert_equal Vagrant::SSH.port, opts[:port] - assert_equal [Vagrant.config.ssh.private_key_path], opts[:keys] + assert_equal @env.config.ssh.host, host + assert_equal @env.config.ssh.username, username + assert_equal @ssh.port, opts[:port] + assert_equal [@env.config.ssh.private_key_path], opts[:keys] true end - Vagrant::SSH.execute + @ssh.execute end should "use custom host if set" do - Vagrant.config.ssh.host = "foo" - Net::SSH.expects(:start).with(Vagrant.config.ssh.host, Vagrant.config.ssh.username, anything).once - Vagrant::SSH.execute + @env.config.ssh.host = "foo" + Net::SSH.expects(:start).with(@env.config.ssh.host, @env.config.ssh.username, anything).once + @ssh.execute end end context "SCPing files to the remote host" do + setup do + mock_ssh + end + should "use Vagrant::SSH execute to setup an SCP connection and upload" do scp = mock("scp") ssh = mock("ssh") scp.expects(:upload!).with("foo", "bar").once Net::SCP.expects(:new).with(ssh).returns(scp).once - Vagrant::SSH.expects(:execute).yields(ssh).once - Vagrant::SSH.upload!("foo", "bar") + @ssh.expects(:execute).yields(ssh).once + @ssh.upload!("foo", "bar") end end context "checking if host is up" do setup do - mock_config + mock_ssh end should "return true if SSH connection works" do Net::SSH.expects(:start).yields("success") - assert Vagrant::SSH.up? + assert @ssh.up? end should "return false if SSH connection times out" do Net::SSH.expects(:start) - assert !Vagrant::SSH.up? + assert !@ssh.up? end should "allow the thread the configured timeout time" do @thread = mock("thread") @thread.stubs(:[]) Thread.expects(:new).returns(@thread) - @thread.expects(:join).with(Vagrant.config.ssh.timeout).once - Vagrant::SSH.up? + @thread.expects(:join).with(@env.config.ssh.timeout).once + @ssh.up? end should "return false if the connection is refused" do Net::SSH.expects(:start).raises(Errno::ECONNREFUSED) assert_nothing_raised { - assert !Vagrant::SSH.up? + assert !@ssh.up? } end should "return false if the connection is dropped" do Net::SSH.expects(:start).raises(Net::SSH::Disconnect) assert_nothing_raised { - assert !Vagrant::SSH.up? + assert !@ssh.up? } end should "specifity the timeout as an option to execute" do - Vagrant::SSH.expects(:execute).with(:timeout => Vagrant.config.ssh.timeout).yields(true) - assert Vagrant::SSH.up? + @ssh.expects(:execute).with(:timeout => @env.config.ssh.timeout).yields(true) + assert @ssh.up? end should "error and exit if a Net::SSH::AuthenticationFailed is raised" do - Vagrant::SSH.expects(:execute).raises(Net::SSH::AuthenticationFailed) - Vagrant::SSH.expects(:error_and_exit).with(:vm_ssh_auth_failed).once - Vagrant::SSH.up? + @ssh.expects(:execute).raises(Net::SSH::AuthenticationFailed) + @ssh.expects(:error_and_exit).with(:vm_ssh_auth_failed).once + @ssh.up? end end context "getting the ssh port" do + setup do + mock_ssh + end + should "return the configured port by default" do - assert_equal Vagrant.config.vm.forwarded_ports[Vagrant.config.ssh.forwarded_port_key][:hostport], Vagrant::SSH.port + assert_equal @env.config.vm.forwarded_ports[@env.config.ssh.forwarded_port_key][:hostport], @ssh.port end should "return the port given in options if it exists" do - assert_equal "47", Vagrant::SSH.port({ :port => "47" }) + assert_equal "47", @ssh.port({ :port => "47" }) end end context "checking key permissions" do setup do + mock_ssh + @ssh.stubs(:file_perms) + @key_path = "foo" - Vagrant::SSH.stubs(:file_perms) @stat = mock("stat") @stat.stubs(:owned?).returns(true) @@ -147,50 +169,54 @@ class SshTest < Test::Unit::TestCase should "do nothing if the user is not the owner" do @stat.expects(:owned?).returns(false) File.expects(:chmod).never - Vagrant::SSH.check_key_permissions(@key_path) + @ssh.check_key_permissions(@key_path) end should "do nothing if the file perms equal 600" do - Vagrant::SSH.expects(:file_perms).with(@key_path).returns("600") + @ssh.expects(:file_perms).with(@key_path).returns("600") File.expects(:chmod).never - Vagrant::SSH.check_key_permissions(@key_path) + @ssh.check_key_permissions(@key_path) end should "chmod the file if the file perms aren't 600" do perm_sequence = sequence("perm_seq") - Vagrant::SSH.expects(:file_perms).returns("900").in_sequence(perm_sequence) + @ssh.expects(:file_perms).returns("900").in_sequence(perm_sequence) File.expects(:chmod).with(0600, @key_path).once.in_sequence(perm_sequence) - Vagrant::SSH.expects(:file_perms).returns("600").in_sequence(perm_sequence) - Vagrant::SSH.expects(:error_and_exit).never - Vagrant::SSH.check_key_permissions(@key_path) + @ssh.expects(:file_perms).returns("600").in_sequence(perm_sequence) + @ssh.expects(:error_and_exit).never + @ssh.check_key_permissions(@key_path) end should "error and exit if the resulting chmod doesn't work" do perm_sequence = sequence("perm_seq") - Vagrant::SSH.expects(:file_perms).returns("900").in_sequence(perm_sequence) + @ssh.expects(:file_perms).returns("900").in_sequence(perm_sequence) File.expects(:chmod).with(0600, @key_path).once.in_sequence(perm_sequence) - Vagrant::SSH.expects(:file_perms).returns("900").in_sequence(perm_sequence) - Vagrant::SSH.expects(:error_and_exit).once.with(:ssh_bad_permissions, :key_path => @key_path).in_sequence(perm_sequence) - Vagrant::SSH.check_key_permissions(@key_path) + @ssh.expects(:file_perms).returns("900").in_sequence(perm_sequence) + @ssh.expects(:error_and_exit).once.with(:ssh_bad_permissions, :key_path => @key_path).in_sequence(perm_sequence) + @ssh.check_key_permissions(@key_path) end should "error and exit if a bad file perm is raised" do - Vagrant::SSH.expects(:file_perms).with(@key_path).returns("900") + @ssh.expects(:file_perms).with(@key_path).returns("900") File.expects(:chmod).raises(Errno::EPERM) - Vagrant::SSH.expects(:error_and_exit).once.with(:ssh_bad_permissions, :key_path => @key_path) - Vagrant::SSH.check_key_permissions(@key_path) + @ssh.expects(:error_and_exit).once.with(:ssh_bad_permissions, :key_path => @key_path) + @ssh.check_key_permissions(@key_path) end end context "getting file permissions" do + setup do + mock_ssh + end + should "return the last 3 characters of the file mode" do path = "foo" mode = "10000foo" stat = mock("stat") File.expects(:stat).with(path).returns(stat) stat.expects(:mode).returns(mode) - Vagrant::SSH.expects(:sprintf).with("%o", mode).returns(mode) - assert_equal path, Vagrant::SSH.file_perms(path) + @ssh.expects(:sprintf).with("%o", mode).returns(mode) + assert_equal path, @ssh.file_perms(path) end end end diff --git a/test/vagrant/vm_test.rb b/test/vagrant/vm_test.rb index e167e69d7..9d468eb05 100644 --- a/test/vagrant/vm_test.rb +++ b/test/vagrant/vm_test.rb @@ -6,7 +6,9 @@ class VMTest < Test::Unit::TestCase mock_config @persisted_vm = mock("persisted_vm") - Vagrant::Env.stubs(:persisted_vm).returns(@persisted_vm) + + @env = mock_environment + @env.stubs(:vm).returns(@persisted_vm) Net::SSH.stubs(:start) end