vaguerent/test/unit/vagrant/box_test.rb

302 lines
7.6 KiB
Ruby

require File.expand_path("../../base", __FILE__)
require "pathname"
require "stringio"
require "tempfile"
require "vagrant/box_metadata"
describe Vagrant::Box do
include_context "unit"
let(:environment) { isolated_environment }
let(:box_collection) { Vagrant::BoxCollection.new(environment.boxes_dir) }
let(:name) { "foo" }
let(:provider) { :virtualbox }
let(:version) { "1.0" }
let(:directory) { environment.box3("foo", "1.0", :virtualbox) }
subject { described_class.new(name, provider, version, directory) }
its(:metadata_url) { should be_nil }
it "provides the name" do
subject.name.should == name
end
it "provides the provider" do
subject.provider.should == provider
end
it "provides the directory" do
subject.directory.should == directory
end
it "provides the metadata associated with a box" do
data = { "foo" => "bar" }
# Write the metadata
directory.join("metadata.json").open("w") do |f|
f.write(JSON.generate(data))
end
# Verify the metadata
subject.metadata.should == data
end
context "with a metadata URL" do
subject do
described_class.new(
name, provider, version, directory,
metadata_url: "foo")
end
its(:metadata_url) { should eq("foo") }
end
context "with a corrupt metadata file" do
before do
directory.join("metadata.json").open("w") do |f|
f.write("")
end
end
it "should raise an exception" do
expect { subject }.
to raise_error(Vagrant::Errors::BoxMetadataCorrupted)
end
end
context "without a metadata file" do
before :each do
directory.join("metadata.json").delete
end
it "should raise an exception" do
expect { subject }.
to raise_error(Vagrant::Errors::BoxMetadataFileNotFound)
end
end
context "#has_update?" do
subject do
described_class.new(
name, provider, version, directory,
metadata_url: "foo")
end
it "raises an exception if no metadata_url is set" do
subject = described_class.new(
name, provider, version, directory)
expect { subject.has_update?("> 0") }.
to raise_error(Vagrant::Errors::BoxUpdateNoMetadata)
end
it "returns nil if there is no update" do
metadata = Vagrant::BoxMetadata.new(StringIO.new(<<-RAW))
{
"name": "foo",
"versions": [
{ "version": "1.0" }
]
}
RAW
subject.stub(load_metadata: metadata)
expect(subject.has_update?).to be_nil
end
it "returns the updated box info if there is an update available" do
metadata = Vagrant::BoxMetadata.new(StringIO.new(<<-RAW))
{
"name": "foo",
"versions": [
{
"version": "1.0"
},
{
"version": "1.1",
"providers": [
{
"name": "virtualbox",
"url": "bar"
}
]
}
]
}
RAW
subject.stub(load_metadata: metadata)
result = subject.has_update?
expect(result).to_not be_nil
expect(result[0]).to be_kind_of(Vagrant::BoxMetadata)
expect(result[1]).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result[2]).to be_kind_of(Vagrant::BoxMetadata::Provider)
expect(result[0].name).to eq("foo")
expect(result[1].version).to eq("1.1")
expect(result[2].url).to eq("bar")
end
it "returns the updated box info within constraints" do
metadata = Vagrant::BoxMetadata.new(StringIO.new(<<-RAW))
{
"name": "foo",
"versions": [
{
"version": "1.0"
},
{
"version": "1.1",
"providers": [
{
"name": "virtualbox",
"url": "bar"
}
]
},
{
"version": "1.4",
"providers": [
{
"name": "virtualbox",
"url": "bar"
}
]
}
]
}
RAW
subject.stub(load_metadata: metadata)
result = subject.has_update?(">= 1.1, < 1.4")
expect(result).to_not be_nil
expect(result[0]).to be_kind_of(Vagrant::BoxMetadata)
expect(result[1]).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result[2]).to be_kind_of(Vagrant::BoxMetadata::Provider)
expect(result[0].name).to eq("foo")
expect(result[1].version).to eq("1.1")
expect(result[2].url).to eq("bar")
end
end
context "#load_metadata" do
let(:metadata_url) do
Tempfile.new("vagrant").tap do |f|
f.write(<<-RAW)
{
"name": "foo",
"description": "bar"
}
RAW
f.close
end
end
subject do
described_class.new(
name, provider, version, directory,
metadata_url: metadata_url.path)
end
it "loads the url and returns the data" do
result = subject.load_metadata
expect(result.name).to eq("foo")
expect(result.description).to eq("bar")
end
end
describe "destroying" do
it "should destroy an existing box" do
# Verify that our "box" exists
directory.exist?.should be
# Destroy it
subject.destroy!.should be
# Verify that it is "destroyed"
directory.exist?.should_not be
end
it "should not error destroying a non-existent box" do
# Get the subject so that it is instantiated
box = subject
# Delete the directory
directory.rmtree
# Destroy it
box.destroy!.should be
end
end
describe "repackaging" do
it "should repackage the box" do
test_file_contents = "hello, world!"
# Put a file in the box directory to verify it is packaged properly
# later.
directory.join("test_file").open("w") do |f|
f.write(test_file_contents)
end
# Repackage our box to some temporary directory
box_output_path = temporary_dir.join("package.box")
expect(subject.repackage(box_output_path)).to be_true
# Let's now add this box again under a different name, and then
# verify that we get the proper result back.
new_box = box_collection.add(box_output_path, "foo2", "1.0")
new_box.directory.join("test_file").read.should == test_file_contents
end
end
describe "comparison and ordering" do
it "should be equal if the name, provider, version match" do
a = described_class.new("a", :foo, "1.0", directory)
b = described_class.new("a", :foo, "1.0", directory)
a.should == b
end
it "should not be equal if name doesn't match" do
a = described_class.new("a", :foo, "1.0", directory)
b = described_class.new("b", :foo, "1.0", directory)
expect(a).to_not eq(b)
end
it "should not be equal if provider doesn't match" do
a = described_class.new("a", :foo, "1.0", directory)
b = described_class.new("a", :bar, "1.0", directory)
expect(a).to_not eq(b)
end
it "should not be equal if version doesn't match" do
a = described_class.new("a", :foo, "1.0", directory)
b = described_class.new("a", :foo, "1.1", directory)
expect(a).to_not eq(b)
end
it "should sort them in order of name, version, provider" do
a = described_class.new("a", :foo, "1.0", directory)
b = described_class.new("a", :foo2, "1.0", directory)
c = described_class.new("a", :foo2, "1.1", directory)
d = described_class.new("b", :foo2, "1.0", directory)
[d, c, a, b].sort.should == [a, b, c, d]
end
end
end