Add test coverage for architecture support

This commit is contained in:
Chris Roberts 2023-07-28 10:40:32 -07:00
parent 51adb12547
commit 6e13612111
19 changed files with 1753 additions and 205 deletions

View File

@ -67,4 +67,16 @@ describe VagrantPlugins::CommandBox::Command::Add do
to raise_error(Vagrant::Errors::CLIInvalidUsage)
end
end
context "with architecture flag" do
let(:argv) { ["foo", "--architecture", "test-arch"] }
it "executes the runner with box architecture set" do
expect(action_runner).to receive(:run) do |_, opts|
expect(opts[:box_architecture]).to eq("test-arch")
end
subject.execute
end
end
end

View File

@ -81,4 +81,40 @@ describe VagrantPlugins::CommandBox::Command::Remove do
to raise_error(Vagrant::Errors::CLIInvalidUsage)
end
end
context "with architecture flag" do
let(:argv) { ["foo", "--architecture", "test-arch"] }
it "should execute runner with box architecture set" do
expect(action_runner).to receive(:run) do |_, opts|
expect(opts[:box_architecture]).to eq("test-arch")
end
subject.execute
end
end
context "with all providers flag" do
let(:argv) { ["foo", "--all-providers"] }
it "should execute runner with all providers enabled" do
expect(action_runner).to receive(:run) do |_, opts|
expect(opts[:box_remove_all_providers]).to be(true)
end
subject.execute
end
end
context "with all architectures flag" do
let(:argv) { ["foo", "--all-architectures"] }
it "should execute runner with all architectures enabled" do
expect(action_runner).to receive(:run) do |_, opts|
expect(opts[:box_remove_all_architectures]).to be(true)
end
subject.execute
end
end
end

View File

