From 90fa705a6dd37118920729d4a072088517c69b36 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 4 Apr 2018 15:44:54 -0700 Subject: [PATCH] Make powershell version detection timeout configurable Allows custom configuration of the powershell timeout and bumps the default timeout from 10 seconds to 30 seconds. Fixes #9629 --- lib/vagrant/util/powershell.rb | 18 +++++++++- test/unit/vagrant/util/powershell_test.rb | 44 +++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test/unit/vagrant/util/powershell_test.rb diff --git a/lib/vagrant/util/powershell.rb b/lib/vagrant/util/powershell.rb index d685e0b56..7c96485ea 100644 --- a/lib/vagrant/util/powershell.rb +++ b/lib/vagrant/util/powershell.rb @@ -11,6 +11,8 @@ module Vagrant class PowerShell # NOTE: Version checks are only on Major MINIMUM_REQUIRED_VERSION = 3 + # Number of seconds to wait while attempting to get powershell version + DEFAULT_VERSION_DETECTION_TIMEOUT = 30 LOGGER = Log4r::Logger.new("vagrant::util::powershell") # @return [String|nil] a powershell executable, depending on environment @@ -101,8 +103,15 @@ module Vagrant ].flatten version = nil + timeout = ENV["VAGRANT_POWERSHELL_VERSION_DETECTION_TIMEOUT"].to_i + if timeout < 1 + timeout = DEFAULT_VERSION_DETECTION_TIMEOUT + end begin - r = Subprocess.execute(*command, notify: [:stdout, :stderr], timeout: 10) {|io_name,data| version = data} + r = Subprocess.execute(*command, + notify: [:stdout, :stderr], + timeout: timeout, + ) {|io_name,data| version = data} rescue Vagrant::Util::Subprocess::TimeoutExceeded LOGGER.debug("Timeout exceeded while attempting to determine version of Powershell.") end @@ -183,6 +192,13 @@ module Vagrant Subprocess::Result.new(code, r_stdout, r_stderr) end end + + # @private + # Reset the cached values for platform. This is not considered a public + # API and should only be used for testing. + def self.reset! + instance_variables.each(&method(:remove_instance_variable)) + end end end end diff --git a/test/unit/vagrant/util/powershell_test.rb b/test/unit/vagrant/util/powershell_test.rb new file mode 100644 index 000000000..d5760fc28 --- /dev/null +++ b/test/unit/vagrant/util/powershell_test.rb @@ -0,0 +1,44 @@ +require File.expand_path("../../../base", __FILE__) + +require 'vagrant/util/powershell' + +describe Vagrant::Util::PowerShell do + include_context "unit" + describe ".version" do + before do + allow(described_class).to receive(:executable) + .and_return("powershell") + allow(Vagrant::Util::Subprocess).to receive(:execute) + end + + after do + described_class.version + described_class.reset! + end + + it "should execute powershell command" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with("powershell", any_args) + end + + it "should use the default timeout" do + expect(Vagrant::Util::Subprocess).to receive(:execute).with(any_args, hash_including( + timeout: Vagrant::Util::PowerShell::DEFAULT_VERSION_DETECTION_TIMEOUT)) + end + + it "should use environment variable provided timeout" do + with_temp_env("VAGRANT_POWERSHELL_VERSION_DETECTION_TIMEOUT" => "1") do + expect(Vagrant::Util::Subprocess).to receive(:execute).with(any_args, hash_including( + timeout: 1)) + described_class.version + end + end + + it "should use default timeout when environment variable value is invalid" do + with_temp_env("VAGRANT_POWERSHELL_VERSION_DETECTION_TIMEOUT" => "invalid value") do + expect(Vagrant::Util::Subprocess).to receive(:execute).with(any_args, hash_including( + timeout: Vagrant::Util::PowerShell::DEFAULT_VERSION_DETECTION_TIMEOUT)) + described_class.version + end + end + end +end