Keep the default duration as a constant and fetch the custom environment variable at run time with a fallback to the default. Set the sleep duration into a constant and add tests covering the expected behaviors when the default duration is in use as well as the override value. Also match the environment variable up with the constant just for consistency.
149 lines
5.5 KiB
Ruby
149 lines
5.5 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
|
|
|
|
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
|