Chris Roberts 6f707c829d Catch any StandardError exception while waiting for Windows reboot
This prevents any unexpected connection related error from breaking
the wait loop while windows reboots. If an underlying problem unrelated
to the guest is causing exceptions, the exception will still be raised
to the user, simply after the loop has exceeded the defined maximum
wait time.

Fixes #11238
2020-03-03 17:02:04 -08:00

116 lines
4.1 KiB
Ruby

require_relative "../../../../base"
require Vagrant.source_root.join("plugins/guests/windows/cap/reboot")
describe "VagrantPlugins::GuestWindows::Cap::Reboot" do
let(:described_class) do
VagrantPlugins::GuestWindows::Plugin.components.guest_capabilities[:windows].get(:wait_for_reboot)
end
let(:vm) { double("vm") }
let(:config) { double("config") }
let(:machine) { double("machine", ui: ui) }
let(:guest) { double("guest") }
let(:communicator) { double("communicator") }
let(:ui) { double("ui") }
before do
allow(machine).to receive(:communicate).and_return(communicator)
allow(machine).to receive(:guest).and_return(guest)
allow(machine.guest).to receive(:ready?).and_return(true)
allow(machine).to receive(:config).and_return(config)
allow(config).to receive(:vm).and_return(vm)
allow(ui).to receive(:info)
end
describe ".reboot" do
before do
allow(vm).to receive(:communicator).and_return(:winrm)
end
it "reboots the vm" do
allow(communicator).to receive(:execute)
expect(communicator).to receive(:test).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0)
expect(communicator).to receive(:execute).with(/shutdown/, { shell: :powershell }).and_return(0)
expect(described_class).to receive(:wait_for_reboot)
described_class.reboot(machine)
end
context "user output" do
before do
allow(communicator).to receive(:execute)
allow(described_class).to receive(:wait_for_reboot)
end
after { described_class.reboot(machine) }
it "sends message to user that guest is rebooting" do
expect(communicator).to receive(:test).and_return(true)
expect(ui).to receive(:info)
end
end
context "with exceptions while waiting for reboot" do
before { allow(described_class).to receive(:sleep) }
it "should retry on any standard error" do
allow(communicator).to receive(:execute)
expect(communicator).to receive(:test).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0)
expect(communicator).to receive(:execute).with(/shutdown/, { shell: :powershell }).and_return(0)
expect(described_class).to receive(:wait_for_reboot).and_raise(StandardError)
expect(described_class).to receive(:wait_for_reboot)
described_class.reboot(machine)
end
it "should not retry when exception is not a standard error" do
allow(communicator).to receive(:execute)
expect(communicator).to receive(:test).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0)
expect(communicator).to receive(:execute).with(/shutdown/, { shell: :powershell }).and_return(0)
expect(described_class).to receive(:wait_for_reboot).and_raise(Exception)
expect { described_class.reboot(machine) }.to raise_error(Exception)
end
end
end
describe "winrm communicator" do
before do
allow(vm).to receive(:communicator).and_return(:winrm)
end
describe ".wait_for_reboot" do
it "runs reboot detect script" do
expect(communicator).to receive(:execute).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0)
allow(communicator).to receive(:execute)
described_class.wait_for_reboot(machine)
end
it "fixes symlinks to network shares" do
allow(communicator).to receive(:execute).and_return(0)
expect(communicator).to receive(:execute).with('net use', { error_check: false, shell: :powershell })
described_class.wait_for_reboot(machine)
end
end
end
describe "ssh communicator" do
before do
allow(vm).to receive(:communicator).and_return(:ssh)
end
describe ".wait_for_reboot" do
it "does execute Windows reboot detect script" do
expect(communicator).to receive(:execute).with(/# Function/, { error_check: false, shell: :powershell }).and_return(0)
expect(communicator).to receive(:execute).with('net use', { error_check: false, shell: :powershell })
described_class.wait_for_reboot(machine)
end
end
end
end