349 lines
8.9 KiB
Ruby
349 lines
8.9 KiB
Ruby
require "json"
|
|
require "pathname"
|
|
require "tempfile"
|
|
|
|
require File.expand_path("../../base", __FILE__)
|
|
|
|
require "vagrant/machine_index"
|
|
|
|
describe Vagrant::MachineIndex do
|
|
include_context "unit"
|
|
|
|
let(:data_dir) { Pathname.new(Dir.mktmpdir("vagrant-test-machine-index-data-dir")) }
|
|
let(:entry_klass) { Vagrant::MachineIndex::Entry }
|
|
|
|
let(:new_entry) do
|
|
entry_klass.new.tap do |e|
|
|
e.name = "foo"
|
|
e.vagrantfile_path = "/bar"
|
|
end
|
|
end
|
|
|
|
subject { described_class.new(data_dir) }
|
|
|
|
after do
|
|
FileUtils.rm_rf(data_dir)
|
|
end
|
|
|
|
it "raises an exception if the data file is corrupt" do
|
|
data_dir.join("index").open("w") do |f|
|
|
f.write(JSON.dump({}))
|
|
end
|
|
|
|
expect { subject }.
|
|
to raise_error(Vagrant::Errors::CorruptMachineIndex)
|
|
end
|
|
|
|
it "raises an exception if the JSON is invalid" do
|
|
data_dir.join("index").open("w") do |f|
|
|
f.write("foo")
|
|
end
|
|
|
|
expect { subject }.
|
|
to raise_error(Vagrant::Errors::CorruptMachineIndex)
|
|
end
|
|
|
|
describe "#each" do
|
|
before do
|
|
5.times do |i|
|
|
e = entry_klass.new
|
|
e.name = "entry-#{i}"
|
|
e.vagrantfile_path = "/foo"
|
|
subject.release(subject.set(e))
|
|
end
|
|
end
|
|
|
|
it "should iterate over all the elements" do
|
|
items = []
|
|
|
|
subject = described_class.new(data_dir)
|
|
subject.each do |entry|
|
|
items << entry.name
|
|
end
|
|
|
|
items.sort!
|
|
expect(items).to eq([
|
|
"entry-0",
|
|
"entry-1",
|
|
"entry-2",
|
|
"entry-3",
|
|
"entry-4",
|
|
])
|
|
end
|
|
end
|
|
|
|
describe "#get and #release" do
|
|
before do
|
|
data = {
|
|
"version" => 1,
|
|
"machines" => {
|
|
"bar" => {
|
|
"name" => "default",
|
|
"provider" => "vmware",
|
|
"local_data_path" => "/foo",
|
|
"vagrantfile_path" => "/foo/bar/baz",
|
|
"state" => "running",
|
|
"updated_at" => "foo",
|
|
},
|
|
"baz" => {
|
|
"name" => "default",
|
|
"provider" => "vmware",
|
|
"vagrantfile_path" => "/foo/bar/baz",
|
|
"state" => "running",
|
|
"updated_at" => "foo",
|
|
"extra_data" => {
|
|
"foo" => "bar",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
data_dir.join("index").open("w") do |f|
|
|
f.write(JSON.dump(data))
|
|
end
|
|
end
|
|
|
|
it "returns nil if the machine doesn't exist" do
|
|
expect(subject.get("foo")).to be_nil
|
|
end
|
|
|
|
it "returns a valid entry if the machine exists" do
|
|
result = subject.get("bar")
|
|
|
|
expect(result.id).to eq("bar")
|
|
expect(result.name).to eq("default")
|
|
expect(result.provider).to eq("vmware")
|
|
expect(result.local_data_path).to eq(Pathname.new("/foo"))
|
|
expect(result.vagrantfile_path).to eq(Pathname.new("/foo/bar/baz"))
|
|
expect(result.state).to eq("running")
|
|
expect(result.updated_at).to eq("foo")
|
|
expect(result.extra_data).to eq({})
|
|
end
|
|
|
|
it "returns a valid entry with extra data" do
|
|
result = subject.get("baz")
|
|
expect(result.id).to eq("baz")
|
|
expect(result.extra_data).to eq({
|
|
"foo" => "bar",
|
|
})
|
|
end
|
|
|
|
it "returns a valid entry by unique prefix" do
|
|
result = subject.get("b")
|
|
|
|
expect(result).to_not be_nil
|
|
expect(result.id).to eq("bar")
|
|
end
|
|
|
|
it "should include? by prefix" do
|
|
expect(subject.include?("b")).to be(true)
|
|
end
|
|
|
|
it "locks the entry so subsequent gets fail" do
|
|
result = subject.get("bar")
|
|
expect(result).to_not be_nil
|
|
|
|
expect { subject.get("bar") }.
|
|
to raise_error(Vagrant::Errors::MachineLocked)
|
|
end
|
|
|
|
it "can unlock a machine" do
|
|
result = subject.get("bar")
|
|
expect(result).to_not be_nil
|
|
subject.release(result)
|
|
|
|
result = subject.get("bar")
|
|
expect(result).to_not be_nil
|
|
end
|
|
end
|
|
|
|
describe "#include" do
|
|
it "should not include non-existent things" do
|
|
expect(subject.include?("foo")).to be(false)
|
|
end
|
|
|
|
it "should include created entries" do
|
|
result = subject.set(new_entry)
|
|
expect(result.id).to_not be_empty
|
|
subject.release(result)
|
|
|
|
subject = described_class.new(data_dir)
|
|
expect(subject.include?(result.id)).to be(true)
|
|
end
|
|
end
|
|
|
|
describe "#set and #get and #delete" do
|
|
it "adds a new entry" do
|
|
result = subject.set(new_entry)
|
|
expect(result.id).to_not be_empty
|
|
|
|
# It should be locked
|
|
expect { subject.get(result.id) }.
|
|
to raise_error(Vagrant::Errors::MachineLocked)
|
|
|
|
# Get it froma new class and check the results
|
|
subject.release(result)
|
|
subject = described_class.new(data_dir)
|
|
entry = subject.get(result.id)
|
|
expect(entry).to_not be_nil
|
|
expect(entry.name).to eq("foo")
|
|
|
|
# TODO: test that updated_at is set
|
|
end
|
|
|
|
it "can delete an entry" do
|
|
result = subject.set(new_entry)
|
|
expect(result.id).to_not be_empty
|
|
subject.delete(result)
|
|
|
|
# Get it from a new class and check the results
|
|
subject = described_class.new(data_dir)
|
|
entry = subject.get(result.id)
|
|
expect(entry).to be_nil
|
|
end
|
|
|
|
it "can delete an entry that doesn't exist" do
|
|
e = entry_klass.new
|
|
expect(subject.delete(e)).to be(true)
|
|
end
|
|
|
|
it "updates an existing entry" do
|
|
entry = entry_klass.new
|
|
entry.name = "foo"
|
|
entry.vagrantfile_path = "/bar"
|
|
|
|
result = subject.set(entry)
|
|
expect(result.id).to_not be_empty
|
|
|
|
result.name = "bar"
|
|
result.extra_data["foo"] = "bar"
|
|
|
|
nextresult = subject.set(result)
|
|
expect(nextresult.id).to eq(result.id)
|
|
|
|
# Release it so we can test the contents
|
|
subject.release(nextresult)
|
|
|
|
# Get it froma new class and check the results
|
|
subject = described_class.new(data_dir)
|
|
entry = subject.get(result.id)
|
|
expect(entry).to_not be_nil
|
|
expect(entry.name).to eq("bar")
|
|
expect(entry.extra_data).to eq({
|
|
"foo" => "bar",
|
|
})
|
|
end
|
|
|
|
it "updates an existing directory if the name, provider, and path are the same" do
|
|
entry = entry_klass.new
|
|
entry.name = "foo"
|
|
entry.provider = "bar"
|
|
entry.vagrantfile_path = "/bar"
|
|
entry.state = "foo"
|
|
|
|
result = subject.set(entry)
|
|
expect(result.id).to_not be_empty
|
|
|
|
# Release it so we can modify it
|
|
subject.release(result)
|
|
|
|
entry2 = entry_klass.new
|
|
entry2.name = entry.name
|
|
entry2.provider = entry.provider
|
|
entry2.vagrantfile_path = entry.vagrantfile_path
|
|
entry2.state = "bar"
|
|
expect(entry2.id).to be_nil
|
|
|
|
nextresult = subject.set(entry2)
|
|
expect(nextresult.id).to eq(result.id)
|
|
|
|
# Release it so we can test the contents
|
|
subject.release(nextresult)
|
|
|
|
# Get it from a new class and check the results
|
|
subject = described_class.new(data_dir)
|
|
entry = subject.get(result.id)
|
|
expect(entry).to_not be_nil
|
|
expect(entry.name).to eq(entry2.name)
|
|
expect(entry.state).to eq(entry2.state)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe Vagrant::MachineIndex::Entry do
|
|
include_context "unit"
|
|
|
|
let(:env) {
|
|
iso_env = isolated_environment
|
|
iso_env.vagrantfile(vagrantfile)
|
|
iso_env.create_vagrant_env
|
|
}
|
|
|
|
let(:vagrantfile) { "" }
|
|
|
|
describe "#valid?" do
|
|
let(:machine) { env.machine(:default, :dummy) }
|
|
|
|
subject do
|
|
described_class.new.tap do |e|
|
|
e.name = "default"
|
|
e.provider = "dummy"
|
|
e.vagrantfile_path = env.root_path
|
|
end
|
|
end
|
|
|
|
it "should be valid with a valid entry" do
|
|
machine.id = "foo"
|
|
expect(subject).to be_valid(env.home_path)
|
|
end
|
|
|
|
it "should be invalid if no Vagrantfile path is set" do
|
|
subject.vagrantfile_path = nil
|
|
expect(subject).to_not be_valid(env.home_path)
|
|
end
|
|
|
|
it "should be invalid if the Vagrantfile path does not exist" do
|
|
subject.vagrantfile_path = Pathname.new("/i/should/not/exist")
|
|
expect(subject).to_not be_valid(env.home_path)
|
|
end
|
|
|
|
it "should be invalid if the machine is inactive" do
|
|
machine.id = nil
|
|
expect(subject).to_not be_valid(env.home_path)
|
|
end
|
|
|
|
it "should be invalid if machine is not created" do
|
|
machine.id = "foo"
|
|
machine.provider.state = Vagrant::MachineState::NOT_CREATED_ID
|
|
expect(subject).to_not be_valid(env.home_path)
|
|
end
|
|
|
|
context "with another active machine" do
|
|
let(:vagrantfile) do
|
|
<<-VF
|
|
Vagrant.configure("2") do |config|
|
|
config.vm.define "web"
|
|
config.vm.define "db"
|
|
end
|
|
VF
|
|
end
|
|
|
|
it "should be invalid if the wrong machine is active only" do
|
|
m = env.machine(:web, :dummy)
|
|
m.id = "foo"
|
|
|
|
subject.name = "db"
|
|
expect(subject).to_not be_valid(env.home_path)
|
|
end
|
|
|
|
it "should be valid if the correct machine is active" do
|
|
env.machine(:web, :dummy).id = "foo"
|
|
env.machine(:db, :dummy).id = "foo"
|
|
|
|
subject.name = "db"
|
|
expect(subject).to be_valid(env.home_path)
|
|
end
|
|
end
|
|
end
|
|
end
|