diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 684f4d2c1..1ebca525d 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -4,11 +4,28 @@ module Vagrant # storing references to the various instances. class Environment ROOTFILE_NAME = "Vagrantfile" + HOME_SUBDIRS = ["tmp", "boxes"] include Util attr_reader :root_path attr_reader :config + attr_reader :box + attr_reader :vm + + #--------------------------------------------------------------- + # Path Helpers + #--------------------------------------------------------------- + + # 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 + + #--------------------------------------------------------------- + # Load Methods + #--------------------------------------------------------------- # Loads this environment's configuration and stores it in the {config} # variable. The configuration loaded by this method is specified to @@ -33,5 +50,41 @@ module Vagrant # 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! + home_path = File.expand_path(config.vagrant.home) + + # 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(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) + end + rescue Errno::ENOENT + @vm = nil + end end end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 9196b3aba..2c5a7db70 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -18,6 +18,59 @@ require 'contest' require 'mocha' class Test::Unit::TestCase + # Mocks an environment, setting it up with the given config. + def mock_environment + Vagrant::Config.reset! + + 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 = Vagrant::Environment.new + environment.instance_variable_set(:@config, config) + environment + end + # Clears the previous config and sets up the new config def mock_config Vagrant::Config.reset! diff --git a/test/vagrant/environment_test.rb b/test/vagrant/environment_test.rb index 5b8b94fc4..a280cca8b 100644 --- a/test/vagrant/environment_test.rb +++ b/test/vagrant/environment_test.rb @@ -1,10 +1,26 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper') -class EnvTest < Test::Unit::TestCase +class EnvironmentTest < Test::Unit::TestCase setup do mock_config end + context "paths" do + setup do + @env = mock_environment + 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 + end + context "loading config" do setup do @root_path = "/foo" @@ -57,4 +73,100 @@ class EnvTest < Test::Unit::TestCase 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::Env::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") + + @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.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") + + 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 "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 end