From 52f3847b0af83f42cfb9eb3f0ba0c510c0923c06 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 3 Apr 2013 21:47:57 -0700 Subject: [PATCH] Laying the foundation for the new guest plugin --- lib/vagrant/errors.rb | 4 ++ lib/vagrant/guest.rb | 101 ++++++++++++++++++++++++++++ lib/vagrant/machine.rb | 28 +------- lib/vagrant/plugin/v2/components.rb | 6 ++ lib/vagrant/plugin/v2/guest.rb | 40 ++++------- lib/vagrant/plugin/v2/manager.rb | 2 +- lib/vagrant/plugin/v2/plugin.rb | 15 ++--- plugins/guests/arch/guest.rb | 4 ++ plugins/guests/arch/plugin.rb | 2 +- plugins/guests/debian/guest.rb | 4 ++ plugins/guests/debian/plugin.rb | 2 +- plugins/guests/fedora/guest.rb | 4 ++ plugins/guests/fedora/plugin.rb | 2 +- plugins/guests/freebsd/guest.rb | 5 ++ plugins/guests/gentoo/guest.rb | 4 ++ plugins/guests/gentoo/plugin.rb | 2 +- plugins/guests/linux/guest.rb | 5 ++ plugins/guests/openbsd/guest.rb | 5 ++ plugins/guests/openbsd/plugin.rb | 2 +- plugins/guests/pld/guest.rb | 4 ++ plugins/guests/pld/plugin.rb | 2 +- plugins/guests/redhat/guest.rb | 4 ++ plugins/guests/redhat/plugin.rb | 2 +- plugins/guests/solaris/guest.rb | 4 ++ plugins/guests/suse/guest.rb | 4 ++ plugins/guests/suse/plugin.rb | 2 +- plugins/guests/ubuntu/guest.rb | 4 ++ plugins/guests/ubuntu/plugin.rb | 2 +- templates/locales/en.yml | 18 ++--- test/unit/vagrant/guest_test.rb | 75 +++++++++++++++++++++ test/unit/vagrant/machine_test.rb | 55 ++------------- 31 files changed, 281 insertions(+), 132 deletions(-) create mode 100644 lib/vagrant/guest.rb create mode 100644 test/unit/vagrant/guest_test.rb diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 084d66c84..9db88ceb6 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -227,6 +227,10 @@ module Vagrant error_key(:port_collision_resume) end + class GuestNotDetected < VagrantError + error_key(:guest_not_detected) + end + class LocalDataDirectoryNotAccessible < VagrantError error_key(:local_data_dir_not_accessible) end diff --git a/lib/vagrant/guest.rb b/lib/vagrant/guest.rb new file mode 100644 index 000000000..52dcd3e21 --- /dev/null +++ b/lib/vagrant/guest.rb @@ -0,0 +1,101 @@ +require "log4r" + +module Vagrant + # This class handles guest-OS specific interactions with a machine. + # It is primarily responsible for detecting the proper guest OS + # implementation and then delegating capabilities. + # + # Vagrant has many tasks which require specific guest OS knowledge. + # These are implemented using a guest/capability system. Various plugins + # register as "guests" which determine the underlying OS of the system. + # Then, "guest capabilities" register themselves for a specific OS (one + # or more), and these capabilities are called. + # + # Example capabilities might be "mount_virtualbox_shared_folder" or + # "configure_networks". + # + # This system allows for maximum flexibility and pluginability for doing + # guest OS specific operations. + class Guest + attr_reader :chain + + def initialize(machine, guests) + @logger = Log4r::Logger.new("vagrant::guest") + @chain = [] + @guests = guests + @machine = machine + end + + # This will detect the proper guest OS for the machine and set up + # the class to actually execute capabilities. + def detect! + @logger.info("Detect guest for machine: #{@machine}") + + # Get the mapping of guests with the most parents. We start searching + # with the guests with the most parents first. + parent_count = {} + @guests.each do |name, parts| + parent_count[name] = 0 + + parent = parts[1] + while parent + parent_count[name] += 1 + parent = @guests[parent] + parent = parent[1] if parent + end + end + + # Now swap around the mapping so that it is a mapping of + # count to the actual list of guest names + parent_count_to_guests = {} + parent_count.each do |name, count| + parent_count_to_guests[count] ||= [] + parent_count_to_guests[count] << name + end + + catch(:guest_os) do + sorted_counts = parent_count_to_guests.keys.sort.reverse + sorted_counts.each do |count| + parent_count_to_guests[count].each do |name| + @logger.debug("Trying: #{name}") + guest_info = @guests[name] + guest = guest_info[0].new + + if guest.detect?(@machine) + @logger.info("Detected: #{name}!") + @chain << guest + + # Build the proper chain of parents if there are any. + # This allows us to do "inheritence" of capabilities later + if guest_info[1] + parent_info = @guests[guest_info[1]] + while parent_info + @chain << parent_info[0].new + parent_info = @guests[parent_info[1]] + end + end + + @logger.info("Full guest chain: #{@chain.inspect}") + + # Exit the search + throw :guest_os + end + end + end + end + + # We shouldn't reach this point. Ideally we would detect + # all operating systems. + raise Errors::GuestNotDetected if @chain.empty? + end + + # This returns whether the guest is ready to work. If this returns + # `false`, then {#detect!} should be called in order to detect the + # guest OS. + # + # @return [Boolean] + def ready? + !@chain.empty? + end + end +end diff --git a/lib/vagrant/machine.rb b/lib/vagrant/machine.rb index f8be78aef..0b12580b1 100644 --- a/lib/vagrant/machine.rb +++ b/lib/vagrant/machine.rb @@ -83,6 +83,7 @@ module Vagrant @config = config @data_dir = data_dir @env = env + @guest = Guest.new(self) @name = name @provider_config = provider_config @provider_name = provider_name @@ -169,32 +170,7 @@ module Vagrant # @return [Object] def guest raise Errors::MachineGuestNotReady if !communicate.ready? - - # Load the initial guest. - last_guest = config.vm.guest - guest = load_guest(last_guest) - - # Loop and distro dispatch while there are distros. - while true - distro = guest.distro_dispatch - break if !distro - - # This is just some really basic loop detection and avoiding for - # guest classes. This is just here to help implementers a bit - # avoid a situation that is fairly easy, since if you subclass - # a parent which does `distro_dispatch`, you'll end up dispatching - # forever. - if distro == last_guest - @logger.warn("Distro dispatch loop in '#{distro}'. Exiting loop.") - break - end - - last_guest = distro - guest = load_guest(distro) - end - - # Return the result - guest + @guest end # This sets the unique ID associated with this machine. This will diff --git a/lib/vagrant/plugin/v2/components.rb b/lib/vagrant/plugin/v2/components.rb index 9510b0a87..636f7ae6c 100644 --- a/lib/vagrant/plugin/v2/components.rb +++ b/lib/vagrant/plugin/v2/components.rb @@ -16,6 +16,11 @@ module Vagrant # @return [Hash] attr_reader :configs + # This contains all the guests and their parents. + # + # @return [Registry>] + attr_reader :guests + # This contains all the provider plugins by name, and returns # the provider class and options. # @@ -27,6 +32,7 @@ module Vagrant @action_hooks = Hash.new { |h, k| h[k] = [] } @configs = Hash.new { |h, k| h[k] = Registry.new } + @guests = Registry.new @providers = Registry.new end end diff --git a/lib/vagrant/plugin/v2/guest.rb b/lib/vagrant/plugin/v2/guest.rb index f757296dd..9af83887b 100644 --- a/lib/vagrant/plugin/v2/guest.rb +++ b/lib/vagrant/plugin/v2/guest.rb @@ -1,35 +1,21 @@ module Vagrant module Plugin module V2 - # The base class for a guest. A guest represents an installed system - # within a machine that Vagrant manages. There are some portions of - # Vagrant which are OS-specific such as mountaing shared folders and - # halting the machine, and this abstraction allows the implementation - # for these to be seperate from the core of Vagrant. + # A base class for a guest OS. A guest OS is responsible for detecting + # that the guest operating system running within the machine. The guest + # can then be extended with various "guest capabilities" which are their + # own form of plugin. + # + # The guest class itself is only responsible for detecting itself, + # and may provide helpers for the capabilties. class Guest - class BaseError < Errors::VagrantError - error_namespace("vagrant.guest.base") - end - - include Vagrant::Util - - # The VM which this system is tied to. - attr_reader :vm - - # Initializes the system. Any subclasses MUST make sure this - # method is called on the parent. Therefore, if a subclass overrides - # `initialize`, then you must call `super`. - def initialize(vm) - @vm = vm - end - - # This method is automatically called when the system is available (when - # Vagrant can successfully SSH into the machine) to give the system a chance - # to determine the distro and return a distro-specific system. + # This method is called when the machine is booted and has communication + # capabilities in order to detect whether this guest operating system + # is running within the machine. # - # If this method returns nil, then this instance is assumed to be - # the most specific guest implementation. - def distro_dispatch + # @return [Boolean] + def guest?(machine) + false end # Halt the machine. This method should gracefully shut down the diff --git a/lib/vagrant/plugin/v2/manager.rb b/lib/vagrant/plugin/v2/manager.rb index f7cfa5c4e..887bd5c0e 100644 --- a/lib/vagrant/plugin/v2/manager.rb +++ b/lib/vagrant/plugin/v2/manager.rb @@ -67,7 +67,7 @@ module Vagrant def guests Registry.new.tap do |result| @registered.each do |plugin| - result.merge!(plugin.guest) + result.merge!(plugin.components.guests) end end end diff --git a/lib/vagrant/plugin/v2/plugin.rb b/lib/vagrant/plugin/v2/plugin.rb index be2d11802..0480631fc 100644 --- a/lib/vagrant/plugin/v2/plugin.rb +++ b/lib/vagrant/plugin/v2/plugin.rb @@ -124,7 +124,6 @@ module Vagrant # without breaking anything in future versions of Vagrant. # # @param [String] name Configuration key. - # XXX: Document options hash def self.config(name, scope=nil, &block) scope ||= :top components.configs[scope].register(name.to_sym, &block) @@ -135,14 +134,14 @@ module Vagrant # the given key. # # @param [String] name Name of the guest. - def self.guest(name=UNSET_VALUE, &block) - data[:guests] ||= Registry.new + # @param [String] parent Name of the parent guest (if any) + def self.guest(name=UNSET_VALUE, parent=nil, &block) + components.guests.register(name.to_sym) do + parent = parent.to_sym if parent - # Register a new guest class only if a name was given - data[:guests].register(name.to_sym, &block) if name != UNSET_VALUE - - # Return the registry - data[:guests] + [block.call, parent] + end + nil end # Defines an additionally available host implementation with diff --git a/plugins/guests/arch/guest.rb b/plugins/guests/arch/guest.rb index 7b0b5f373..a354f6799 100644 --- a/plugins/guests/arch/guest.rb +++ b/plugins/guests/arch/guest.rb @@ -12,6 +12,10 @@ module VagrantPlugins # Make the TemplateRenderer top-level include Vagrant::Util + def detect?(machine) + machine.communicate.test("cat /etc/arch-release") + end + def change_host_name(name) # Only do this if the hostname is not already set if !vm.communicate.test("sudo hostname | grep '#{name}'") diff --git a/plugins/guests/arch/plugin.rb b/plugins/guests/arch/plugin.rb index bcbb945ae..36c2d76ce 100644 --- a/plugins/guests/arch/plugin.rb +++ b/plugins/guests/arch/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "Arch guest" description "Arch guest support." - guest("arch") do + guest("arch", "linux") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/debian/guest.rb b/plugins/guests/debian/guest.rb index c5a32cb19..2712b32c7 100644 --- a/plugins/guests/debian/guest.rb +++ b/plugins/guests/debian/guest.rb @@ -12,6 +12,10 @@ module VagrantPlugins # Make the TemplateRenderer top-level include Vagrant::Util + def detect?(machine) + machine.communicate.test("cat /proc/version | grep 'Debian'") + end + def configure_networks(networks) # First, remove any previous network modifications # from the interface file. diff --git a/plugins/guests/debian/plugin.rb b/plugins/guests/debian/plugin.rb index 7cb276635..b9190d4bf 100644 --- a/plugins/guests/debian/plugin.rb +++ b/plugins/guests/debian/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "Debian guest" description "Debian guest support." - guest("debian") do + guest("debian", "linux") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/fedora/guest.rb b/plugins/guests/fedora/guest.rb index 54856a3f5..f32d8f3d2 100644 --- a/plugins/guests/fedora/guest.rb +++ b/plugins/guests/fedora/guest.rb @@ -12,6 +12,10 @@ module VagrantPlugins # Make the TemplateRenderer top-level include Vagrant::Util + def detect?(machine) + machine.communicate.test("grep 'Fedora release 1[678]' /etc/redhat-release") + end + def configure_networks(networks) # Accumulate the configurations to add to the interfaces file as well # as what interfaces we're actually configuring since we use that later. diff --git a/plugins/guests/fedora/plugin.rb b/plugins/guests/fedora/plugin.rb index 29323f188..73bbcb911 100644 --- a/plugins/guests/fedora/plugin.rb +++ b/plugins/guests/fedora/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "Fedora guest" description "Fedora guest support." - guest("fedora") do + guest("fedora", "linux") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/freebsd/guest.rb b/plugins/guests/freebsd/guest.rb index 7a3b5ea66..c5ff14951 100644 --- a/plugins/guests/freebsd/guest.rb +++ b/plugins/guests/freebsd/guest.rb @@ -11,6 +11,11 @@ module VagrantPlugins error_namespace("vagrant.guest.freebsd") end + def detect?(machine) + # TODO: FreeBSD detection + false + end + def halt begin vm.communicate.sudo("shutdown -p now") diff --git a/plugins/guests/gentoo/guest.rb b/plugins/guests/gentoo/guest.rb index 2f59dbd2c..5aaacd573 100644 --- a/plugins/guests/gentoo/guest.rb +++ b/plugins/guests/gentoo/guest.rb @@ -11,6 +11,10 @@ module VagrantPlugins # Make the TemplateRenderer top-level include Vagrant::Util + def detect?(machine) + machine.communicate.test("cat /etc/gentoo-release") + end + def configure_networks(networks) # Remove any previous host only network additions to the interface file vm.communicate.sudo("sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/conf.d/net > /tmp/vagrant-network-interfaces") diff --git a/plugins/guests/gentoo/plugin.rb b/plugins/guests/gentoo/plugin.rb index c888d811d..b37b39565 100644 --- a/plugins/guests/gentoo/plugin.rb +++ b/plugins/guests/gentoo/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "Gentoo guest" description "Gentoo guest support." - guest("gentoo") do + guest("gentoo", "linux") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/linux/guest.rb b/plugins/guests/linux/guest.rb index 7c649be92..f0bc77c1d 100644 --- a/plugins/guests/linux/guest.rb +++ b/plugins/guests/linux/guest.rb @@ -18,6 +18,11 @@ module VagrantPlugins @logger = Log4r::Logger.new("vagrant::guest::linux") end + def detect?(machine) + # TODO: Linux detection + false + end + def distro_dispatch @vm.communicate.tap do |comm| if comm.test("cat /etc/debian_version") diff --git a/plugins/guests/openbsd/guest.rb b/plugins/guests/openbsd/guest.rb index dd4a4831a..8a4e6408d 100644 --- a/plugins/guests/openbsd/guest.rb +++ b/plugins/guests/openbsd/guest.rb @@ -5,6 +5,11 @@ require Vagrant.source_root.join("plugins/guests/linux/guest") module VagrantPlugins module GuestOpenBSD class Guest < VagrantPlugins::GuestLinux::Guest + def detect?(machine) + # TODO: OpenBSD detection + false + end + def halt vm.communicate.sudo("shutdown -p -h now") end diff --git a/plugins/guests/openbsd/plugin.rb b/plugins/guests/openbsd/plugin.rb index ce74391c0..dd6f38a76 100644 --- a/plugins/guests/openbsd/plugin.rb +++ b/plugins/guests/openbsd/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "OpenBSD guest" description "OpenBSD guest support." - guest("openbsd") do + guest("openbsd", "linux") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/pld/guest.rb b/plugins/guests/pld/guest.rb index b183102a4..a2d7ad881 100644 --- a/plugins/guests/pld/guest.rb +++ b/plugins/guests/pld/guest.rb @@ -5,6 +5,10 @@ require Vagrant.source_root.join("plugins/guests/redhat/guest") module VagrantPlugins module GuestPld class Guest < VagrantPlugins::GuestRedHat::Guest + def detect?(machine) + machine.communicate.test("cat /etc/pld-release") + end + def network_scripts_dir '/etc/sysconfig/interfaces/' end diff --git a/plugins/guests/pld/plugin.rb b/plugins/guests/pld/plugin.rb index b072ed9f6..bd457b8c1 100644 --- a/plugins/guests/pld/plugin.rb +++ b/plugins/guests/pld/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "PLD Linux guest" description "PLD Linux guest support." - guest("pld") do + guest("pld", "redhat") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/redhat/guest.rb b/plugins/guests/redhat/guest.rb index 39c508856..0ac990ea0 100644 --- a/plugins/guests/redhat/guest.rb +++ b/plugins/guests/redhat/guest.rb @@ -12,6 +12,10 @@ module VagrantPlugins # Make the TemplateRenderer top-level include Vagrant::Util + def detect?(machine) + machine.communicate.test("cat /etc/redhat-release") + end + def configure_networks(networks) # Accumulate the configurations to add to the interfaces file as # well as what interfaces we're actually configuring since we use that diff --git a/plugins/guests/redhat/plugin.rb b/plugins/guests/redhat/plugin.rb index 4355152ff..dd80ef78f 100644 --- a/plugins/guests/redhat/plugin.rb +++ b/plugins/guests/redhat/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "RedHat guest" description "RedHat guest support." - guest("redhat") do + guest("redhat", "linux") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/solaris/guest.rb b/plugins/guests/solaris/guest.rb index a5f13c92e..a815748d0 100644 --- a/plugins/guests/solaris/guest.rb +++ b/plugins/guests/solaris/guest.rb @@ -11,6 +11,10 @@ module VagrantPlugins error_namespace("vagrant.guest.solaris") end + def detect?(machine) + machine.communicate.test("grep 'Solaris' /etc/release") + end + def configure_networks(networks) networks.each do |network| device = "#{vm.config.solaris.device}#{network[:interface]}" diff --git a/plugins/guests/suse/guest.rb b/plugins/guests/suse/guest.rb index 8694b669e..e6caeda45 100644 --- a/plugins/guests/suse/guest.rb +++ b/plugins/guests/suse/guest.rb @@ -5,6 +5,10 @@ require Vagrant.source_root.join("plugins/guests/redhat/guest") module VagrantPlugins module GuestSuse class Guest < VagrantPlugins::GuestRedHat::Guest + def detect?(machine) + machine.communicate.test("cat /etc/SuSE-release") + end + def network_scripts_dir '/etc/sysconfig/network/' end diff --git a/plugins/guests/suse/plugin.rb b/plugins/guests/suse/plugin.rb index 12e925f02..0fd401ea7 100644 --- a/plugins/guests/suse/plugin.rb +++ b/plugins/guests/suse/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "SUSE guest" description "SUSE guest support." - guest("suse") do + guest("suse", "redhat") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/plugins/guests/ubuntu/guest.rb b/plugins/guests/ubuntu/guest.rb index bc199b535..707f2e8fa 100644 --- a/plugins/guests/ubuntu/guest.rb +++ b/plugins/guests/ubuntu/guest.rb @@ -5,6 +5,10 @@ require Vagrant.source_root.join("plugins/guests/debian/guest") module VagrantPlugins module GuestUbuntu class Guest < VagrantPlugins::GuestDebian::Guest + def detect?(machine) + machine.communicate.test("cat /proc/version | grep 'Ubuntu'") + end + def mount_shared_folder(name, guestpath, options) # Mount it like normal super diff --git a/plugins/guests/ubuntu/plugin.rb b/plugins/guests/ubuntu/plugin.rb index 8e3cc72c1..f8e5c0708 100644 --- a/plugins/guests/ubuntu/plugin.rb +++ b/plugins/guests/ubuntu/plugin.rb @@ -6,7 +6,7 @@ module VagrantPlugins name "Ubuntu guest" description "Ubuntu guest support." - guest("ubuntu") do + guest("ubuntu", "debian") do require File.expand_path("../guest", __FILE__) Guest end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 832fb2701..ea5ae4d1d 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -173,18 +173,12 @@ en: of the official installers or another gem is wrongly attempting to use Vagrant internals directly. Please properly install Vagrant to fix this. If this error persists, please contact support. - guest: - invalid_class: |- - The specified guest class does not inherit from a proper guest - component class. The guest class must inherit from this. - - The specified guest class was: %{guest} - unknown_type: |- - The specified guest type is unknown: %{guest}. Please change this - to a proper value. - unspecified: |- - A VM guest type must be specified! This is done via the `config.vm.guest` - configuration value. Please read the documentation online for more information. + guest_not_detected: |- + The guest operating system of the machine could not be detected! + Vagrant requires this knowledge to perform specific tasks such + as mounting shared folders and configuring networks. Please add + the ability to detect this guest operating system to Vagrant + by creating a plugin or reporting a bug. home_dir_not_accessible: |- The home directory you specified is not accessible. The home directory that Vagrant uses must be both readable and writable. diff --git a/test/unit/vagrant/guest_test.rb b/test/unit/vagrant/guest_test.rb new file mode 100644 index 000000000..0cff98738 --- /dev/null +++ b/test/unit/vagrant/guest_test.rb @@ -0,0 +1,75 @@ +require "pathname" + +require File.expand_path("../../base", __FILE__) + +describe Vagrant::Guest do + include_context "unit" + + let(:guests) { {} } + let(:machine) { double("machine") } + + subject { described_class.new(machine, guests) } + + # This registers a guest with the class. + # + # @param [Symbol] name Name of the guest + # @param [Symbol] parent Name of the parent + # @param [Boolean] detect Whether or not to detect properly + def register_guest(name, parent, detect) + guest = Class.new(Vagrant.plugin("2", "guest")) do + define_method(:name) do + name + end + + define_method(:detect?) do |m| + detect + end + end + + guests[name] = [guest, parent] + end + + describe "#detect!" do + it "detects the first match" do + register_guest(:foo, nil, false) + register_guest(:bar, nil, true) + register_guest(:baz, nil, false) + + subject.detect! + subject.chain.length.should == 1 + subject.chain[0].name.should == :bar + end + + it "detects those with the most parents first" do + register_guest(:foo, nil, true) + register_guest(:bar, :foo, true) + register_guest(:baz, :bar, true) + register_guest(:foo2, nil, true) + register_guest(:bar2, :foo2, true) + + subject.detect! + subject.chain.length.should == 3 + subject.chain.map(&:name).should == [:baz, :bar, :foo] + end + + it "raises an exception if no guest can be detected" do + expect { subject.detect! }. + to raise_error(Vagrant::Errors::GuestNotDetected) + end + end + + describe "#ready?" do + before(:each) do + register_guest(:foo, nil, true) + end + + it "should not be ready by default" do + subject.ready?.should_not be + end + + it "should be ready after detecting" do + subject.detect! + subject.ready?.should be + end + end +end diff --git a/test/unit/vagrant/machine_test.rb b/test/unit/vagrant/machine_test.rb index 7a24be9ab..74cdb51c1 100644 --- a/test/unit/vagrant/machine_test.rb +++ b/test/unit/vagrant/machine_test.rb @@ -197,6 +197,7 @@ describe Vagrant::Machine do let(:communicator) do result = double("communicator") result.stub(:ready?).and_return(true) + result.stub(:test).and_return(false) result end @@ -212,63 +213,19 @@ describe Vagrant::Machine do end it "should return the configured guest" do - test_guest = Class.new(Vagrant.plugin("2", :guest)) + test_guest = Class.new(Vagrant.plugin("2", :guest)) do + def detect?(machine) + true + end + end register_plugin do |p| p.guest(:test) { test_guest } end - config.vm.guest = :test - result = instance.guest result.should be_kind_of(test_guest) end - - it "should raise an exception if it can't find the configured guest" do - config.vm.guest = :bad - - expect { instance.guest }. - to raise_error(Vagrant::Errors::VMGuestError) - end - - it "should distro dispatch to the most specific guest" do - # Create the classes and dispatch the parent into the child - guest_parent = Class.new(Vagrant.plugin("2", :guest)) do - def distro_dispatch - :child - end - end - - guest_child = Class.new(Vagrant.plugin("2", :guest)) - - # Register the classes - register_plugin do |p| - p.guest(:parent) { guest_parent } - p.guest(:child) { guest_child } - end - - # Test that the result is the child - config.vm.guest = :parent - instance.guest.should be_kind_of(guest_child) - end - - it "should protect against loops in the distro dispatch" do - # Create the classes and dispatch the parent into the child - guest_parent = Class.new(Vagrant.plugin("2", :guest)) do - def distro_dispatch - :parent - end - end - - # Register the classes - register_plugin do |p| - p.guest(:parent) { guest_parent } - end - - # Test that the result is the child - config.vm.guest = :parent - instance.guest.should be_kind_of(guest_parent) - end end describe "setting the ID" do