The basic process for this is to: 1. Load the configuration using the proper loader for that version. i.e. if you're loading V1 config, then use the V1 loader. 2. If we just loaded a version that isn't current (imagine we're currently at V3), then we need to upgrade that config. So we first ask the V2 loader to upgrade the V1 config to V2, then we ask the V3 loader to upgrade the V2 config to V3. We keep track of warnings and errors throughout this process. 3. Finally, we have a current config, so we merge it into the in-process configuration that is being loaded.
163 lines
4.0 KiB
Ruby
163 lines
4.0 KiB
Ruby
require File.expand_path("../../../base", __FILE__)
|
|
|
|
require "vagrant/registry"
|
|
|
|
describe Vagrant::Config::Loader do
|
|
include_context "unit"
|
|
|
|
# This is the current version of configuration for the tests.
|
|
let(:current_version) { version_order.last }
|
|
|
|
# This is just a dummy implementation of a configuraiton loader which
|
|
# simply acts on hashes.
|
|
let(:test_loader) do
|
|
Class.new(Vagrant::Config::VersionBase) do
|
|
def self.init
|
|
{}
|
|
end
|
|
|
|
def self.load(proc)
|
|
init.tap do |obj|
|
|
proc.call(obj)
|
|
end
|
|
end
|
|
|
|
def self.merge(old, new)
|
|
old.merge(new)
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:versions) do
|
|
Vagrant::Registry.new.tap do |r|
|
|
r.register("1") { test_loader }
|
|
end
|
|
end
|
|
|
|
let(:version_order) { ["1"] }
|
|
|
|
let(:instance) { described_class.new(versions, version_order) }
|
|
|
|
describe "basic loading" do
|
|
it "should ignore non-existent load order keys" do
|
|
instance.load_order = [:foo]
|
|
instance.load
|
|
end
|
|
|
|
it "should load and return the configuration" do
|
|
proc = Proc.new do |config|
|
|
config[:foo] = "yep"
|
|
end
|
|
|
|
instance.load_order = [:proc]
|
|
instance.set(:proc, [[current_version, proc]])
|
|
config = instance.load
|
|
|
|
config[:foo].should == "yep"
|
|
end
|
|
end
|
|
|
|
describe "finalization" do
|
|
it "should finalize the configuration" do
|
|
# Create the finalize method on our loader
|
|
def test_loader.finalize(obj)
|
|
obj[:finalized] = true
|
|
obj
|
|
end
|
|
|
|
# Basic configuration proc
|
|
proc = lambda do |config|
|
|
config[:foo] = "yep"
|
|
end
|
|
|
|
# Run the actual configuration and assert that we get the proper result
|
|
instance.load_order = [:proc]
|
|
instance.set(:proc, [[current_version, proc]])
|
|
config = instance.load
|
|
config[:foo].should == "yep"
|
|
config[:finalized].should == true
|
|
end
|
|
end
|
|
|
|
describe "upgrading" do
|
|
it "should do an upgrade to the latest version" do
|
|
test_loader_v2 = Class.new(test_loader) do
|
|
def self.upgrade(old)
|
|
new = old.dup
|
|
new[:v2] = true
|
|
|
|
[new, [], []]
|
|
end
|
|
end
|
|
|
|
versions.register("2") { test_loader_v2 }
|
|
version_order << "2"
|
|
|
|
# Load a version 1 proc, and verify it is upgraded to version 2
|
|
proc = lambda { |config| config[:foo] = "yep" }
|
|
instance.load_order = [:proc]
|
|
instance.set(:proc, [["1", proc]])
|
|
config = instance.load
|
|
config[:foo].should == "yep"
|
|
config[:v2].should == true
|
|
end
|
|
end
|
|
|
|
describe "loading edge cases" do
|
|
it "should only run the same proc once" do
|
|
count = 0
|
|
proc = Proc.new do |config|
|
|
config[:foo] = "yep"
|
|
count += 1
|
|
end
|
|
|
|
instance.load_order = [:proc]
|
|
instance.set(:proc, [[current_version, proc]])
|
|
|
|
5.times do
|
|
result = instance.load
|
|
|
|
# Verify the config result
|
|
result[:foo].should == "yep"
|
|
|
|
# Verify the count is only one
|
|
count.should == 1
|
|
end
|
|
end
|
|
|
|
it "should only load configuration files once" do
|
|
$_config_data = 0
|
|
|
|
# We test both setting a file multiple times as well as multiple
|
|
# loads, since both should not cache the data.
|
|
file = temporary_file("$_config_data += 1")
|
|
instance.load_order = [:file]
|
|
5.times { instance.set(:file, file) }
|
|
5.times { instance.load }
|
|
|
|
$_config_data.should == 1
|
|
end
|
|
|
|
it "should not clear the cache if setting to the same value multiple times" do
|
|
$_config_data = 0
|
|
|
|
file = temporary_file("$_config_data += 1")
|
|
|
|
instance.load_order = [:proc]
|
|
instance.set(:proc, file)
|
|
5.times { instance.load }
|
|
|
|
instance.set(:proc, file)
|
|
5.times { instance.load }
|
|
|
|
$_config_data.should == 1
|
|
end
|
|
|
|
it "should raise proper error if there is a syntax error in a Vagrantfile" do
|
|
instance.load_order = [:file]
|
|
expect { instance.set(:file, temporary_file("Vagrant:^Config")) }.
|
|
to raise_exception(Vagrant::Errors::VagrantfileSyntaxError)
|
|
end
|
|
end
|
|
end
|