@ -37,18 +37,16 @@ describe VagrantPlugins::CommandBox::Command::Update do
describe "execute" do
context "updating specific box" do
let(:argv) { ["--box", "foo"] }
let(:scratch) { Dir.mktmpdir("vagrant-test-command-box-update-execute") }
let(:metadata_url) { Pathname.new(scratch).join("metadata.json") }
let(:box_args) { ["foo", "1.0", :virtualbox] }
let(:box_opts) { {metadata_url: metadata_url.to_s} }
before do
metadata_url.open("w") do |f|
f.write("")
end
test_iso_env.box3(
"foo", "1.0", :virtualbox, metadata_url: metadata_url.to_s)
test_iso_env.box3(*box_args, **box_opts)
end
after do
@ -72,43 +70,43 @@ describe VagrantPlugins::CommandBox::Command::Update do
it "does the correct update if there is an update" do
metadata_url.open("w") do |f|
f.write(<<-RAW)
f.write(
{
"name": "foo",
"versions": [
name: "foo",
versions: [
{
"version": "1.0"
version: "1.0"
},
{
"version": "1.8",
"providers": [
version: "1.8",
providers: [
{
"name": "virtualbox",
"url": "bar"
name: "virtualbox",
url: "bar"
}
]
},
{
"version": "1.10",
"providers": [
version: "1.10",
providers: [
{
"name": "virtualbox",
"url": "bar"
name: "virtualbox",
url: "bar"
}
]
},
{
"version": "1.11",
"providers": [
version: "1.11",
providers: [
{
"name": "virtualbox",
"url": "bar"
name: "virtualbox",
url: "bar"
}
]
}
]
}
RAW
}.to_json
)
end
action_called = false
@ -147,25 +145,25 @@ describe VagrantPlugins::CommandBox::Command::Update do
it "updates the proper box" do
metadata_url.open("w") do |f|
f.write(<<-RAW)
f.write(
{
"name": "foo",
"versions": [
name: "foo",
versions: [
{
"version": "1.0"
version: "1.0"
},
{
"version": "1.1",
"providers": [
version: "1.1",
providers: [
{
"name": "vmware",
"url": "bar"
name: "vmware",
url: "bar"
}
]
}
]
}
RAW
}.to_json
)
end
test_iso_env.box3("foo", "1.0", :vmware)
@ -200,25 +198,25 @@ describe VagrantPlugins::CommandBox::Command::Update do
it "passes down download options" do
metadata_url.open("w") do |f|
f.write(<<-RAW)
f.write(
{
"name": "foo",
"versions": [
name: "foo",
versions: [
{
"version": "1.0"
version: "1.0"
},
{
"version": "1.1",
"providers": [
version: "1.1",
providers: [
{
"name": "virtualbox",
"url": "bar"
name: "virtualbox",
url: "bar"
}
]
}
]
}
RAW
}.to_json
)
end
action_called = false
@ -249,6 +247,174 @@ describe VagrantPlugins::CommandBox::Command::Update do
to raise_error(Vagrant::Errors::BoxNotFound)
end
end
context "with architecture" do
let(:box_opts) { {metadata_url: metadata_url.to_s, architecture: "test-arch"} }
it "doesn't update if they're up to date" do
called = false
allow(action_runner).to receive(:run) do |callable, opts|
if opts[:box_provider]
called = true
end
opts
end
subject.execute
expect(called).to be(false)
end
it "does the correct update if there is an update" do
metadata_url.open("w") do |f|
f.write(
{
name: "foo",
versions: [
{
version: "1.0"
},
{
version: "1.8",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: "test-arch",
default_architecture: true
}
]
},
{
version: "1.10",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: "test-arch",
default_architecture: true
}
]
},
{
version: "1.11",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: "test-arch",
default_architecture: true
}
]
}
]
}.to_json
)
end
action_called = false
allow(action_runner).to receive(:run) do |action, opts|
if opts[:box_provider]
action_called = true
expect(opts[:box_force]).to eq(nil)
expect(opts[:box_url]).to eq(metadata_url.to_s)
expect(opts[:box_provider]).to eq("virtualbox")
expect(opts[:box_version]).to eq("1.11")
expect(opts[:box_architecture]).to eq("test-arch")
expect(opts[:box_download_ca_path]).to be_nil
expect(opts[:box_download_ca_cert]).to be_nil
expect(opts[:box_download_client_cert]).to be_nil
expect(opts[:box_download_insecure]).to be_nil
end
opts
end
subject.execute
expect(action_called).to be(true)
end
it "raises an error if there are multiple providers" do
test_iso_env.box3("foo", "1.0", :vmware)
expect(action_runner).to receive(:run).never
expect { subject.execute }.
to raise_error(Vagrant::Errors::BoxUpdateMultiProvider)
end
it "raises an error if there are multiple architectures" do
test_iso_env.box3("foo", "1.0", :virtualbox, architecture: "other-arch")
expect(action_runner).to receive(:run).never
expect { subject.execute }.
to raise_error(Vagrant::Errors::BoxUpdateMultiArchitecture)
end
context "with multiple architectures and specifying the architecture" do
let(:argv) { ["--box", "foo", "--architecture", "other-arch"] }
it "updates the proper box" do
metadata_url.open("w") do |f|
f.write(
{
name: "foo",
versions: [
{
version: "1.0"
},
{
version: "1.1",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: "test-arch",
},
{
name: "virtualbox",
url: "bar",
architecture: "other-arch",
}
]
}
]
}.to_json
)
end
test_iso_env.box3("foo", "1.0", :virtualbox, architecture: "other-arch")
action_called = false
allow(action_runner).to receive(:run) do |action, opts|
if opts[:box_provider]
action_called = true
expect(opts[:box_url]).to eq(metadata_url.to_s)
expect(opts[:box_provider]).to eq("virtualbox")
expect(opts[:box_version]).to eq("1.1")
expect(opts[:box_architecture]).to eq("other-arch")
end
opts
end
subject.execute
expect(action_called).to be(true)
end
it "raises an error if that provider doesn't exist" do
expect(action_runner).to receive(:run).never
expect { subject.execute }.
to raise_error(Vagrant::Errors::BoxNotFoundWithProviderArchitecture)
end
end
end
end
context "updating environment machines" do
@ -286,25 +452,27 @@ describe VagrantPlugins::CommandBox::Command::Update do
context "boxes have an update" do
let(:md) {
md = Vagrant::BoxMetadata.new(StringIO.new(<<-RAW))
Vagrant::BoxMetadata.new(
StringIO.new(
{
"name": "foo",
"versions": [
name: "foo",
versions: [
{
"version": "1.0"
version: "1.0"
},
{
"version": "1.1",
"providers": [
version: "1.1",
providers: [
{
"name": "virtualbox",
"url": "bar"
name: "virtualbox",
url: "bar"
}
]
}
]
}
RAW
}.to_json
)
)
}
before { allow(machine).to receive(:box).and_return(box) }

View File

@ -40,7 +40,7 @@ describe VagrantPlugins::CloudCommand::BoxCommand::Command::Show do
end
it "should display the box results" do
expect(subject).to receive(:format_box_results).with(box, env)
expect(subject).to receive(:format_box_results).with(box, env, {})
subject.show_box(org_name, box_name, access_token, options)
end
@ -62,7 +62,7 @@ describe VagrantPlugins::CloudCommand::BoxCommand::Command::Show do
end
it "should print the version details" do
expect(subject).to receive(:format_box_results).with(box_version, env)
expect(subject).to receive(:format_box_results).with(box_version, env, {})
subject.show_box(org_name, box_name, access_token, options)
end
@ -144,6 +144,34 @@ describe VagrantPlugins::CloudCommand::BoxCommand::Command::Show do
subject.execute
end
end
context "with architectures flag set" do
let(:arch_option) { "test-arch" }
before { argv.push("--architectures").push(arch_option) }
it "shouild show box with architectures option set" do
expect(subject).to receive(:show_box) do |*_, opts|
expect(opts[:architectures]).to eq([arch_option])
end
subject.execute
end
end
context "with providers flag set" do
let(:provider_option) { "test-provider" }
before { argv.push("--providers").push(provider_option) }
it "shilud show box with providers option set" do
expect(subject).to receive(:show_box) do |*_, opts|
expect(opts[:providers]).to eq([provider_option])
end
subject.execute
end
end
end
end
end

View File

@ -43,7 +43,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Create do
subject { described_class.new(argv, env) }
it "should add a new provider to the box version" do
expect(version).to receive(:add_provider).with(provider_name)
expect(version).to receive(:add_provider).with(provider_name, nil)
subject.create_provider(org_name, box_name, box_version, provider_name, provider_url, access_token, options)
end
@ -166,6 +166,59 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Create do
subject.execute
end
end
it "should include detected host architecture by default" do
host_arch = double("host-arch")
expect(Vagrant::Util::Platform).to receive(:architecture).and_return(host_arch)
expect(subject).to receive(:create_provider) do |*_, opts|
expect(opts[:architecture]).to eq(host_arch)
end
subject.execute
end
context "with architecture flag" do
let(:arch_option) { "test-arch" }
before { argv.push("--architecture").push(arch_option) }
it "should include the architecture option" do
expect(subject).to receive(:create_provider) do |*args, opts|
expect(opts[:architecture]).to eq(arch_option)
end
subject.execute
end
end
context "with default architecture flag" do
before { argv.push(default_arch_flag) }
context "when flag is enabled" do
let(:default_arch_flag) { "--default-architecture" }
it "should include default architecture with true value" do
expect(subject).to receive(:create_provider) do |*args, opts|
expect(opts[:default_architecture]).to be(true)
end
subject.execute
end
end
context "when flag is disabled" do
let(:default_arch_flag) { "--no-default-architecture" }
it "should include default architecture with false value" do
expect(subject).to receive(:create_provider) do |*args, opts|
expect(opts[:default_architecture]).to be(false)
end
subject.execute
end
end
end
end
end
end

View File

@ -16,7 +16,8 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
let(:organization) { double("organization") }
let(:box) { double("box", versions: [version]) }
let(:version) { double("version", version: box_version, providers: [provider]) }
let(:provider) { double("provider", name: box_version_provider) }
let(:provider) { double("provider", name: box_version_provider, architecture: architecture) }
let(:architecture) { double("test-architecture") }
describe "#delete_provider" do
let(:options) { {} }
@ -30,8 +31,14 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
with(custom_server: anything, access_token: access_token).
and_return(account)
allow(subject).to receive(:with_provider).
with(account: account, org: org_name, box: box_name, version: box_version, provider: box_version_provider).
and_yield(provider)
with(
account: account,
org: org_name,
box: box_name,
version: box_version,
provider: box_version_provider,
architecture: architecture
).and_yield(provider)
allow(provider).to receive(:delete)
end
@ -39,11 +46,11 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
it "should delete the provider" do
expect(provider).to receive(:delete)
subject.delete_provider(org_name, box_name, box_version, box_version_provider, access_token, options)
subject.delete_provider(org_name, box_name, box_version, box_version_provider, architecture, account, options)
end
it "should return zero on success" do
r = subject.delete_provider(org_name, box_name, box_version, box_version_provider, access_token, options)
r = subject.delete_provider(org_name, box_name, box_version, box_version_provider, architecture, account, options)
expect(r).to eq(0)
end
@ -53,7 +60,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
end
it "should return non-zero" do
r = subject.delete_provider(org_name, box_name, box_version, box_version_provider, access_token, options)
r = subject.delete_provider(org_name, box_name, box_version, box_version_provider, architecture, account, options)
expect(r).to be_a(Integer)
expect(r).not_to eq(0)
end
@ -75,11 +82,16 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
let(:client) { double("client", token: access_token) }
before do
allow(VagrantCloud::Account).to receive(:new).and_return(account)
allow(account).to receive(:organization).with(name: org_name).
and_return(organization)
allow(iso_env).to receive(:action_runner).and_return(action_runner)
allow(subject).to receive(:client_login).
and_return(client)
allow(iso_env.ui).to receive(:ask).
and_return("y")
allow(subject).to receive(:select_provider_architecture).
and_return(architecture)
allow(subject).to receive(:delete_provider)
end
@ -115,7 +127,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
it "should delete the provider" do
expect(subject).to receive(:delete_provider).
with(org_name, box_name, version_arg, provider_arg, access_token, anything)
with(org_name, box_name, version_arg, provider_arg, architecture, account, anything)
subject.execute
end
@ -124,6 +136,43 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Delete do
subject.execute
end
context "with architecture argument" do
let(:architecture_argument) { "test-arch" }
before { argv << architecture_argument }
it "should delete the provider" do
expect(subject).to receive(:delete_provider).
with(org_name, box_name, version_arg, provider_arg, architecture_argument, account, anything)
subject.execute
end
it "should not attempt to select the architecture" do
expect(subject).not_to receive(:select_provider_architecture)
subject.execute
end
end
context "with multiple provider architectures" do
let(:box_version) { double("box-version", providers: providers) }
let(:providers) {
[
double("dummy-provider", architecture: "amd64"),
double("dummy-provider", architecture: "arm64")
]
}
before do
expect(subject).to receive(:select_provider_architecture).and_call_original
expect(subject).to receive(:with_version).and_yield(box_version)
end
it "should prompt for architecture selection" do
expect(iso_env.ui).to receive(:ask).and_return("amd64")
subject.execute
end
end
context "with force flag" do
before { argv << "--force" }

View File

@ -12,6 +12,7 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
let(:box_name) { "my-box" }
let(:box_version) { "1.0.0" }
let(:box_version_provider) { "my-provider" }
let(:box_architecture) { "box-architecture" }
let(:account) { double("account") }
let(:organization) { double("organization") }
let(:box) { double("box", versions: [version]) }
@ -31,7 +32,14 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
with(custom_server: anything, access_token: access_token).
and_return(account)
allow(subject).to receive(:with_provider).
with(account: account, org: org_name, box: box_name, version: box_version, provider: box_version_provider).
with(
account: account,
org: org_name,
box: box_name,
version: box_version,
provider: box_version_provider,
architecture: box_architecture
).
and_yield(provider)
allow(provider).to receive(:save)
allow(subject).to receive(:format_box_results)
@ -41,24 +49,60 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
it "should update the provider" do
expect(provider).to receive(:save)
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
subject.update_provider(
org_name,
box_name,
box_version,
box_version_provider,
box_architecture,
provider_url,
access_token,
options
)
end
it "should return 0 on success" do
result = subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
result = subject.update_provider(
org_name,
box_name,
box_version,
box_version_provider,
box_architecture,
provider_url,
access_token,
options
)
expect(result).to eq(0)
end
it "should return non-zero result on error" do
expect(provider).to receive(:save).and_raise(VagrantCloud::Error)
result = subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
result = subject.update_provider(
org_name,
box_name,
box_version,
box_version_provider,
box_architecture,
provider_url,
access_token,
options
)
expect(result).not_to eq(0)
expect(result).to be_a(Integer)
end
it "should not update the URL when unset" do
expect(provider).not_to receive(:url=)
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
subject.update_provider(
org_name,
box_name,
box_version,
box_version_provider,
box_architecture,
provider_url,
access_token,
options
)
end
context "when URL is set" do
@ -66,19 +110,78 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
it "should update the URL" do
expect(provider).to receive(:url=).with(provider_url)
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
subject.update_provider(
org_name,
box_name,
box_version,
box_version_provider,
box_architecture,
provider_url,
access_token,
options
)
end
end
context "with options set" do
let(:checksum) { double("checksum") }
let(:checksum_type) { double("checksum_type") }
let(:options) { {} }
after do
subject.update_provider(
org_name,
box_name,
box_version,
box_version_provider,
box_architecture,
provider_url,
access_token,
options
)
end
it "should not modify option controlled values when unset" do
expect(provider).not_to receive(:checksum=)
expect(provider).not_to receive(:checksum_type=)
expect(provider).not_to receive(:architecture=)
expect(provider).not_to receive(:default_architecture=)
end
context "with checksum options set" do
let(:options) { {checksum: checksum, checksum_type: checksum_type} }
it "should set checksum options before saving" do
expect(provider).to receive(:checksum=).with(checksum)
expect(provider).to receive(:checksum_type=).with(checksum_type)
subject.update_provider(org_name, box_name, box_version, box_version_provider, provider_url, access_token, options)
end
end
context "with architecture option set" do
let(:architecture) { double("architecture") }
let(:options) { {architecture: architecture} }
it "should set architecture before saving" do
expect(provider).to receive(:architecture=).with(architecture)
end
end
context "with default architecture option set" do
context "with true value" do
let(:options) { {default_architecture: true} }
it "should set default architecture to true" do
expect(provider).to receive(:default_architecture=).with(true)
end
end
context "with false value" do
let(:options) { {default_architecture: false} }
it "should set default architecture to false" do
expect(provider).to receive(:default_architecture=).with(false)
end
end
end
end
end
@ -134,13 +237,42 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
before { argv << version_arg }
it "shows help" do
expect { subject.execute }.
to raise_error(Vagrant::Errors::CLIInvalidUsage)
end
context "with architecture argument" do
let(:architecture_arg) { "box-architecture" }
before { argv << architecture_arg }
it "should create the provider" do
expect(subject).to receive(:update_provider).with(org_name, box_name, version_arg, provider_arg, any_args)
expect(subject).
to receive(:update_provider).
with(
org_name,
box_name,
version_arg,
provider_arg,
architecture_arg,
any_args
)
subject.execute
end
it "should not provide URL value" do
expect(subject).to receive(:update_provider).with(org_name, box_name, version_arg, provider_arg, nil, any_args)
expect(subject).
to receive(:update_provider).
with(
org_name,
box_name,
version_arg,
provider_arg,
architecture_arg,
nil,
any_args
)
subject.execute
end
@ -150,7 +282,17 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
before { argv << url_arg }
it "should provide the URL value" do
expect(subject).to receive(:update_provider).with(org_name, box_name, version_arg, provider_arg, url_arg, any_args)
expect(subject).
to receive(:update_provider).
with(
org_name,
box_name,
version_arg,
provider_arg,
architecture_arg,
url_arg,
any_args
)
subject.execute
end
end
@ -162,8 +304,56 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
before { argv.push("--checksum").push(checksum_arg).push("--checksum-type").push(checksum_type_arg) }
it "should include the checksum options" do
expect(subject).to receive(:update_provider).
with(org_name, box_name, version_arg, provider_arg, any_args, hash_including(checksum: checksum_arg, checksum_type: checksum_type_arg))
expect(subject).
to receive(:update_provider).
with(
org_name,
box_name,
version_arg,
provider_arg,
architecture_arg,
any_args,
hash_including(
checksum: checksum_arg,
checksum_type: checksum_type_arg
)
)
subject.execute
end
end
context "with architecture flag" do
let(:architecture_flag) { "test-arch" }
before { argv.push("--architecture").push(architecture_flag) }
it "should include the architecture flag" do
expect(subject).to receive(:update_provider) do |*_, opts|
expect(opts[:architecture]).to eq(architecture_flag)
end
subject.execute
end
end
context "with default architecture flag" do
context "enabled" do
before { argv.push("--default-architecture") }
it "should include default architecture set to true" do
expect(subject).to receive(:update_provider) do |*_, opts|
expect(opts[:default_architecture]).to be(true)
end
subject.execute
end
end
context "disabled" do
before { argv.push("--no-default-architecture") }
it "should include default architecture set to false" do
expect(subject).to receive(:update_provider) do |*_, opts|
expect(opts[:default_architecture]).to be(false)
end
subject.execute
end
end
@ -172,3 +362,5 @@ describe VagrantPlugins::CloudCommand::ProviderCommand::Command::Update do
end
end
end
end
end

View File

@ -20,16 +20,20 @@ describe VagrantPlugins::CloudCommand::Command::Publish do
let(:ui) { Vagrant::UI::Silent.new }
let(:upload_url) { double("upload_url") }
let(:access_token) { double("access_token") }
let(:default_architecture) { double("default-architecture") }
subject { described_class.new(argv, iso_env) }
before do
allow(Vagrant::Util::Platform).to receive(:architecture).
and_return(default_architecture)
allow(iso_env).to receive(:ui).and_return(ui)
allow(File).to receive(:stat).with(box).
and_return(double("box_stat", size: box_size))
allow(VagrantCloud::Account).to receive(:new).
with(custom_server: anything, access_token: anything).
and_return(account)
allow(provider).to receive(:architecture=).with(default_architecture)
end
describe "#upload_box_file" do
@ -148,21 +152,69 @@ describe VagrantPlugins::CloudCommand::Command::Publish do
let(:options) { {} }
it "should not modify the provider" do
expect(provider).not_to receive(:url=)
expect(provider).not_to receive(:checksum=)
expect(provider).not_to receive(:checksum_type=)
expect(provider).not_to receive(:architecture=)
expect(provider).not_to receive(:default_architecture=)
subject.set_provider_info(provider, options)
end
end
context "with options set" do
let(:options) { {url: url, checksum: checksum, checksum_type: checksum_type} }
context "with options" do
let(:options) { {} }
let(:url) { double("url") }
let(:checksum) { double("checksum") }
let(:checksum_type) { double("checksum_type") }
let(:architecture) { double("architecture") }
it "should set info on provider" do
after { subject.set_provider_info(provider, options) }
context "with url set" do
before { options[:url] = url }
it "should set url on provider" do
expect(provider).to receive(:url=).with(url)
end
end
context "with checksum set" do
before do
options[:checksum] = checksum
options[:checksum_type] = checksum_type
end
it "should set checksum on provider" do
expect(provider).to receive(:checksum=).with(checksum)
expect(provider).to receive(:checksum_type=).with(checksum_type)
subject.set_provider_info(provider, options)
end
end
context "with architecture set" do
before { options[:architecture] = architecture }
it "should set architecture on provider" do
expect(provider).to receive(:architecture=).with(architecture)
end
end
context "with default architecture set" do
context "with true value" do
before { options[:default_architecture] = true }
it "should set default architecture to true" do
expect(provider).to receive(:default_architecture=).with(true)
end
end
context "with false value" do
before { options[:default_architecture] = false }
it "should set default architecture to false" do
expect(provider).to receive(:default_architecture=).with(false)
end
end
end
end
end

View File

@ -45,6 +45,7 @@ describe VagrantPlugins::CloudCommand::Command::Search do
end
context "with valid options" do
let(:architecture) { double("architecture") }
let(:provider) { double("provider") }
let(:sort) { double("sort") }
let(:order) { double("order") }
@ -52,6 +53,7 @@ describe VagrantPlugins::CloudCommand::Command::Search do
let(:page) { double("page") }
let(:options) { {
architecture: architecture,
provider: provider,
sort: sort,
order: order,

View File

@ -116,6 +116,34 @@ describe VagrantPlugins::Kernel_V2::VMConfig do
end
end
describe "#box_architecture" do
it "is not required" do
subject.box_architecture = nil
subject.finalize!
assert_valid
end
it "is :auto by default" do
subject.finalize!
assert_valid
expect(subject.box_architecture).to eq(:auto)
end
it "can be set to custom value" do
subject.box_architecture = "test-arch"
subject.finalize!
assert_valid
expect(subject.box_architecture).to eq("test-arch")
end
it "is converted to string" do
subject.box_architecture = :test_arch
subject.finalize!
assert_valid
expect(subject.box_architecture).to eq("test_arch")
end
end
context "#box_check_update" do
it "defaults to true" do
with_temp_env("VAGRANT_BOX_UPDATE_CHECK_DISABLE" => "") do

View File

@ -100,8 +100,11 @@ module Unit
# @param [String] provider
# @return [Pathname]
def box3(name, version, provider, **opts)
args = [name, version, provider.to_s]
args << opts[:architecture].to_s if opts[:architecture]
# Create the directory for the box
box_dir = boxes_dir.join(name, version, provider.to_s)
box_dir = boxes_dir.join(*args)
box_dir.mkpath
# Create the metadata.json for it

View File

@ -210,7 +210,7 @@ describe Vagrant::Action::Builtin::BoxAdd, :skip_windows, :bsdtar do
env[:box_provider] = "virtualbox"
expect(box_collection).to receive(:find).with(
"foo", ["virtualbox"], "0").and_return(box)
"foo", ["virtualbox"], "0", nil).and_return(box)
expect(box_collection).to receive(:add).never
expect(app).to receive(:call).never
@ -903,6 +903,304 @@ describe Vagrant::Action::Builtin::BoxAdd, :skip_windows, :bsdtar do
subject.call(env)
end
context "with box architecture configured" do
before do
allow(Vagrant::Util::Platform).to receive(:architecture).and_return("test-arch")
end
context "set to :auto" do
before do
env[:box_architecture] = :auto
end
it "adds the latest version of a box with only one provider and matching architecture" do
box_path = iso_env.box2_file(:virtualbox)
tf = Tempfile.new(["vagrant-box-latest-version", ".json"]).tap do |f|
f.write(
{
name: "foo/bar",
versions: [
{
version: "0.5",
},
{
version: "0.7",
providers: [
{
name: "virtualbox",
url: "/dev/null/invalid.path",
architecture: "amd64",
default_architecture: true,
},
{
name: "virtualbox",
url: "#{box_path}",
architecture: "test-arch",
default_architecture: false,
}
]
}
]
}.to_json
)
f.close
end
env[:box_url] = tf.path
expect(box_collection).to receive(:add).with(any_args) { |path, name, version, opts|
expect(checksum(path)).to eq(checksum(box_path))
expect(name).to eq("foo/bar")
expect(version).to eq("0.7")
expect(opts[:metadata_url]).to eq("file://#{tf.path}")
expect(opts[:architecture]).to eq(:auto)
true
}.and_return(box)
expect(app).to receive(:call).with(env)
subject.call(env)
end
it "adds the latest version of a box with only one provider and no unknown architecture set as default" do
box_path = iso_env.box2_file(:virtualbox)
tf = Tempfile.new(["vagrant-box-latest-version", ".json"]).tap do |f|
f.write(
{
name: "foo/bar",
versions: [
{
version: "0.5",
},
{
version: "0.7",
providers: [
{
name: "virtualbox",
url: "#{box_path}",
architecture: "unknown",
default_architecture: true,
},
{
name: "virtualbox",
url: "/dev/null/invalid.path",
architecture: "amd64",
default_architecture: false,
}
]
}
]
}.to_json
)
f.close
end
env[:box_url] = tf.path
expect(box_collection).to receive(:add).with(any_args) { |path, name, version, opts|
expect(checksum(path)).to eq(checksum(box_path))
expect(name).to eq("foo/bar")
expect(version).to eq("0.7")
expect(opts[:metadata_url]).to eq("file://#{tf.path}")
expect(opts[:architecture]).to eq(:auto)
true
}.and_return(box)
expect(app).to receive(:call).with(env)
subject.call(env)
end
it "errors adding latest version of a box with only one provider and no matching architecture" do
allow(Vagrant::Util::Platform).to receive(:architecture).and_return("test-arch")
box_path = iso_env.box2_file(:virtualbox)
tf = Tempfile.new(["vagrant-box-latest-version", ".json"]).tap do |f|
f.write(
{
name: "foo/bar",
versions: [
{
version: "0.5",
},
{
version: "0.7",
providers: [
{
name: "virtualbox",
url: "#{box_path}",
architecture: "amd64",
default_architecture: true,
},
{
name: "virtualbox",
url: "/dev/null/invalid.path",
architecture: "arm64",
default_architecture: false,
}
]
}
]
}.to_json
)
f.close
end
env[:box_url] = tf.path
expect {
subject.call(env)
}.to raise_error(Vagrant::Errors::BoxAddNoMatchingVersion)
end
end
context "set to nil" do
before do
env[:box_architecture] = nil
end
it "adds the latest version of a box with only one provider and default architecture" do
box_path = iso_env.box2_file(:virtualbox)
tf = Tempfile.new(["vagrant-box-latest-version", ".json"]).tap do |f|
f.write(
{
name: "foo/bar",
versions: [
{
version: "0.5",
},
{
version: "0.7",
providers: [
{
name: "virtualbox",
url: "#{box_path}",
architecture: "amd64",
default_architecture: true,
},
{
name: "virtualbox",
url: "/dev/null/invalid.path",
architecture: "test-arch",
default_architecture: false,
}
]
}
]
}.to_json
)
f.close
end
env[:box_url] = tf.path
expect(box_collection).to receive(:add).with(any_args) { |path, name, version, opts|
expect(checksum(path)).to eq(checksum(box_path))
expect(name).to eq("foo/bar")
expect(version).to eq("0.7")
expect(opts[:metadata_url]).to eq("file://#{tf.path}")
expect(opts[:architecture]).to be_nil
true
}.and_return(box)
expect(app).to receive(:call).with(env)
subject.call(env)
end
end
context "set to explicit value" do
before do
env[:box_architecture] = "arm64"
end
it "adds the latest version of a box with only one provider and matching architecture" do
box_path = iso_env.box2_file(:virtualbox)
tf = Tempfile.new(["vagrant-box-latest-version", ".json"]).tap do |f|
f.write(
{
name: "foo/bar",
versions: [
{
version: "0.5",
},
{
version: "0.7",
providers: [
{
name: "virtualbox",
url: "#{box_path}",
architecture: "arm64",
default_architecture: false,
},
{
name: "virtualbox",
url: "/dev/null/invalid.path",
architecture: "test-arch",
default_architecture: true,
}
]
}
]
}.to_json
)
f.close
end
env[:box_url] = tf.path
expect(box_collection).to receive(:add).with(any_args) { |path, name, version, opts|
expect(checksum(path)).to eq(checksum(box_path))
expect(name).to eq("foo/bar")
expect(version).to eq("0.7")
expect(opts[:metadata_url]).to eq("file://#{tf.path}")
expect(opts[:architecture]).to eq("arm64")
true
}.and_return(box)
expect(app).to receive(:call).with(env)
subject.call(env)
end
it "errors adding the latest version of a box with only one provider and no matching architecture" do
box_path = iso_env.box2_file(:virtualbox)
tf = Tempfile.new(["vagrant-box-latest-version", ".json"]).tap do |f|
f.write(
{
name: "foo/bar",
versions: [
{
version: "0.5",
},
{
version: "0.7",
providers: [
{
name: "virtualbox",
url: "#{box_path}",
architecture: "amd64",
default_architecture: true,
},
{
name: "virtualbox",
url: "/dev/null/invalid.path",
architecture: "386",
default_architecture: false,
}
]
}
]
}.to_json
)
f.close
end
env[:box_url] = tf.path
expect {
subject.call(env)
}.to raise_error(Vagrant::Errors::BoxAddNoMatchingVersion)
end
end
end
it "adds the latest version of a box with the specified provider" do
box_path = iso_env.box2_file(:vmware)
tf = Tempfile.new(["vagrant-box-specific-provider", ".json"]).tap do |f|
@ -1304,7 +1602,7 @@ describe Vagrant::Action::Builtin::BoxAdd, :skip_windows, :bsdtar do
env[:box_url] = tf.path
expect(box_collection).to receive(:find).
with("foo/bar", "virtualbox", "0.7").and_return(box)
with("foo/bar", "virtualbox", "0.7", nil).and_return(box)
expect(box_collection).to receive(:add).never
expect(app).to receive(:call).never

View File

@ -17,7 +17,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
subject { described_class.new(app, env) }
let(:box_collection) { double("box_collection") }
let(:home_path) { "foo" }
let(:home_path) { double("home-path") }
let(:machine_index) { [] }
let(:iso_env) { isolated_environment }
@ -27,12 +27,12 @@ describe Vagrant::Action::Builtin::BoxRemove do
end
it "deletes the box if it is the only option" do
allow(box_collection).to receive(:all).and_return([["foo", "1.0", :virtualbox]])
allow(box_collection).to receive(:all).and_return([["foo", "1.0", :virtualbox, nil]])
env[:box_name] = "foo"
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(true)
expect(box).to receive(:destroy!).once
@ -54,7 +54,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
env[:box_provider] = "virtualbox"
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(false)
expect(box).to receive(:destroy!).once
@ -76,7 +76,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
env[:box_version] = "1.0"
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(false)
expect(box).to receive(:destroy!).once
@ -87,6 +87,131 @@ describe Vagrant::Action::Builtin::BoxRemove do
expect(env[:box_removed]).to equal(box)
end
context "with architecture" do
let(:architecture) { "test-arch" }
let(:box) do
box_dir = iso_env.box3("foo", "1.0", :virtualbox, architecture: architecture)
Vagrant::Box.new("foo", :virtualbox, "1.0", box_dir, architecture: architecture)
end
it "deletes the box if it is the only option" do
allow(box_collection).to receive(:all).and_return([["foo", "1.0", :virtualbox, architecture]])
env[:box_name] = "foo"
expect(box_collection).to receive(:find).
with("foo", :virtualbox, "1.0", architecture).
and_return(box)
expect(box_collection).to receive(:clean).
with(box.name).
and_return(true)
expect(box).to receive(:destroy!).once
expect(app).to receive(:call).with(env).once
subject.call(env)
expect(env[:box_removed]).to equal(box)
end
it "deletes the box with the specified provider if given" do
allow(box_collection).to receive(:all)
.and_return([
["foo", "1.0", :virtualbox, architecture],
["foo", "1.0", :vmware, architecture],
])
env[:box_name] = "foo"
env[:box_provider] = "virtualbox"
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0", architecture).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(false)
expect(box).to receive(:destroy!).once
expect(app).to receive(:call).with(env).once
subject.call(env)
expect(env[:box_removed]).to equal(box)
end
it "deletes the box with the specified version if given" do
allow(box_collection).to receive(:all)
.and_return([
["foo", "1.0", :virtualbox, architecture],
["foo", "1.1", :virtualbox, architecture],
])
env[:box_name] = "foo"
env[:box_version] = "1.0"
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0", architecture).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(false)
expect(box).to receive(:destroy!).once
expect(app).to receive(:call).with(env).once
subject.call(env)
expect(env[:box_removed]).to equal(box)
end
it "deletes the box with the specificed version and architecture" do
allow(box_collection).to receive(:all)
.and_return([
["foo", "1.0", :virtualbox, architecture],
["foo", "1.0", :virtualbox, "other-arch"],
])
env[:box_name] = "foo"
env[:box_version] = "1.0"
env[:box_architecture] = architecture
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0", architecture).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(false)
expect(box).to receive(:destroy!).once
expect(app).to receive(:call).with(env).once
subject.call(env)
expect(env[:box_removed]).to equal(box)
end
it "errors when box with specified version does not included specified architecture" do
allow(box_collection).to receive(:all)
.and_return([
["foo", "1.0", :virtualbox, architecture],
["foo", "1.0", :virtualbox, "other-arch"],
])
env[:box_name] = "foo"
env[:box_version] = "1.0"
env[:box_architecture] = "unknown-arch"
expect {
subject.call(env)
}.to raise_error(Vagrant::Errors::BoxRemoveArchitectureNotFound)
end
it "errors when box with specified version has multiple architectures" do
allow(box_collection).to receive(:all)
.and_return([
["foo", "1.0", :virtualbox, architecture],
["foo", "1.0", :virtualbox, "other-arch"],
])
env[:box_name] = "foo"
env[:box_version] = "1.0"
expect {
subject.call(env)
}.to raise_error(Vagrant::Errors::BoxRemoveMultiArchitecture)
end
end
context "checking if a box is in use" do
def new_entry(name, provider, version, valid=true)
Vagrant::MachineIndex::Entry.new.tap do |entry|
@ -117,7 +242,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
it "does delete if the box is not in use" do
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box).to receive(:destroy!).once
expect(box_collection).to receive(:clean).with(box.name)
.and_return(true)
@ -133,7 +258,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
with(anything, env).and_return(result)
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(true)
expect(box).to receive(:destroy!).once
@ -149,7 +274,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
with(anything, env).and_return(result)
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box).to receive(:destroy!).never
subject.call(env)
@ -164,7 +289,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
with(anything, env).and_return(result)
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box).to receive(:destroy!).never
subject.call(env)
@ -178,7 +303,7 @@ describe Vagrant::Action::Builtin::BoxRemove do
with(anything, env).and_return(result)
expect(box_collection).to receive(:find).with(
"foo", :virtualbox, "1.0").and_return(box)
"foo", :virtualbox, "1.0", nil).and_return(box)
expect(box_collection).to receive(:clean).with(box.name)
.and_return(true)
expect(box).to receive(:destroy!)

