385 lines
11 KiB
Ruby
385 lines
11 KiB
Ruby
require "pathname"
|
|
|
|
require File.expand_path("../../base", __FILE__)
|
|
|
|
describe Vagrant::Machine do
|
|
include_context "unit"
|
|
|
|
let(:name) { "foo" }
|
|
let(:provider) { double("provider") }
|
|
let(:provider_cls) do
|
|
obj = double("provider_cls")
|
|
obj.stub(:new => provider)
|
|
obj
|
|
end
|
|
let(:provider_config) { Object.new }
|
|
let(:provider_name) { :test }
|
|
let(:provider_options) { {} }
|
|
let(:box) { Object.new }
|
|
let(:config) { env.config_global }
|
|
let(:data_dir) { Pathname.new(Tempdir.new.path) }
|
|
let(:env) do
|
|
# We need to create a Vagrantfile so that this test environment
|
|
# has a proper root path
|
|
test_env.vagrantfile("")
|
|
|
|
# Create the Vagrant::Environment instance
|
|
test_env.create_vagrant_env
|
|
end
|
|
|
|
let(:test_env) { isolated_environment }
|
|
|
|
let(:instance) { new_instance }
|
|
|
|
subject { instance }
|
|
|
|
# Returns a new instance with the test data
|
|
def new_instance
|
|
described_class.new(name, provider_name, provider_cls, provider_config,
|
|
provider_options, config, data_dir, box, env)
|
|
end
|
|
|
|
describe "initialization" do
|
|
describe "provider initialization" do
|
|
# This is a helper that generates a test for provider intialization.
|
|
# This is a separate helper method because it takes a block that can
|
|
# be used to have additional tests on the received machine.
|
|
#
|
|
# @yield [machine] Yields the machine that the provider initialization
|
|
# method received so you can run additional tests on it.
|
|
def provider_init_test
|
|
received_machine = nil
|
|
|
|
provider_cls = double("provider_cls")
|
|
provider_cls.should_receive(:new) do |machine|
|
|
# Store this for later so we can verify that it is the
|
|
# one we expected to receive.
|
|
received_machine = machine
|
|
|
|
# Sanity check
|
|
machine.should be
|
|
|
|
# Yield our machine if we want to do additional tests
|
|
yield machine if block_given?
|
|
end
|
|
|
|
# Initialize a new machine and verify that we properly receive
|
|
# the machine we expect.
|
|
instance = described_class.new(name, provider_name, provider_cls, provider_config,
|
|
provider_options, config, data_dir, box, env)
|
|
received_machine.should eql(instance)
|
|
end
|
|
|
|
it "should initialize with the machine object" do
|
|
# Just run the blank test
|
|
provider_init_test
|
|
end
|
|
|
|
it "should have the machine name setup" do
|
|
provider_init_test do |machine|
|
|
machine.name.should == name
|
|
end
|
|
end
|
|
|
|
it "should have the machine configuration" do
|
|
provider_init_test do |machine|
|
|
machine.config.should eql(config)
|
|
end
|
|
end
|
|
|
|
it "should have the box" do
|
|
provider_init_test do |machine|
|
|
machine.box.should eql(box)
|
|
end
|
|
end
|
|
|
|
it "should have the environment" do
|
|
provider_init_test do |machine|
|
|
machine.env.should eql(env)
|
|
end
|
|
end
|
|
|
|
it "should have access to the ID" do
|
|
# Stub this because #id= calls it.
|
|
provider.stub(:machine_id_changed)
|
|
|
|
# Set the ID on the previous instance so that it is persisted
|
|
instance.id = "foo"
|
|
|
|
provider_init_test do |machine|
|
|
machine.id.should == "foo"
|
|
end
|
|
end
|
|
|
|
it "should NOT have access to the provider" do
|
|
provider_init_test do |machine|
|
|
machine.provider.should be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "attributes" do
|
|
its(:name) { should eq(name) }
|
|
its(:config) { should eql(config) }
|
|
its(:box) { should eql(box) }
|
|
its(:env) { should eql(env) }
|
|
its(:provider) { should eql(provider) }
|
|
its(:provider_config) { should eql(provider_config) }
|
|
its(:provider_options) { should eq(provider_options) }
|
|
end
|
|
|
|
describe "actions" do
|
|
it "should be able to run an action that exists" do
|
|
action_name = :up
|
|
called = false
|
|
callable = lambda { |_env| called = true }
|
|
|
|
provider.should_receive(:action).with(action_name).and_return(callable)
|
|
instance.action(:up)
|
|
called.should be
|
|
end
|
|
|
|
it "should provide the machine in the environment" do
|
|
action_name = :up
|
|
machine = nil
|
|
callable = lambda { |env| machine = env[:machine] }
|
|
|
|
provider.stub(:action).with(action_name).and_return(callable)
|
|
instance.action(:up)
|
|
|
|
machine.should eql(instance)
|
|
end
|
|
|
|
it "should pass any extra options to the environment" do
|
|
action_name = :up
|
|
foo = nil
|
|
callable = lambda { |env| foo = env[:foo] }
|
|
|
|
provider.stub(:action).with(action_name).and_return(callable)
|
|
instance.action(:up, :foo => :bar)
|
|
|
|
foo.should == :bar
|
|
end
|
|
|
|
it "should return the environment as a result" do
|
|
action_name = :up
|
|
callable = lambda { |env| env[:result] = "FOO" }
|
|
|
|
provider.stub(:action).with(action_name).and_return(callable)
|
|
result = instance.action(action_name)
|
|
|
|
result[:result].should == "FOO"
|
|
end
|
|
|
|
it "should raise an exception if the action is not implemented" do
|
|
action_name = :up
|
|
|
|
provider.stub(:action).with(action_name).and_return(nil)
|
|
|
|
expect { instance.action(action_name) }.
|
|
to raise_error(Vagrant::Errors::UnimplementedProviderAction)
|
|
end
|
|
end
|
|
|
|
describe "communicator" do
|
|
it "should always return the SSH communicator" do
|
|
instance.communicate.should be_kind_of(VagrantPlugins::CommunicatorSSH::Communicator)
|
|
end
|
|
|
|
it "should memoize the result" do
|
|
obj = instance.communicate
|
|
instance.communicate.should eql(obj)
|
|
end
|
|
end
|
|
|
|
describe "guest implementation" do
|
|
let(:communicator) do
|
|
result = double("communicator")
|
|
result.stub(:ready?).and_return(true)
|
|
result.stub(:test).and_return(false)
|
|
result
|
|
end
|
|
|
|
before(:each) do
|
|
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
|
|
|
|
instance.stub(:communicate).and_return(communicator)
|
|
end
|
|
|
|
it "should raise an exception if communication is not ready" do
|
|
communicator.should_receive(:ready?).and_return(false)
|
|
|
|
expect { instance.guest }.
|
|
to raise_error(Vagrant::Errors::MachineGuestNotReady)
|
|
end
|
|
|
|
it "should return the configured guest" do
|
|
result = instance.guest
|
|
result.should be_kind_of(Vagrant::Guest)
|
|
result.ready?.should be
|
|
result.chain[0][0].should == :test
|
|
end
|
|
end
|
|
|
|
describe "setting the ID" do
|
|
before(:each) do
|
|
provider.stub(:machine_id_changed)
|
|
end
|
|
|
|
it "should not have an ID by default" do
|
|
instance.id.should be_nil
|
|
end
|
|
|
|
it "should set an ID" do
|
|
instance.id = "bar"
|
|
instance.id.should == "bar"
|
|
end
|
|
|
|
it "should notify the machine that the ID changed" do
|
|
provider.should_receive(:machine_id_changed).once
|
|
|
|
instance.id = "bar"
|
|
end
|
|
|
|
it "should persist the ID" do
|
|
instance.id = "foo"
|
|
new_instance.id.should == "foo"
|
|
end
|
|
|
|
it "should delete the ID" do
|
|
instance.id = "foo"
|
|
|
|
second = new_instance
|
|
second.id.should == "foo"
|
|
second.id = nil
|
|
|
|
third = new_instance
|
|
third.id.should be_nil
|
|
end
|
|
end
|
|
|
|
describe "ssh info" do
|
|
describe "with the provider returning nil" do
|
|
it "should return nil if the provider returns nil" do
|
|
provider.should_receive(:ssh_info).and_return(nil)
|
|
instance.ssh_info.should be_nil
|
|
end
|
|
end
|
|
|
|
describe "with the provider returning data" do
|
|
let(:provider_ssh_info) { {} }
|
|
|
|
before(:each) do
|
|
provider.should_receive(:ssh_info).and_return(provider_ssh_info)
|
|
end
|
|
|
|
[:host, :port, :username].each do |type|
|
|
it "should return the provider data if not configured in Vagrantfile" do
|
|
provider_ssh_info[type] = "foo"
|
|
instance.config.ssh.send("#{type}=", nil)
|
|
|
|
instance.ssh_info[type].should == "foo"
|
|
end
|
|
|
|
it "should return the Vagrantfile value if provider data not given" do
|
|
provider_ssh_info[type] = nil
|
|
instance.config.ssh.send("#{type}=", "bar")
|
|
|
|
instance.ssh_info[type].should == "bar"
|
|
end
|
|
|
|
it "should use the default if no override and no provider" do
|
|
provider_ssh_info[type] = nil
|
|
instance.config.ssh.send("#{type}=", nil)
|
|
instance.config.ssh.default.send("#{type}=", "foo")
|
|
|
|
instance.ssh_info[type].should == "foo"
|
|
end
|
|
|
|
it "should use the override if set even with a provider" do
|
|
provider_ssh_info[type] = "baz"
|
|
instance.config.ssh.send("#{type}=", "bar")
|
|
instance.config.ssh.default.send("#{type}=", "foo")
|
|
|
|
instance.ssh_info[type].should == "bar"
|
|
end
|
|
end
|
|
|
|
it "should set the configured forward agent settings" do
|
|
provider_ssh_info[:forward_agent] = true
|
|
instance.config.ssh.forward_agent = false
|
|
|
|
instance.ssh_info[:forward_agent].should == false
|
|
end
|
|
|
|
it "should set the configured forward X11 settings" do
|
|
provider_ssh_info[:forward_x11] = true
|
|
instance.config.ssh.forward_x11 = false
|
|
|
|
instance.ssh_info[:forward_x11].should == false
|
|
end
|
|
|
|
it "should return the provider private key if given" do
|
|
provider_ssh_info[:private_key_path] = "/foo"
|
|
|
|
instance.ssh_info[:private_key_path].should == "/foo"
|
|
end
|
|
|
|
it "should return the configured SSH key path if set" do
|
|
provider_ssh_info[:private_key_path] = nil
|
|
instance.config.ssh.private_key_path = "/bar"
|
|
|
|
instance.ssh_info[:private_key_path].should == "/bar"
|
|
end
|
|
|
|
context "expanding path relative to the root path" do
|
|
it "should with the provider key path" do
|
|
provider_ssh_info[:private_key_path] = "~/foo"
|
|
|
|
instance.ssh_info[:private_key_path].should ==
|
|
File.expand_path("~/foo", env.root_path)
|
|
end
|
|
|
|
it "should with the config private key path" do
|
|
provider_ssh_info[:private_key_path] = nil
|
|
instance.config.ssh.private_key_path = "~/bar"
|
|
|
|
instance.ssh_info[:private_key_path].should ==
|
|
File.expand_path("~/bar", env.root_path)
|
|
end
|
|
end
|
|
|
|
it "should return the default private key path if provider and config doesn't have one" do
|
|
provider_ssh_info[:private_key_path] = nil
|
|
instance.config.ssh.private_key_path = nil
|
|
|
|
instance.ssh_info[:private_key_path].should == instance.env.default_private_key_path.to_s
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "state" do
|
|
it "should query state from the provider" do
|
|
state = Vagrant::MachineState.new(:id, "short", "long")
|
|
|
|
provider.should_receive(:state).and_return(state)
|
|
instance.state.id.should == :id
|
|
end
|
|
|
|
it "should raise an exception if a MachineState is not returned" do
|
|
provider.should_receive(:state).and_return(:old_school)
|
|
expect { instance.state }.
|
|
to raise_error(Vagrant::Errors::MachineStateInvalid)
|
|
end
|
|
end
|
|
end
|