Refined some tests to use real Vagrantfiles instead of mocks

This commit is contained in:
Mitchell Hashimoto 2010-09-03 19:25:48 -07:00
parent 3470d98fca
commit 260f1dcec4
8 changed files with 152 additions and 192 deletions

View File

@ -2,10 +2,10 @@
require 'vagrant' require 'vagrant'
require 'vagrant/cli' require 'vagrant/cli'
env = Vagrant::Environment.load! env = Vagrant::Environment.new
begin begin
Vagrant::CLI.start(ARGV, :env => env) Vagrant::CLI.start(ARGV, :env => env.load!)
rescue Vagrant::Errors::VagrantError => e rescue Vagrant::Errors::VagrantError => e
opts = { :_translate => false, :_prefix => false } opts = { :_translate => false, :_prefix => false }
env.ui.error e.message, opts if e.message env.ui.error e.message, opts if e.message

View File

@ -1,3 +1,4 @@
require 'pathname'
require 'json' require 'json'
require 'i18n' require 'i18n'
require 'virtualbox' require 'virtualbox'
@ -23,7 +24,7 @@ module Vagrant
# The source root is the path to the root directory of # The source root is the path to the root directory of
# the Vagrant gem. # the Vagrant gem.
def self.source_root def self.source_root
@source_root ||= File.expand_path('../../', __FILE__) @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
end end
end end

View File

@ -23,16 +23,8 @@ module Vagrant
# Class Methods # Class Methods
#--------------------------------------------------------------- #---------------------------------------------------------------
class << self 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 # Verifies that VirtualBox is installed and that the version of
# VirtualBox installed is high enough. Also verifies that the # VirtualBox installed is high enough.
# configuration path is properly set.
def check_virtualbox! def check_virtualbox!
version = VirtualBox.version version = VirtualBox.version
raise Errors::VirtualBoxNotDetected.new if version.nil? raise Errors::VirtualBoxNotDetected.new if version.nil?
@ -54,6 +46,8 @@ module Vagrant
opts.each do |key, value| opts.each do |key, value|
instance_variable_set("@#{key}".to_sym, opts[key]) instance_variable_set("@#{key}".to_sym, opts[key])
end end
@loaded = false
end end
#--------------------------------------------------------------- #---------------------------------------------------------------
@ -191,16 +185,23 @@ module Vagrant
# Load Methods # 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 # Loads this entire environment, setting up the instance variables
# such as `vm`, `config`, etc. on this environment. The order this # such as `vm`, `config`, etc. on this environment. The order this
# method calls its other methods is very particular. # method calls its other methods is very particular.
def load! def load!
self.class.check_virtualbox!
load_config! load_config!
load_home_directory! load_home_directory!
load_box! load_box!
load_config! load_config!
self.class.check_virtualbox!
load_vm! load_vm!
@loaded = true
self self
end end

View File

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

8
test/support/path.rb Normal file
View File

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

View File

@ -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" # Add this folder to the load path for "test_helper"
$:.unshift(File.dirname(__FILE__)) $:.unshift(File.dirname(__FILE__))
require 'vagrant'
require 'contest'
require 'mocha'
require 'support/path'
require 'support/environment'
# Add the I18n locale for tests # Add the I18n locale for tests
I18n.load_path << File.expand_path("../locales/en.yml", __FILE__) I18n.load_path << File.expand_path("../locales/en.yml", __FILE__)
class Test::Unit::TestCase class Test::Unit::TestCase
include VagrantTestHelpers::Path
include VagrantTestHelpers::Environment
# Mocks an environment, setting it up with the given config. # Mocks an environment, setting it up with the given config.
def mock_environment def mock_environment
environment = Vagrant::Environment.new environment = Vagrant::Environment.new
@ -122,20 +122,5 @@ class Test::Unit::TestCase
_, env = mock_action_data _, env = mock_action_data
[downloader_klass.new(env), tempfile] [downloader_klass.new(env), tempfile]
end 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 end

View File

@ -4,7 +4,7 @@ class DataStoreTest < Test::Unit::TestCase
setup do setup do
@klass = Vagrant::DataStore @klass = Vagrant::DataStore
@initial_data = { "foo" => "bar" } @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) } File.open(@db_file, "w") { |f| f.write(@initial_data.to_json) }
@instance = @klass.new(@db_file) @instance = @klass.new(@db_file)

View File

