Files
vagrant-libvirt/spec/unit/action/wait_till_up_spec.rb
Darragh Bailey 1fe5a80516 Ensure state is correct reflected in global-status (#1292)
Vagrant relies on the side effect of checking the machine state to
trigger updating of the state in the global machine index. As a
consequence any action should not inspect the domain state directly and
instead should access the machine state.

Additionally as part of the up/start actions should switch to built-in
WaitForCommunicator which will inspect the machine states by default to
align with the expected state updating side effects that would be in
effect for any internal provider shipped with vagrant.

Closes: #948
Partial-Fix: #193
2021-05-20 13:36:23 +01:00

129 lines
4.6 KiB
Ruby

require 'vagrant-libvirt/action/wait_till_up'
require 'vagrant-libvirt/errors'
require 'spec_helper'
require 'support/sharedcontext'
require 'support/libvirt_context'
describe VagrantPlugins::ProviderLibvirt::Action::WaitTillUp do
subject { described_class.new(app, env) }
include_context 'vagrant-unit'
include_context 'libvirt'
include_context 'unit'
let (:driver) { VagrantPlugins::ProviderLibvirt::Driver.new env[:machine] }
describe '#call' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Provider).to receive(:driver)
.and_return(driver)
allow(driver).to receive(:get_domain).and_return(domain)
allow(driver).to receive(:state).and_return(:running)
end
context 'when machine does not exist' do
before do
allow(driver).to receive(:get_domain).and_return(nil)
end
it 'raises exception' do
expect(app).to_not receive(:call)
expect { subject.call(env) }.to raise_error(::VagrantPlugins::ProviderLibvirt::Errors::NoDomainError,
/No domain found. Domain dummy-vagrant_dummy not found/)
end
end
context 'when machine is booting' do
context 'if interrupted looking for IP' do
before do
env[:interrupted] = true
end
it 'should exit' do
expect(app).to_not receive(:call)
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
expect(subject.call(env)).to be_nil
end
end
context 'multiple timeouts waiting for IP' do
before do
allow(env).to receive(:[]).and_call_original
allow(env).to receive(:[]).with(:interrupted).and_return(false)
allow(logger).to receive(:debug)
allow(logger).to receive(:info)
end
it 'should abort after hitting limit' do
expect(domain).to receive(:wait_for).at_least(300).times.and_raise(::Fog::Errors::TimeoutError)
expect(app).to_not receive(:call)
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
expect(ui).to_not receive(:info).with('Waiting for SSH to become available...')
expect(env[:machine].communicate).to_not receive(:ready?)
expect {subject.call(env) }.to raise_error(::Fog::Errors::TimeoutError)
end
end
end
context 'when machine boots and ip available' do
before do
allow(domain).to receive(:wait_for).and_return(true)
allow(env).to receive(:[]).and_call_original
allow(env).to receive(:[]).with(:interrupted).and_return(false)
allow(driver).to receive(:get_domain_ipaddress).and_return('192.168.121.2')
end
it 'should call the next hook' do
expect(app).to receive(:call)
expect(ui).to receive(:info).with('Waiting for domain to get an IP address...')
expect(logger).to receive(:debug).with(/Searching for IP for MAC address: .*/)
expect(logger).to receive(:info).with('Got IP address 192.168.121.2')
expect(logger).to receive(:info).with(/Time for getting IP: .*/)
expect(subject.call(env)).to be_nil
end
end
end
describe '#recover' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:get_domain).and_return(machine)
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
.and_return(:not_created)
allow(env).to receive(:[]).and_call_original
end
it 'should do nothing by default' do
expect(env).to_not receive(:[]).with(:action_runner) # cleanup
expect(subject.recover(env)).to be_nil
end
context 'with machine coming up' do
before do
allow_any_instance_of(VagrantPlugins::ProviderLibvirt::Driver).to receive(:state)
.and_return(:running)
env[:destroy_on_error] = true
end
context 'and user has disabled destroy on failure' do
before do
env[:destroy_on_error] = false
end
it 'skips terminate on failure' do
expect(env).to_not receive(:[]).with(:action_runner) # cleanup
expect(subject.recover(env)).to be_nil
end
end
context 'and using default settings' do
let(:runner) { double('runner') }
it 'deletes VM on failure' do
expect(env).to receive(:[]).with(:action_runner).and_return(runner) # cleanup
expect(runner).to receive(:run)
expect(subject.recover(env)).to be_nil
end
end
end
end
end