151 lines
5.6 KiB
Ruby
151 lines
5.6 KiB
Ruby
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
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) { Vagrant::UI::Silent.new }
|
|
|
|
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)
|
|
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).and_call_original
|
|
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
|
|
|
|
context "reboot configuration" do
|
|
before 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)
|
|
allow(described_class).to receive(:sleep)
|
|
allow(described_class).to receive(:wait_for_reboot).and_raise(StandardError)
|
|
end
|
|
|
|
context "default retry duration value" do
|
|
let(:max_retries) { (described_class::DEFAULT_MAX_REBOOT_RETRY_DURATION / described_class::WAIT_SLEEP_TIME) + 2 }
|
|
|
|
it "should receive expected number of wait_for_reboot calls" do
|
|
expect(described_class).to receive(:wait_for_reboot).exactly(max_retries).times
|
|
expect { described_class.reboot(machine) }.to raise_error(StandardError)
|
|
end
|
|
end
|
|
|
|
context "with custom retry duration value" do
|
|
let(:duration) { 10 }
|
|
let(:max_retries) { (duration / described_class::WAIT_SLEEP_TIME) + 2 }
|
|
|
|
before do
|
|
expect(ENV).to receive(:fetch).with("VAGRANT_MAX_REBOOT_RETRY_DURATION", anything).and_return(duration)
|
|
end
|
|
|
|
it "should receive expected number of wait_for_reboot calls" do
|
|
expect(described_class).to receive(:wait_for_reboot).exactly(max_retries).times
|
|
expect { described_class.reboot(machine) }.to raise_error(StandardError)
|
|
end
|
|
end
|
|
end
|
|
end
|