View File

@ -36,11 +36,11 @@ describe Vagrant::BoxCollection, :skip_windows, :bsdtar do
# Verify some output
results = subject.all
expect(results.length).to eq(5)
expect(results.include?(["foo", "1.0", :virtualbox])).to be
expect(results.include?(["foo", "1.0", :vmware])).to be
expect(results.include?(["bar", "0", :ec2])).to be
expect(results.include?(["foo/bar", "1.0", :virtualbox])).to be
expect(results.include?(["foo:colon", "1.0", :virtualbox])).to be
expect(results).to include(["foo", "1.0", :virtualbox, nil])
expect(results).to include(["foo", "1.0", :vmware, nil])
expect(results).to include(["bar", "0", :ec2, nil])
expect(results).to include(["foo/bar", "1.0", :virtualbox, nil])
expect(results).to include(["foo:colon", "1.0", :virtualbox, nil])
end
it "should return the boxes and their providers even if box has wrong version" do
@ -57,11 +57,11 @@ describe Vagrant::BoxCollection, :skip_windows, :bsdtar do
# Verify some output
results = subject.all
expect(results.length).to eq(4)
expect(results.include?(["foo", "1.0", :virtualbox])).not_to be
expect(results.include?(["foo", "1.0", :vmware])).to be
expect(results.include?(["bar", "0", :ec2])).to be
expect(results.include?(["foo/bar", "1.0", :virtualbox])).to be
expect(results.include?(["foo:colon", "1.0", :virtualbox])).to be
expect(results).not_to include(["foo", "1.0", :virtualbox, nil])
expect(results).to include(["foo", "1.0", :vmware, nil])
expect(results).to include(["bar", "0", :ec2, nil])
expect(results).to include(["foo/bar", "1.0", :virtualbox, nil])
expect(results).to include(["foo:colon", "1.0", :virtualbox, nil])
end
it 'does not raise an exception when a file appears in the boxes dir' do
@ -175,7 +175,7 @@ describe Vagrant::BoxCollection, :skip_windows, :bsdtar do
# Make sure the results still exist
results = subject.all
expect(results.length).to eq(1)
expect(results.include?(["foo", "1.0", :vmware])).to be
expect(results).to include(["foo", "1.0", :vmware, nil])
end
it "doesn't remove the directory if a version exists" do
@ -195,7 +195,7 @@ describe Vagrant::BoxCollection, :skip_windows, :bsdtar do
# Make sure the results still exist
results = subject.all
expect(results.length).to eq(1)
expect(results.include?(["foo", "1.0", :virtualbox])).to be
expect(results).to include(["foo", "1.0", :virtualbox, nil])
end
end