@ -33,30 +33,6 @@ class EnvironmentTest < Test::Unit::TestCase
end end
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 context "initialization" do
should "set the cwd if given" do should "set the cwd if given" do
cwd = "foobarbaz" cwd = "foobarbaz"
@ -72,14 +48,10 @@ class EnvironmentTest < Test::Unit::TestCase
context "paths" do context "paths" do
setup do setup do
@env = mock_environment @env = vagrant_env
end end
context "dotfile path" do 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 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 assert_equal File.join(@env.root_path, @env.config.vagrant.dotfile_name), @env.dotfile_path
end end
@ -98,24 +70,20 @@ class EnvironmentTest < Test::Unit::TestCase
context "temp path" do context "temp path" do
should "return the home path joined with 'tmp'" do should "return the home path joined with 'tmp'" do
home_path = "foo" assert_equal File.join(@env.home_path, "tmp"), @env.tmp_path
@env.stubs(:home_path).returns(home_path)
assert_equal File.join("foo", "tmp"), @env.tmp_path
end end
end end
context "boxes path" do context "boxes path" do
should "return the home path joined with 'tmp'" do should "return the home path joined with 'tmp'" do
home_path = "foo" assert_equal File.join(@env.home_path, "boxes"), @env.boxes_path
@env.stubs(:home_path).returns(home_path)
assert_equal File.join("foo", "boxes"), @env.boxes_path
end end
end end
end end
context "resource" do context "resource" do
setup do setup do
@env = mock_environment @env = vagrant_env
end end
should "return 'vagrant' as a default" do should "return 'vagrant' as a default" do
@ -129,114 +97,76 @@ class EnvironmentTest < Test::Unit::TestCase
end end
context "primary VM helper" do 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 should "return the first VM if not multivm" do
result = mock("result") env = vagrant_env
assert_equal env.vms[@klass::DEFAULT_VM], env.primary_vm
@env.stubs(:multivm?).returns(false)
@env.stubs(:vms).returns({:default => result})
assert_equal result, @env.primary_vm
end end
should "call and return the primary VM from the parent if has one" do should "call and return the primary VM from the parent if has one" do
result = mock("result") env = vagrant_env(vagrantfile(<<-vf))
parent = mock("parent") config.vm.define(:web, :primary => true) do; end
parent.expects(:primary_vm).returns(result) config.vm.define :db do; end
vf
@env.stubs(:parent).returns(parent) assert_equal :web, env.primary_vm.name
assert_equal result, @env.primary_vm
end end
should "return nil if no VM is marked as primary" do should "return nil if no VM is marked as primary" do
@env.config.vm.define(:foo) env = vagrant_env(vagrantfile(<<-vf))
@env.config.vm.define(:bar) config.vm.define :web
@env.config.vm.define(:baz) config.vm.define :db
config.vm.define :utility
vf
assert @env.primary_vm.nil? 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
end end
end end
context "multivm? helper" do context "multivm? helper" do
setup do
@env = mock_environment
end
context "with a parent" do
setup do
@parent = mock('parent')
@env.stubs(:parent).returns(@parent)
end
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 should "return true if VM length greater than 1" do
@env.stubs(:vms).returns([1,2,3]) env = vagrant_env(vagrantfile(<<-vf))
assert @env.multivm? config.vm.define :web
config.vm.define :db
vf
assert env.multivm?
end end
should "return false if VM length is 1" do should "return false if VM length is 1" do
@env.stubs(:vms).returns([1]) env = vagrant_env(vagrantfile(<<-vf))
assert !@env.multivm? config.vm.define :web
end vf
assert !env.multivm?
end end
end end
context "local data" do context "local data" do
setup do
@env = mock_environment
end
should "lazy load the data store only once" do should "lazy load the data store only once" do
result = mock("result") result = { :foo => :bar }
Vagrant::DataStore.expects(:new).with(@env.dotfile_path).returns(result).once Vagrant::DataStore.expects(:new).returns(result).once
assert_equal result, @env.local_data env = vagrant_env
assert_equal result, @env.local_data assert_equal result, env.local_data
assert_equal result, @env.local_data assert_equal result, env.local_data
assert_equal result, env.local_data
end end
should "return the parent's local data if a parent exists" do should "return the parent's local data if a parent exists" do
@env.stubs(:parent).returns(mock_environment) env = vagrant_env(vagrantfile(<<-vf))
result = @env.parent.local_data config.vm.define :web
config.vm.define :db
vf
env.local_data[:foo] = :bar
Vagrant::DataStore.expects(:new).never Vagrant::DataStore.expects(:new).never
assert_equal result, @env.local_data assert_equal :bar, env.vms[:web].env.local_data[:foo]
end end
end end
context "accessing host" do context "accessing host" do
setup do setup do
@env = mock_environment @env = vagrant_env
end end
should "load the host once" do should "load the host once" do
@ -250,7 +180,7 @@ class EnvironmentTest < Test::Unit::TestCase
context "accessing actions" do context "accessing actions" do
setup do setup do
@env = mock_environment @env = vagrant_env
end end
should "initialize the Action object with the given environment" do should "initialize the Action object with the given environment" do
@ -263,24 +193,25 @@ class EnvironmentTest < Test::Unit::TestCase
end end
context "global data" do context "global data" do
setup do
@env = mock_environment
end
should "lazy load the data store only once" do should "lazy load the data store only once" do
result = mock("result") env = vagrant_env
Vagrant::DataStore.expects(:new).with(File.expand_path("global_data.json", @env.home_path)).returns(result).once store = env.global_data
assert_equal result, @env.global_data
assert_equal result, @env.global_data assert env.global_data.equal?(store)
assert_equal result, @env.global_data assert env.global_data.equal?(store)
assert env.global_data.equal?(store)
end end
should "return the parent's local data if a parent exists" do should "return the parent's local data if a parent exists" do
@env.stubs(:parent).returns(mock_environment) env = vagrant_env(vagrantfile(<<-vf))
result = @env.parent.global_data config.vm.define :web
config.vm.define :db
vf
result = env.global_data
Vagrant::DataStore.expects(:new).never Vagrant::DataStore.expects(:new).never
assert_equal result, @env.global_data assert env.vms[:web].env.global_data.equal?(result)
end end
end end
@ -288,28 +219,26 @@ class EnvironmentTest < Test::Unit::TestCase
should "lazy load the logger only once" do should "lazy load the logger only once" do
result = Vagrant::Util::ResourceLogger.new("vagrant", mock_environment) result = Vagrant::Util::ResourceLogger.new("vagrant", mock_environment)
Vagrant::Util::ResourceLogger.expects(:new).returns(result).once Vagrant::Util::ResourceLogger.expects(:new).returns(result).once
@env = mock_environment env = vagrant_env
assert_equal result, @env.logger assert_equal result, env.logger
assert_equal result, @env.logger assert_equal result, env.logger
assert_equal result, @env.logger assert_equal result, env.logger
end end
should "return the parent's local data if a parent exists" do should "return the parent's logger if a parent exists" do
@env = mock_environment env = vagrant_env(vagrantfile(<<-vf))
@env.stubs(:parent).returns(mock_environment) config.vm.define :web
result = @env.parent.logger config.vm.define :db
vf
result = env.logger
Vagrant::Util::ResourceLogger.expects(:new).never Vagrant::Util::ResourceLogger.expects(:new).never
assert_equal result, @env.logger assert env.vms[:web].env.logger.equal?(result)
end end
end end
context "loading the root path" do 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 should "should walk the parent directories looking for rootfile" do
paths = [Pathname.new("/foo/bar/baz"), paths = [Pathname.new("/foo/bar/baz"),
Pathname.new("/foo/bar"), 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) File.expects(:exist?).with(File.join(path.to_s, @klass::ROOTFILE_NAME)).returns(false).in_sequence(search_seq)
end end
@env.stubs(:cwd).returns(paths.first.to_s) assert !@klass.new(:cwd => paths.first).root_path
assert !@env.root_path
end end
should "should set the path for the rootfile" do should "should set the path for the rootfile" do
path = File.expand_path("/foo") path = File.expand_path("/foo")
@env.stubs(:cwd).returns(path)
File.expects(:exist?).with(File.join(path, @klass::ROOTFILE_NAME)).returns(true) 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 end
should "only load the root path once" do 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 end
should "only load the root path once even if nil" do 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? env = @klass.new
assert @env.root_path.nil? assert env.root_path.nil?
assert @env.root_path.nil? assert env.root_path.nil?
assert env.root_path.nil?
end end
end end
@ -359,11 +288,11 @@ class EnvironmentTest < Test::Unit::TestCase
context "overall load method" do context "overall load method" do
should "load! should call proper sequence and return itself" do should "load! should call proper sequence and return itself" do
call_seq = sequence("call_sequence") 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_config!).once.in_sequence(call_seq)
@env.expects(:load_home_directory!).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_box!).once.in_sequence(call_seq)
@env.expects(:load_config!).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) @env.expects(:load_vm!).once.in_sequence(call_seq)
assert_equal @env, @env.load! assert_equal @env, @env.load!
end end
@ -577,6 +506,5 @@ class EnvironmentTest < Test::Unit::TestCase
assert !@env.vms.values.first.created? assert !@env.vms.values.first.created?
end end
end end
end end
end end