Files
vagrant-libvirt/spec/unit/action/destroy_domain_spec.rb
Darragh Bailey 27a541bba9 Validate partial mocks (#1417)
Switch to using explicit references to objects to be partially mocked
and remove the need to resolve the string constants as this will catch
more instances of calls to invalid or missing methods.

Rework how the vm is added to the machine for one of the tests as it is
not a method and instead is provided via internal state being exposed
with a helper.
2021-12-03 11:28:21 +00:00

208 lines
8.5 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
require 'support/sharedcontext'
require 'support/libvirt_context'
require 'vagrant-libvirt/action/destroy_domain'
describe VagrantPlugins::ProviderLibvirt::Action::DestroyDomain do
subject { described_class.new(app, env) }
include_context 'unit'
include_context 'libvirt'
let(:driver) { double('driver') }
let(:libvirt_domain) { double('libvirt_domain') }
let(:libvirt_client) { double('libvirt_client') }
let(:servers) { double('servers') }
let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) }
before do
allow(machine.provider).to receive('driver').and_return(driver)
allow(driver).to receive(:connection).and_return(connection)
allow(logger).to receive(:info)
end
describe '#call' do
before do
allow(connection).to receive(:client).and_return(libvirt_client)
allow(libvirt_client).to receive(:lookup_domain_by_uuid)
.and_return(libvirt_domain)
allow(libvirt_domain).to receive(:name).and_return('vagrant-test_default')
allow(connection).to receive(:servers).and_return(servers)
allow(servers).to receive(:get).and_return(domain)
# always see this at the start of #call
expect(ui).to receive(:info).with('Removing domain...')
end
context 'when no snapshots' do
let(:root_disk) { double('libvirt_root_disk') }
before do
allow(libvirt_domain).to receive(:list_snapshots).and_return([])
allow(libvirt_domain).to receive(:has_managed_save?).and_return(nil)
allow(root_disk).to receive(:name).and_return('vagrant-test_default.img')
end
context 'when box only has one root disk' do
it 'calls fog to destroy volumes' do
expect(domain).to receive(:destroy).with(destroy_volumes: true)
expect(subject.call(env)).to be_nil
end
context 'when has additional disks' do
let(:vagrantfile_providerconfig) do
<<-EOF
libvirt.storage :file
EOF
end
let(:domain_xml_file) { 'additional_disks_domain.xml' }
let(:extra_disk) { double('libvirt_extra_disk') }
before do
allow(extra_disk).to receive(:name).and_return('vagrant-test_default-vdb.qcow2')
allow(domain).to receive(:volumes).and_return([root_disk, extra_disk])
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
end
it 'destroys disks individually' do
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(extra_disk).to receive(:destroy) # extra disk remove
expect(root_disk).to receive(:destroy) # root disk remove
expect(subject.call(env)).to be_nil
end
end
end
context 'when box has multiple disks' do
let(:domain_xml_file) { 'box_multiple_disks.xml' }
it 'calls fog to destroy volumes' do
expect(domain).to receive(:destroy).with(destroy_volumes: true)
expect(subject.call(env)).to be_nil
end
context 'when has additional disks' do
let(:domain_xml_file) { 'box_multiple_disks_and_additional_disks.xml' }
let(:vagrantfile_providerconfig) do
<<-EOF
libvirt.storage :file
libvirt.storage :file
EOF
end
let(:domain_disks) {[
[double('box-disk-1'), 'vagrant-test_default.img'],
[double('box-disk-2'), 'vagrant-test_default_1.img'],
[double('box-disk-3'), 'vagrant-test_default_2.img'],
[double('additional-disk-1'), 'vagrant-test_default-vdd.qcow2'],
[double('additional-disk-2'), 'vagrant-test_default-vde.qcow2'],
]}
before do
allow(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
allow(domain).to receive(:volumes).and_return(domain_disks.map { |a| a.first })
end
it 'destroys disks individually' do
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
context 'when has disks added via custom virsh commands' do
let(:domain_xml_file) { 'box_multiple_disks_and_additional_and_custom_disks.xml' }
let(:domain_disks) {[
[double('box-disk-1'), 'vagrant-test_default.img'],
[double('box-disk-2'), 'vagrant-test_default_1.img'],
[double('box-disk-3'), 'vagrant-test_default_2.img'],
[double('additional-disk-1'), 'vagrant-test_default-vdd.qcow2'],
[double('additional-disk-2'), 'vagrant-test_default-vde.qcow2'],
[double('custom-disk-1'), 'vagrant-test_default-vdf.qcow2'],
]}
it 'only destroys expected disks' do
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected.*/)
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
next if disk == domain_disks.last.first
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
context 'without aliases' do
let(:domain_xml_file) { 'box_multiple_disks_and_additional_and_custom_disks_no_aliases.xml' }
it 'only destroys expected disks' do
expect(ui).to receive(:warn).with(/Destroying machine that was originally created without device aliases.*/)
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected/)
expect(ui).to receive(:warn).with(/box metadata not available to get volume list during destroy, assuming inferred list/)
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
# ignore box disks 2 and 3 and the last custom disk
next if domain_disks.last.first == disk
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
context 'with box metadata' do
let(:box) { instance_double(::Vagrant::Box) }
before do
allow(env[:machine]).to receive(:box).and_return(box)
allow(box).to receive(:metadata).and_return(Hash[
'disks' => [
{:name => 'box-disk-1'},
{:name => 'box-disk-2'},
{:name => 'box-disk-3'},
]
])
end
it 'only destroys expected disks' do
expect(ui).to receive(:warn).with(/Destroying machine that was originally created without device aliases.*/)
expect(ui).to receive(:warn).with(/Unexpected number of volumes detected/)
domain_disks.each do |disk, name|
expect(disk).to receive(:name).and_return(name).at_least(:once)
# ignore box disks 2 and 3 and the last custom disk
next if domain_disks.last.first == disk
expect(disk).to receive(:destroy)
end
expect(domain).to receive(:destroy).with(destroy_volumes: false)
expect(subject.call(env)).to be_nil
end
end
end
end
end
end
context 'when has CDROMs attached' do
let(:vagrantfile_providerconfig) do
<<-EOF
libvirt.storage :file, :device => :cdrom
EOF
end
let(:domain_xml_file) { 'cdrom_domain.xml' }
it 'uses explicit removal of disks' do
expect(domain).to receive(:volumes).and_return([root_disk, nil])
expect(libvirt_domain).to receive(:xml_desc).and_return(domain_xml)
expect(domain).to_not receive(:destroy).with(destroy_volumes: true)
expect(root_disk).to receive(:destroy) # root disk remove
expect(subject.call(env)).to be_nil
end
end
end
end
end