This commit adds a unique error message for an empty box value. It requires modifications to vagrantfile.rb because some Vagrantfile config is used before validation occurs.
536 lines
14 KiB
Ruby
536 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
|
|
|
|
it "does not try to load the box if the box is empty" do
|
|
provider_cls = register_provider("foo")
|
|
|
|
configure do |config|
|
|
config.vm.box = ""
|
|
end
|
|
|
|
expect(boxes).not_to receive(:find)
|
|
results = subject.machine_config(:default, :foo, boxes)
|
|
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
|