525 lines
14 KiB
Ruby
525 lines
14 KiB
Ruby
require File.expand_path("../../base", __FILE__)
|
|
|
|
require "pathname"
|
|
require "tmpdir"
|
|
|
|
require "vagrant/vagrantfile"
|
|
|
|
describe Vagrant::Vagrantfile do
|
|
include_context "unit"
|
|
|
|
let(:keys) { [] }
|
|
let(:loader) {
|
|
Vagrant::Config::Loader.new(
|
|
Vagrant::Config::VERSIONS, Vagrant::Config::VERSIONS_ORDER)
|
|
}
|
|
|
|
subject { described_class.new(loader, keys) }
|
|
|
|
before do
|
|
keys << :test
|
|
end
|
|
|
|
def configure(&block)
|
|
loader.set(:test, [["2", block]])
|
|
end
|
|
|
|
# A helper to register a provider for use in tests.
|
|
def register_provider(name, config_class=nil, options=nil)
|
|
provider_cls = Class.new(VagrantTests::DummyProvider) do
|
|
if options && options[:unusable]
|
|
def self.usable?(raise_error=false)
|
|
raise Vagrant::Errors::VagrantError if raise_error
|
|
false
|
|
end
|
|
end
|
|
end
|
|
|
|
register_plugin("2") do |p|
|
|
p.provider(name, options) { provider_cls }
|
|
|
|
if config_class
|
|
p.config(name, :provider) { config_class }
|
|
end
|
|
end
|
|
|
|
provider_cls
|
|
end
|
|
|
|
describe "#config" do
|
|
it "exposes the global configuration" do
|
|
configure do |config|
|
|
config.vm.box = "what"
|
|
end
|
|
|
|
expect(subject.config.vm.box).to eq("what")
|
|
end
|
|
end
|
|
|
|
describe "#machine" do
|
|
let(:boxes) { Vagrant::BoxCollection.new(iso_env.boxes_dir) }
|
|
let(:data_path) { Pathname.new(Dir.mktmpdir("vagrant-machine-data-path")) }
|
|
let(:env) { iso_env.create_vagrant_env }
|
|
let(:iso_env) { isolated_environment }
|
|
let(:vagrantfile) { described_class.new(loader, keys) }
|
|
|
|
subject { vagrantfile.machine(:default, :foo, boxes, data_path, env) }
|
|
|
|
before do
|
|
@foo_config_cls = Class.new(Vagrant.plugin("2", "config")) do
|
|
attr_accessor :value
|
|
end
|
|
|
|
@provider_cls = register_provider("foo", @foo_config_cls)
|
|
|
|
configure do |config|
|
|
config.vm.box = "foo"
|
|
config.vm.provider "foo" do |p|
|
|
p.value = "rawr"
|
|
end
|
|
end
|
|
|
|
iso_env.box3("foo", "1.0", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 123
|
|
end
|
|
VF
|
|
end
|
|
|
|
after do
|
|
FileUtils.rm_rf(data_path.to_s)
|
|
end
|
|
|
|
describe '#data_dir' do
|
|
subject { super().data_dir }
|
|
it { should eq(data_path) }
|
|
end
|
|
|
|
describe '#env' do
|
|
subject { super().env }
|
|
it { should equal(env) }
|
|
end
|
|
|
|
describe '#name' do
|
|
subject { super().name }
|
|
it { should eq(:default) }
|
|
end
|
|
|
|
describe '#provider' do
|
|
subject { super().provider }
|
|
it { should be_kind_of(@provider_cls) }
|
|
end
|
|
|
|
describe '#provider_name' do
|
|
subject { super().provider_name }
|
|
it { should eq(:foo) }
|
|
end
|
|
|
|
describe '#vagrantfile' do
|
|
subject { super().vagrantfile }
|
|
it { should equal(vagrantfile) }
|
|
end
|
|
|
|
it "has the proper box" do
|
|
expect(subject.box.name).to eq("foo")
|
|
end
|
|
|
|
it "has the valid configuration" do
|
|
expect(subject.config.vm.box).to eq("foo")
|
|
end
|
|
|
|
it "loads the provider-specific configuration" do
|
|
expect(subject.provider_config).to be_kind_of(@foo_config_cls)
|
|
expect(subject.provider_config.value).to eq("rawr")
|
|
end
|
|
end
|
|
|
|
describe "#machine_config" do
|
|
let(:iso_env) { isolated_environment }
|
|
let(:boxes) { Vagrant::BoxCollection.new(iso_env.boxes_dir) }
|
|
|
|
it "should return a basic configured machine" do
|
|
provider_cls = register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = "foo"
|
|
end
|
|
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
box = results[:box]
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("foo")
|
|
expect(box).to be_nil
|
|
expect(results[:provider_cls]).to equal(provider_cls)
|
|
end
|
|
|
|
it "configures without a provider or boxes" do
|
|
register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = "foo"
|
|
end
|
|
|
|
results = subject.machine_config(:default, nil, nil)
|
|
box = results[:box]
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("foo")
|
|
expect(box).to be_nil
|
|
expect(results[:provider_cls]).to be_nil
|
|
end
|
|
|
|
it "configures with sub-machine config" do
|
|
register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.ssh.port = "1"
|
|
config.vm.box = "base"
|
|
|
|
config.vm.define "foo" do |f|
|
|
f.ssh.port = 100
|
|
end
|
|
end
|
|
|
|
results = subject.machine_config(:foo, :foo, boxes)
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(100)
|
|
end
|
|
|
|
it "configures with box configuration if it exists" do
|
|
register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
end
|
|
|
|
iso_env.box3("base", "1.0", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 123
|
|
end
|
|
VF
|
|
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
box = results[:box]
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(123)
|
|
expect(box).to_not be_nil
|
|
expect(box.name).to eq("base")
|
|
end
|
|
|
|
it "does not configure box configuration if set to ignore" do
|
|
register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
config.vm.ignore_box_vagrantfile = true
|
|
end
|
|
|
|
iso_env.box3("base", "1.0", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 123
|
|
config.vm.hostname = "hello"
|
|
end
|
|
VF
|
|
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
box = results[:box]
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(nil)
|
|
expect(config.vm.hostname).to eq(nil)
|
|
expect(box).to_not be_nil
|
|
expect(box.name).to eq("base")
|
|
end
|
|
|
|
it "configures with the proper box version" do
|
|
register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
config.vm.box_version = "~> 1.2"
|
|
end
|
|
|
|
iso_env.box3("base", "1.0", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 123
|
|
end
|
|
VF
|
|
|
|
iso_env.box3("base", "1.3", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 245
|
|
end
|
|
VF
|
|
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
box = results[:box]
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(245)
|
|
expect(box).to_not be_nil
|
|
expect(box.name).to eq("base")
|
|
expect(box.version).to eq("1.3")
|
|
end
|
|
|
|
it "configures with box config of other supported formats" do
|
|
register_provider("foo", nil, box_format: "bar")
|
|
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
end
|
|
|
|
iso_env.box3("base", "1.0", :bar, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 123
|
|
end
|
|
VF
|
|
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(123)
|
|
end
|
|
|
|
it "loads provider overrides if set" do
|
|
register_provider("foo")
|
|
register_provider("bar")
|
|
|
|
configure do |config|
|
|
config.ssh.port = 1
|
|
config.vm.box = "base"
|
|
|
|
config.vm.provider "foo" do |_, c|
|
|
c.ssh.port = 100
|
|
end
|
|
end
|
|
|
|
# Test with the override
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(100)
|
|
|
|
# Test without the override
|
|
results = subject.machine_config(:default, :bar, boxes)
|
|
config = results[:config]
|
|
expect(config.vm.box).to eq("base")
|
|
expect(config.ssh.port).to eq(1)
|
|
end
|
|
|
|
it "loads the proper box if in a provider override" do
|
|
register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
config.vm.box_version = "1.0"
|
|
|
|
config.vm.provider "foo" do |_, c|
|
|
c.vm.box = "foobox"
|
|
c.vm.box_version = "2.0"
|
|
end
|
|
end
|
|
|
|
iso_env.box3("base", "1.0", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 123
|
|
end
|
|
VF
|
|
|
|
iso_env.box3("foobox", "2.0", :foo, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.ssh.port = 234
|
|
end
|
|
VF
|
|
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
config = results[:config]
|
|
box = results[:box]
|
|
expect(config.vm.box).to eq("foobox")
|
|
expect(config.ssh.port).to eq(234)
|
|
expect(config.vm.box_version).to eq("2.0")
|
|
expect(box).to_not be_nil
|
|
expect(box.name).to eq("foobox")
|
|
expect(box.version).to eq("2.0")
|
|
end
|
|
|
|
it "raises an error if the machine is not found" do
|
|
expect { subject.machine_config(:foo, :foo, boxes) }.
|
|
to raise_error(Vagrant::Errors::MachineNotFound)
|
|
end
|
|
|
|
it "raises an error if the provider is not found" do
|
|
expect { subject.machine_config(:default, :foo, boxes) }.
|
|
to raise_error(Vagrant::Errors::ProviderNotFound)
|
|
end
|
|
|
|
it "raises an error if the provider is not found but gives suggestion" do
|
|
register_provider("foo")
|
|
|
|
expect { subject.machine_config(:default, :Foo, boxes) }.
|
|
to raise_error(Vagrant::Errors::ProviderNotFoundSuggestion)
|
|
end
|
|
|
|
it "raises an error if the provider is not usable" do
|
|
register_provider("foo", nil, unusable: true)
|
|
|
|
expect { subject.machine_config(:default, :foo, boxes) }.
|
|
to raise_error(Vagrant::Errors::ProviderNotUsable)
|
|
end
|
|
|
|
context "when provider validation is ignored" do
|
|
before do
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
config.vm.box_version = "1.0"
|
|
config.vm.define :guest1
|
|
config.vm.define :guest2
|
|
|
|
config.vm.provider "custom" do |_, c|
|
|
c.ssh.port = 123
|
|
end
|
|
end
|
|
|
|
iso_env.box3("base", "1.0", :custom, vagrantfile: <<-VF)
|
|
Vagrant.configure("2") do |config|
|
|
config.vagrant.plugins = "vagrant-custom"
|
|
end
|
|
VF
|
|
end
|
|
|
|
it "should not raise an error if provider is not found" do
|
|
expect { subject.machine_config(:guest1, :custom, boxes, nil, false) }.
|
|
not_to raise_error
|
|
end
|
|
|
|
it "should return configuration from box Vagrantfile" do
|
|
config = subject.machine_config(:guest1, :custom, boxes, nil, false)[:config]
|
|
expect(config.vagrant.plugins).to be_a(Hash)
|
|
expect(config.vagrant.plugins.keys).to include("vagrant-custom")
|
|
end
|
|
end
|
|
|
|
context "local box metadata file" do
|
|
let(:data_path) { double(:data_path) }
|
|
let(:meta_file) { double(:meta_file) }
|
|
let(:box_version) { "2.0" }
|
|
|
|
before do
|
|
register_provider("foo")
|
|
iso_env.box3("base", "1.0", :foo)
|
|
allow(data_path).to receive(:join).with("box_meta").
|
|
and_return(meta_file)
|
|
allow(meta_file).to receive(:file?).and_return(false)
|
|
configure do |config|
|
|
config.vm.box = "base"
|
|
config.vm.box_version = box_version
|
|
end
|
|
end
|
|
|
|
it "checks for local box metadata file" do
|
|
expect(meta_file).to receive(:file?).and_return(false)
|
|
subject.machine_config(:default, :foo, boxes, data_path)
|
|
end
|
|
|
|
context "file exists" do
|
|
let(:meta_file_content) { '{"name":"base","version":"1.0"}' }
|
|
|
|
before do
|
|
allow(meta_file).to receive(:file?).and_return(true)
|
|
allow(meta_file).to receive(:read).and_return(meta_file_content)
|
|
end
|
|
|
|
it "reads the local box metadata file" do
|
|
expect(meta_file).to receive(:read).and_return(meta_file_content)
|
|
subject.machine_config(:default, :foo, boxes, data_path)
|
|
end
|
|
|
|
it "properly loads the box defined in metadata" do
|
|
result = subject.machine_config(:default, :foo, boxes, data_path)
|
|
expect(result[:box]).not_to be_nil
|
|
end
|
|
|
|
context "with invalid box version" do
|
|
let(:box_version) { "1.0" }
|
|
let(:meta_file_content) { '{"name":"base","version":"2.0"}' }
|
|
|
|
it "loads box base on Vagrantfile information" do
|
|
result = subject.machine_config(:default, :foo, boxes, data_path)
|
|
expect(result[:box]).not_to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#machine_names" do
|
|
it "returns the default name when single-VM" do
|
|
configure { |config| }
|
|
|
|
expect(subject.machine_names).to eq([:default])
|
|
end
|
|
|
|
it "returns all of the names in a multi-VM" do
|
|
configure do |config|
|
|
config.vm.define "foo"
|
|
config.vm.define "bar"
|
|
end
|
|
|
|
expect(subject.machine_names).to eq(
|
|
[:foo, :bar])
|
|
end
|
|
end
|
|
|
|
describe "#machine_names_and_options" do
|
|
it "returns the default name" do
|
|
configure { |config| }
|
|
|
|
expect(subject.machine_names_and_options).to eq({
|
|
default: { config_version: "2" },
|
|
})
|
|
end
|
|
|
|
it "returns all the machines" do
|
|
configure do |config|
|
|
config.vm.define "foo"
|
|
config.vm.define "bar", autostart: false
|
|
config.vm.define "baz", autostart: true
|
|
end
|
|
|
|
expect(subject.machine_names_and_options).to eq({
|
|
foo: { config_version: "2" },
|
|
bar: { config_version: "2", autostart: false },
|
|
baz: { config_version: "2", autostart: true },
|
|
})
|
|
end
|
|
end
|
|
|
|
describe "#primary_machine_name" do
|
|
it "returns the default name when single-VM" do
|
|
configure { |config| }
|
|
|
|
expect(subject.primary_machine_name).to eq(:default)
|
|
end
|
|
|
|
it "returns the designated machine in multi-VM" do
|
|
configure do |config|
|
|
config.vm.define "foo"
|
|
config.vm.define "bar", primary: true
|
|
config.vm.define "baz"
|
|
end
|
|
|
|
expect(subject.primary_machine_name).to eq(:bar)
|
|
end
|
|
|
|
it "returns nil if no designation in multi-VM" do
|
|
configure do |config|
|
|
config.vm.define "foo"
|
|
config.vm.define "baz"
|
|
end
|
|
|
|
expect(subject.primary_machine_name).to be_nil
|
|
end
|
|
end
|
|
end
|