View File

@ -9,34 +9,32 @@ describe Vagrant::BoxMetadata do
include_context "unit"
let(:raw) do
<<-RAW
{
"name": "foo",
"description": "bar",
"versions": [
name: "foo",
description: "bar",
versions: [
{
"version": "1.0.0",
"providers": [
{ "name": "virtualbox" },
{ "name": "vmware" }
version: "1.0.0",
providers: [
{ name: "virtualbox" },
{ name: "vmware" }
],
},
{
version: "1.1.5",
providers: [
{ name: "virtualbox" }
]
},
{
"version": "1.1.5",
"providers": [
{ "name": "virtualbox" }
]
},
{
"version": "1.1.0",
"providers": [
{ "name": "virtualbox" },
{ "name": "vmware" }
version: "1.1.0",
providers: [
{ name: "virtualbox" },
{ name: "vmware" }
]
}
]
}
RAW
}.to_json
end
subject { described_class.new(raw) }
@ -53,9 +51,7 @@ describe Vagrant::BoxMetadata do
context "with poorly formatted JSON" do
let(:raw) {
<<-RAW
{ "name": "foo", }
RAW
{name: "foo"}.to_json + ","
}
it "raises an exception" do
@ -66,15 +62,14 @@ describe Vagrant::BoxMetadata do
context "with poorly formatted version" do
let(:raw) {
<<-RAW
{ "name": "foo",
"versions": [
{
"version": "I AM NOT VALID"
name: "foo",
versions: [
{
version: "I AM NOT VALID"
}
]
}
RAW
}.to_json
}
it "raises an exception" do
@ -124,6 +119,213 @@ describe Vagrant::BoxMetadata do
["1.0.0", "1.1.0"])
end
end
context "with architecture" do
let(:raw) do
{
name: "foo",
description: "bar",
versions: [
{
version: "1.0.0",
providers: [
{
name: "virtualbox",
default_architecture: true,
architecture: "amd64"
},
{
name: "virtualbox",
default_architecture: false,
architecture: "arm64"
},
{
name: "vmware",
default_architecture: true,
architecture: "arm64"
},
{
name: "vmware",
default_architecture: false,
architecture: "amd64"
}
],
},
{
version: "1.1.5",
providers: [
{
name: "virtualbox",
architecture: "amd64",
default_architecture: true,
}
]
},
{
version: "1.1.6",
providers: [
{
name: "virtualbox",
architecture: "arm64",
default_architecture: true,
},
]
},
{
version: "1.1.0",
providers: [
{
name: "virtualbox",
architecture: "amd64",
default_architecture: true,
},
{
name: "vmware",
architecture: "amd64",
default_architecture: true,
}
]
},
{
version: "2.0.0",
providers: [
{
name: "vmware",
architecture: "arm64",
default_architecture: true,
}
]
}
]
}.to_json
end
subject { described_class.new(raw) }
before { allow(Vagrant::Util::Platform).to receive(:architecture).and_return("amd64") }
describe "#version" do
it "matches an exact version" do
result = subject.version("1.0.0")
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.0.0")
end
it "matches a constraint with latest matching version" do
result = subject.version(">= 1.0")
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.1.5")
end
it "matches complex constraints" do
result = subject.version(">= 0.9, ~> 1.0.0")
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.0.0")
end
context "with provider filter" do
it "matches the constraint that has the given provider" do
result = subject.version(">= 0", provider: :vmware)
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.1.0")
end
it "matches the exact version that has the given provider" do
result = subject.version("1.0.0", provider: :virtualbox)
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.0.0")
end
it "does not match exact version that has given provider but not host architecture" do
result = subject.version("1.1.6", provider: :virtualbox)
expect(result).to be_nil
end
context "with architecture filter" do
it "matches the exact version that has provider with host architecture when using :auto" do
result = subject.version("1.0.0", provider: :virtualbox, architecture: :auto)
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.0.0")
end
it "matches the exact version that has provider with defined host architecture" do
result = subject.version("1.0.0", provider: :virtualbox, architecture: "arm64")
expect(result).to_not be_nil
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.0.0")
end
it "does not match the exact version that has provider with defined host architecture" do
result = subject.version("1.0.0", provider: :virtualbox, architecture: "ppc64")
expect(result).to be_nil
end
end
end
context "with architecture filter" do
it "matches a constraint that has the detected host architecture" do
result = subject.version("> 0", architecture: :auto)
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.1.5")
end
it "matches a constraint that has the provided architecture" do
result = subject.version("> 0", architecture: "arm64")
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("2.0.0")
end
it "matches exact version that has the provided architecture" do
result = subject.version("1.0.0", architecture: "arm64")
expect(result).to be_kind_of(Vagrant::BoxMetadata::Version)
expect(result.version).to eq("1.0.0")
end
it "does not match exact version that does not have provided architecture" do
result = subject.version("2.0.0", architecture: "amd64")
expect(result).to be_nil
end
end
end
describe "#versions" do
it "returns the versions it contained" do
expect(subject.versions).
to eq(["1.0.0", "1.1.0", "1.1.5", "1.1.6", "2.0.0"])
end
context "with provider filter" do
it "filters versions" do
expect(subject.versions(provider: :vmware)).
to eq(["1.0.0", "1.1.0", "2.0.0"])
end
end
context "with architecture filter" do
it "filters versions" do
expect(subject.versions(architecture: "arm64")).
to eq(["1.0.0", "1.1.6", "2.0.0"])
end
it "returns none when no matching architecture available" do
expect(subject.versions(architecture: "other")).
to be_empty
end
it "filters based on host architecture when :auto used" do
expect(subject.versions(architecture: :auto)).
to eq(subject.versions(architecture: "amd64"))
end
end
end
end
end
describe Vagrant::BoxMetadata::Version do
@ -203,4 +405,28 @@ describe Vagrant::BoxMetadata::Provider do
expect(subject.checksum_type).to be_nil
end
end
describe "architecture" do
it "is set properly" do
raw["architecture"] = "test-arch"
expect(subject.architecture).to eq("test-arch")
end
it "is nil if not set" do
expect(subject.architecture).to be_nil
end
end
describe "#architecture_support?" do
it "is false if architecture is not supported" do
expect(subject.architecture_support?).to be(false)
end
it "is true if architecture is supported" do
raw["default_architecture"] = false
expect(subject.architecture_support?).to be(true)
end
end
end

View File

@ -19,6 +19,7 @@ describe Vagrant::Box, :skip_windows do
let(:name) { "foo" }
let(:provider) { :virtualbox }
let(:version) { "1.0" }
let(:architecture) { "test-architecture" }
let(:directory) { environment.box3("foo", "1.0", :virtualbox) }
subject { described_class.new(name, provider, version, directory) }
@ -209,6 +210,154 @@ describe Vagrant::Box, :skip_windows do
expect(result[1].version).to eq("1.1")
expect(result[2].url).to eq("bar")
end
context "with architecture" do
subject do
described_class.new(
name, provider, version, directory,
architecture: architecture,
metadata_url: "foo"
)
end
it "raises an exception if no metadata_url is set" do
subject = described_class.new(
name, provider, version, directory,
architecture: architecture,
)
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(
{
name: "foo",
versions: [ { version: "1.0" } ]
}.to_json
)
allow(subject).to receive(:load_metadata).and_return(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(
{
name: "foo",
versions: [
{version: "1.0"},
{
version: "1.1",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: architecture,
}
]
}
]
}.to_json
)
allow(subject).to receive(:load_metadata).and_return(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 nil if update does not support architecture" do
metadata = Vagrant::BoxMetadata.new(
{
name: "foo",
versions: [
{version: "1.0"},
{
version: "1.1",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: "other-architecture",
}
]
}
]
}.to_json
)
allow(subject).to receive(:load_metadata).and_return(metadata)
result = subject.has_update?
expect(result).to be_nil
end
it "returns the updated box info within constraints" do
metadata = Vagrant::BoxMetadata.new(
{
name: "foo",
versions: [
{
version: "1.0",
},
{
version: "1.1",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: architecture
},
]
},
{
version: "1.2",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: "other-architecture",
},
]
},
{
version: "1.4",
providers: [
{
name: "virtualbox",
url: "bar",
architecture: architecture
}
]
}
]
}.to_json
)
allow(subject).to receive(:load_metadata).and_return(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
end
context "#automatic_update_check_allowed?" do
@ -236,12 +385,13 @@ describe Vagrant::Box, :skip_windows do
context "#in_use?" do
let(:index) { [] }
def new_entry(name, provider, version)
def new_entry(name, provider, version, architecture=nil)
Vagrant::MachineIndex::Entry.new.tap do |entry|
entry.extra_data["box"] = {
"name" => name,
"provider" => provider,
"version" => version,
"architecture" => architecture,
}
end
end
@ -261,6 +411,27 @@ describe Vagrant::Box, :skip_windows do
expect(subject.in_use?(index)).to eq([matching])
end
context "with architecture information" do
subject { described_class.new(name, provider, version, directory, architecture: architecture) }
it "returns nil if the index has no matching entries" do
index << new_entry("foo", "bar", "1.0", "amd64")
index << new_entry("foo", "baz", "1.2", "arm64")
index << new_entry(name, provider.to_s, version, "random-arch")
expect(subject).to_not be_in_use(index)
end
it "returns matching entries if they exist" do
matching = new_entry(name, provider.to_s, version, architecture)
index << new_entry("foo", "bar", "1.0", "amd64")
index << matching
index << new_entry("foo", "baz", "1.2")
expect(subject.in_use?(index)).to eq([matching])
end
end
end
context "#load_metadata" do

View File

@ -26,6 +26,7 @@ describe Vagrant::Machine do
double("box").tap do |b|
allow(b).to receive(:name).and_return("foo")
allow(b).to receive(:provider).and_return(:dummy)
allow(b).to receive(:architecture)
allow(b).to receive(:version).and_return("1.0")
end
end
@ -580,6 +581,7 @@ describe Vagrant::Machine do
box = double("box")
allow(box).to receive(:name).and_return("foo")
allow(box).to receive(:provider).and_return(:bar)
allow(box).to receive(:architecture)
allow(box).to receive(:version).and_return("1.2.3")
subject.box = box
@ -599,6 +601,7 @@ describe Vagrant::Machine do
expect(entry.extra_data["box"]).to eq({
"name" => box.name,
"provider" => box.provider.to_s,
"architecture" => nil,
"version" => box.version,
})
env.machine_index.release(entry)

View File

@ -11,6 +11,70 @@ describe Vagrant::Util::Platform do
after { described_class.reset! }
subject { described_class }
describe "#architecture" do
let(:cpu_string) { "unknown" }
before do
allow(RbConfig::CONFIG).
to receive(:[]).with("target_cpu").
and_return(cpu_string)
end
context "when cpu is x86_64" do
let(:cpu_string) { "x86_64" }
it "should be mapped to amd64" do
expect(described_class.architecture).to eq("amd64")
end
end
context "when cpu is i386" do
let(:cpu_string) { "i386" }
it "should be mapped to 386" do
expect(described_class.architecture).to eq("386")
end
end
context "when cpu is arm64" do
let(:cpu_string) { "arm64" }
it "should be arm64" do
expect(described_class.architecture).to eq("arm64")
end
end
context "when cpu is aarch64" do
let(:cpu_string) { "aarch64" }
it "should be mapped to arm64" do
expect(described_class.architecture).to eq("arm64")
end
end
context "when cpu is unmapped value" do
let(:cpu_string) { "custom-cpu" }
it "should be returned as-is" do
expect(described_class.architecture).to eq(cpu_string)
end
end
context "when environment variable override is set" do
let(:host_override) { "custom-host-override" }
before do
allow(ENV).to receive(:[]).
with("VAGRANT_HOST_ARCHITECTURE").
and_return(host_override)
end
it "should return the custom override" do
expect(subject.architecture).to eq(host_override)
end
end
end
describe "#cygwin_path" do
let(:path) { "C:\\msys2\\home\\vagrant" }
let(:updated_path) { "/home/vagrant" }

View File

@ -266,6 +266,44 @@ describe Vagrant::Vagrantfile do
expect(box.version).to eq("1.3")
end
it "configures with the custom box architecture" do
register_provider("foo")
configure do |config|
config.vm.box = "base"
config.vm.box_architecture = "custom-arch"
end
results = subject.machine_config(:default, :foo, boxes)
config = results[:config]
expect(config.vm.box).to eq("base")
expect(config.vm.box_architecture).to eq("custom-arch")
end
it "configures with the default box architecture" do
register_provider("foo")
configure do |config|
config.vm.box = "base"
end
results = subject.machine_config(:default, :foo, boxes)
config = results[:config]
expect(config.vm.box).to eq("base")
expect(config.vm.box_architecture).to eq(:auto)
end
it "configures box architecture to nil" do
register_provider("foo")
configure do |config|
config.vm.box = "base"
config.vm.box_architecture = nil
end
results = subject.machine_config(:default, :foo, boxes)
config = results[:config]
expect(config.vm.box).to eq("base")
expect(config.vm.box_architecture).to be_nil
end
it "configures with box config of other supported formats" do
register_provider("foo", nil, box_format: "bar")