From 260f1dcec46101fef1bddfcaf9d8445a394bee4a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 3 Sep 2010 19:25:48 -0700 Subject: [PATCH] Refined some tests to use real Vagrantfiles instead of mocks --- bin/vagrant | 4 +- lib/vagrant.rb | 3 +- lib/vagrant/environment.rb | 21 +-- test/support/environment.rb | 37 +++++ test/support/path.rb | 8 ++ test/test_helper.rb | 33 ++--- test/vagrant/data_store_test.rb | 2 +- test/vagrant/environment_test.rb | 236 +++++++++++-------------------- 8 files changed, 152 insertions(+), 192 deletions(-) create mode 100644 test/support/environment.rb create mode 100644 test/support/path.rb diff --git a/bin/vagrant b/bin/vagrant index d8b765fd4..4533b46ab 100755 --- a/bin/vagrant +++ b/bin/vagrant @@ -2,10 +2,10 @@ require 'vagrant' require 'vagrant/cli' -env = Vagrant::Environment.load! +env = Vagrant::Environment.new begin - Vagrant::CLI.start(ARGV, :env => env) + Vagrant::CLI.start(ARGV, :env => env.load!) rescue Vagrant::Errors::VagrantError => e opts = { :_translate => false, :_prefix => false } env.ui.error e.message, opts if e.message diff --git a/lib/vagrant.rb b/lib/vagrant.rb index 588b34454..958992cc6 100644 --- a/lib/vagrant.rb +++ b/lib/vagrant.rb @@ -1,3 +1,4 @@ +require 'pathname' require 'json' require 'i18n' require 'virtualbox' @@ -23,7 +24,7 @@ module Vagrant # The source root is the path to the root directory of # the Vagrant gem. def self.source_root - @source_root ||= File.expand_path('../../', __FILE__) + @source_root ||= Pathname.new(File.expand_path('../../', __FILE__)) end end diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 5fdbfaa30..64c9782e4 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -23,16 +23,8 @@ module Vagrant # Class Methods #--------------------------------------------------------------- class << self - # Loads and returns an environment given a specific working - # directory. If a working directory is not given, it will default - # to the pwd. - def load!(cwd=nil) - Environment.new(:cwd => cwd).load! - end - # Verifies that VirtualBox is installed and that the version of - # VirtualBox installed is high enough. Also verifies that the - # configuration path is properly set. + # VirtualBox installed is high enough. def check_virtualbox! version = VirtualBox.version raise Errors::VirtualBoxNotDetected.new if version.nil? @@ -54,6 +46,8 @@ module Vagrant opts.each do |key, value| instance_variable_set("@#{key}".to_sym, opts[key]) end + + @loaded = false end #--------------------------------------------------------------- @@ -191,16 +185,23 @@ module Vagrant # Load Methods #--------------------------------------------------------------- + # Returns a boolean representing if the environment has been + # loaded or not. + def loaded? + !!@loaded + end + # 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! + self.class.check_virtualbox! load_config! load_home_directory! load_box! load_config! - self.class.check_virtualbox! load_vm! + @loaded = true self end diff --git a/test/support/environment.rb b/test/support/environment.rb new file mode 100644 index 000000000..29dcc99d6 --- /dev/null +++ b/test/support/environment.rb @@ -0,0 +1,37 @@ +require 'fileutils' + +module VagrantTestHelpers + module Environment + # Creates a "vagrant_app" directory in the test tmp folder + # which can be used for creating test Vagrant environments. + # Returns the root directory of the app. + def vagrant_app(*path) + root = tmp_path.join("vagrant_app") + FileUtils.rm_rf(root) + FileUtils.mkdir_p(root) + root.join(*path) + end + + # Creates a Vagrantfile with the given contents in the given + # app directory. + def vagrantfile(*args) + path = args.shift.join("Vagrantfile") if Pathname === args.first + path ||= vagrant_app("Vagrantfile") + str = args.shift || "" + File.open(path.to_s, "w") do |f| + f.puts "Vagrant::Config.run do |config|" + f.puts str + f.puts "end" + end + + path.parent + end + + # Creates and _loads_ a Vagrant environment at the given path + def vagrant_env(*args) + path = args.shift if Pathname === args.first + path ||= vagrantfile + Vagrant::Environment.new(:cwd => path).load! + end + end +end diff --git a/test/support/path.rb b/test/support/path.rb new file mode 100644 index 000000000..23749a78f --- /dev/null +++ b/test/support/path.rb @@ -0,0 +1,8 @@ +module VagrantTestHelpers + module Path + # Path to the tmp directory for the tests + def tmp_path + Vagrant.source_root.join("test", "tmp") + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index c197cc675..96b3351e2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,19 +1,19 @@ -# ruby-debug, not necessary, but useful if we have it -begin - require 'ruby-debug' -rescue LoadError; end - -require File.join(File.dirname(__FILE__), '..', 'lib', 'vagrant') -require 'contest' -require 'mocha' - # Add this folder to the load path for "test_helper" $:.unshift(File.dirname(__FILE__)) +require 'vagrant' +require 'contest' +require 'mocha' +require 'support/path' +require 'support/environment' + # Add the I18n locale for tests I18n.load_path << File.expand_path("../locales/en.yml", __FILE__) class Test::Unit::TestCase + include VagrantTestHelpers::Path + include VagrantTestHelpers::Environment + # Mocks an environment, setting it up with the given config. def mock_environment environment = Vagrant::Environment.new @@ -122,20 +122,5 @@ class Test::Unit::TestCase _, env = mock_action_data [downloader_klass.new(env), tempfile] end - - # Silences one or more streams for the duration of a block. - # This was taken from the facets library. - def silence_stream(*streams) #:yeild: - on_hold = streams.collect{ |stream| stream.dup } - streams.each do |stream| - stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') - stream.sync = true - end - yield - ensure - streams.each_with_index do |stream, i| - stream.reopen(on_hold[i]) - end - end end diff --git a/test/vagrant/data_store_test.rb b/test/vagrant/data_store_test.rb index 89addb959..221e4c914 100644 --- a/test/vagrant/data_store_test.rb +++ b/test/vagrant/data_store_test.rb @@ -4,7 +4,7 @@ class DataStoreTest < Test::Unit::TestCase setup do @klass = Vagrant::DataStore @initial_data = { "foo" => "bar" } - @db_file = File.expand_path("test/tmp/data_store_test", Vagrant.source_root) + @db_file = File.join(tmp_path, "data_store_test") File.open(@db_file, "w") { |f| f.write(@initial_data.to_json) } @instance = @klass.new(@db_file) diff --git a/test/vagrant/environment_test.rb b/test/vagrant/environment_test.rb index bb82c9b2a..d3f116bbb 100644 --- a/test/vagrant/environment_test.rb +++ b/test/vagrant/environment_test.rb @@ -33,30 +33,6 @@ class EnvironmentTest < Test::Unit::TestCase 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 - @klass.expects(:new).with(:cwd => @cwd).once.returns(@env) - @env.expects(:load!).returns(@env) - assert_equal @env, @klass.load!(@cwd) - end - - should "work without a given cwd" do - @klass.expects(:new).with(:cwd => nil).returns(@env) - - assert_nothing_raised { - env = @klass.load! - assert_equal env, @env - } - end - end - context "initialization" do should "set the cwd if given" do cwd = "foobarbaz" @@ -72,14 +48,10 @@ class EnvironmentTest < Test::Unit::TestCase context "paths" do setup do - @env = mock_environment + @env = vagrant_env 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 @@ -98,24 +70,20 @@ class EnvironmentTest < Test::Unit::TestCase 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 + assert_equal File.join(@env.home_path, "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 + assert_equal File.join(@env.home_path, "boxes"), @env.boxes_path end end end context "resource" do setup do - @env = mock_environment + @env = vagrant_env end should "return 'vagrant' as a default" do @@ -129,114 +97,76 @@ class EnvironmentTest < Test::Unit::TestCase end context "primary VM helper" do - setup do - @env = mock_environment - @env.stubs(:multivm?).returns(true) - end - should "return the first VM if not multivm" do - result = mock("result") - - @env.stubs(:multivm?).returns(false) - @env.stubs(:vms).returns({:default => result}) - - assert_equal result, @env.primary_vm + env = vagrant_env + assert_equal env.vms[@klass::DEFAULT_VM], env.primary_vm end should "call and return the primary VM from the parent if has one" do - result = mock("result") - parent = mock("parent") - parent.expects(:primary_vm).returns(result) + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define(:web, :primary => true) do; end + config.vm.define :db do; end + vf - @env.stubs(:parent).returns(parent) - assert_equal result, @env.primary_vm + assert_equal :web, env.primary_vm.name end should "return nil if no VM is marked as primary" do - @env.config.vm.define(:foo) - @env.config.vm.define(:bar) - @env.config.vm.define(:baz) + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define :web + config.vm.define :db + config.vm.define :utility + vf - assert @env.primary_vm.nil? - end - - should "return the primary VM" do - @env.config.vm.define(:foo) - @env.config.vm.define(:bar, :primary => true) - @env.config.vm.define(:baz) - - result = mock("result") - vms = { - :foo => :foo, - :bar => result, - :baz => :baz - } - @env.stubs(:vms).returns(vms) - - assert_equal result, @env.primary_vm + assert env.primary_vm.nil? end end context "multivm? helper" do - setup do - @env = mock_environment + should "return true if VM length greater than 1" do + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define :web + config.vm.define :db + vf + + assert env.multivm? end - context "with a parent" do - setup do - @parent = mock('parent') - @env.stubs(:parent).returns(@parent) - end + should "return false if VM length is 1" do + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define :web + vf - should "return the value of multivm? from the parent" do - result = mock("result") - @parent.stubs(:multivm?).returns(result) - assert_equal result, @env.multivm? - end - end - - context "without a parent" do - setup do - @env.stubs(:parent).returns(nil) - end - - should "return true if VM length greater than 1" do - @env.stubs(:vms).returns([1,2,3]) - assert @env.multivm? - end - - should "return false if VM length is 1" do - @env.stubs(:vms).returns([1]) - assert !@env.multivm? - end + assert !env.multivm? end end context "local data" do - setup do - @env = mock_environment - end - should "lazy load the data store only once" do - result = mock("result") - Vagrant::DataStore.expects(:new).with(@env.dotfile_path).returns(result).once - assert_equal result, @env.local_data - assert_equal result, @env.local_data - assert_equal result, @env.local_data + result = { :foo => :bar } + Vagrant::DataStore.expects(:new).returns(result).once + env = vagrant_env + assert_equal result, env.local_data + assert_equal result, env.local_data + assert_equal result, env.local_data end should "return the parent's local data if a parent exists" do - @env.stubs(:parent).returns(mock_environment) - result = @env.parent.local_data + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define :web + config.vm.define :db + vf + + env.local_data[:foo] = :bar Vagrant::DataStore.expects(:new).never - assert_equal result, @env.local_data + assert_equal :bar, env.vms[:web].env.local_data[:foo] end end context "accessing host" do setup do - @env = mock_environment + @env = vagrant_env end should "load the host once" do @@ -250,7 +180,7 @@ class EnvironmentTest < Test::Unit::TestCase context "accessing actions" do setup do - @env = mock_environment + @env = vagrant_env end should "initialize the Action object with the given environment" do @@ -263,24 +193,25 @@ class EnvironmentTest < Test::Unit::TestCase end context "global data" do - setup do - @env = mock_environment - end - should "lazy load the data store only once" do - result = mock("result") - Vagrant::DataStore.expects(:new).with(File.expand_path("global_data.json", @env.home_path)).returns(result).once - assert_equal result, @env.global_data - assert_equal result, @env.global_data - assert_equal result, @env.global_data + env = vagrant_env + store = env.global_data + + assert env.global_data.equal?(store) + assert env.global_data.equal?(store) + assert env.global_data.equal?(store) end should "return the parent's local data if a parent exists" do - @env.stubs(:parent).returns(mock_environment) - result = @env.parent.global_data + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define :web + config.vm.define :db + vf + + result = env.global_data Vagrant::DataStore.expects(:new).never - assert_equal result, @env.global_data + assert env.vms[:web].env.global_data.equal?(result) end end @@ -288,28 +219,26 @@ class EnvironmentTest < Test::Unit::TestCase should "lazy load the logger only once" do result = Vagrant::Util::ResourceLogger.new("vagrant", mock_environment) Vagrant::Util::ResourceLogger.expects(:new).returns(result).once - @env = mock_environment - assert_equal result, @env.logger - assert_equal result, @env.logger - assert_equal result, @env.logger + env = vagrant_env + assert_equal result, env.logger + assert_equal result, env.logger + assert_equal result, env.logger end - should "return the parent's local data if a parent exists" do - @env = mock_environment - @env.stubs(:parent).returns(mock_environment) - result = @env.parent.logger + should "return the parent's logger if a parent exists" do + env = vagrant_env(vagrantfile(<<-vf)) + config.vm.define :web + config.vm.define :db + vf + + result = env.logger Vagrant::Util::ResourceLogger.expects(:new).never - assert_equal result, @env.logger + assert env.vms[:web].env.logger.equal?(result) end end context "loading the root path" do - setup do - @env = mock_environment - @env.stubs(:cwd).returns("/foo") - end - should "should walk the parent directories looking for rootfile" do paths = [Pathname.new("/foo/bar/baz"), Pathname.new("/foo/bar"), @@ -322,32 +251,32 @@ class EnvironmentTest < Test::Unit::TestCase File.expects(:exist?).with(File.join(path.to_s, @klass::ROOTFILE_NAME)).returns(false).in_sequence(search_seq) end - @env.stubs(:cwd).returns(paths.first.to_s) - assert !@env.root_path + assert !@klass.new(:cwd => paths.first).root_path end should "should set the path for the rootfile" do path = File.expand_path("/foo") - @env.stubs(:cwd).returns(path) File.expects(:exist?).with(File.join(path, @klass::ROOTFILE_NAME)).returns(true) - assert_equal path, @env.root_path + assert_equal path, @klass.new(:cwd => path).root_path end should "only load the root path once" do - File.expects(:exist?).with(File.join(@env.cwd, @klass::ROOTFILE_NAME)).returns(true).once + env = @klass.new + File.expects(:exist?).with(File.join(env.cwd, @klass::ROOTFILE_NAME)).returns(true).once - assert_equal @env.cwd, @env.root_path - assert_equal @env.cwd, @env.root_path - assert_equal @env.cwd, @env.root_path + assert_equal env.cwd, env.root_path + assert_equal env.cwd, env.root_path + assert_equal env.cwd, env.root_path end should "only load the root path once even if nil" do - File.expects(:exist?).twice.returns(false) + File.stubs(:exist?).returns(false) - assert @env.root_path.nil? - assert @env.root_path.nil? - assert @env.root_path.nil? + env = @klass.new + assert env.root_path.nil? + assert env.root_path.nil? + assert env.root_path.nil? end end @@ -359,11 +288,11 @@ class EnvironmentTest < Test::Unit::TestCase context "overall load method" do should "load! should call proper sequence and return itself" do call_seq = sequence("call_sequence") + @klass.expects(:check_virtualbox!).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) - @klass.expects(:check_virtualbox!).once.in_sequence(call_seq) @env.expects(:load_vm!).once.in_sequence(call_seq) assert_equal @env, @env.load! end @@ -577,6 +506,5 @@ class EnvironmentTest < Test::Unit::TestCase assert !@env.vms.values.first.created? end end - end end