From 047c094e41e0a5e322c4dafa149dd471bf6d88d7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 18 Mar 2010 14:43:17 -0700 Subject: [PATCH] Environment#load! implemented to set up an instance of environment --- lib/vagrant/environment.rb | 40 ++++ test/vagrant/environment_test.rb | 340 +++++++++++++++++++------------ 2 files changed, 255 insertions(+), 125 deletions(-) diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 1ebca525d..36845f2ad 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -8,6 +8,7 @@ module Vagrant include Util + attr_accessor :cwd attr_reader :root_path attr_reader :config attr_reader :box @@ -17,6 +18,14 @@ module Vagrant # 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 @@ -27,6 +36,37 @@ module Vagrant # 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! + load_vm! + 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 diff --git a/test/vagrant/environment_test.rb b/test/vagrant/environment_test.rb index a280cca8b..6418f831c 100644 --- a/test/vagrant/environment_test.rb +++ b/test/vagrant/environment_test.rb @@ -10,6 +10,17 @@ class EnvironmentTest < Test::Unit::TestCase @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") @@ -21,152 +32,231 @@ class EnvironmentTest < Test::Unit::TestCase end end - context "loading config" do - setup do - @root_path = "/foo" - @env = Vagrant::Environment.new - @env.stubs(:root_path).returns(@root_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!).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 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 + context "loading" 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) + context "overall load method" do + should "load! should load the config and set the persisted_uid" 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) + @env.expects(:load_vm!).once.in_sequence(call_seq) + @env.load! + end + end + + context "loading the root path" do + setup do + @env.cwd = "/foo" 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 + 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 - Vagrant::Box.expects(:find).never - @env.load_box! + 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::Env::ROOTFILE_NAME}").returns(true) + + assert Vagrant::Env.load_root_path!(Pathname.new(path)) + assert_equal path, Vagrant::Env.root_path + end 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 config" do + setup do + @root_path = "/foo" + @env = Vagrant::Environment.new + @env.stubs(:root_path).returns(@root_path) - context "loading the UUID out from the persisted dotfile" do - setup do - @env = mock_environment - @env.stubs(:root_path).returns("foo") + File.stubs(:exist?).returns(false) + Vagrant::Config.stubs(:execute!) + Vagrant::Config.stubs(:reset!) + end - File.stubs(:file?).returns(true) + should "reset the configuration object" do + Vagrant::Config.expects(:reset!).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 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 - should "loading of the uuid from the dotfile" do - vm = mock("vm") + context "loading home directory" do + setup do + @env = mock_environment + @home_dir = File.expand_path(@env.config.vagrant.home) - 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! + File.stubs(:directory?).returns(true) + FileUtils.stubs(:mkdir_p) + end - assert_equal vm, @env.vm + 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 - should "do nothing if the root path is nil" do - File.expects(:open).never - @env.stubs(:root_path).returns(nil) - @env.load_vm! + 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 - should "do nothing if dotfile is not a file" do - File.expects(:file?).returns(false) - File.expects(:open).never - @env.load_vm! - end + context "loading the UUID out from the persisted dotfile" do + setup do + @env = mock_environment + @env.stubs(:root_path).returns("foo") - should "uuid should be nil if dotfile didn't exist" do - File.expects(:open).raises(Errno::ENOENT) - @env.load_vm! - assert_nil @env.vm + 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 end