New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add exponential increase on timeout in #sshable? for services that do not respond in 8s #214
Changes from 5 commits
ee55ecc
8ea03d6
dd90fc4
2c1d839
f51f6a1
927a629
2eff6cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
require "spec_helper" | ||
require "fog/compute/models/server" | ||
|
||
describe Fog::Compute::Server do | ||
before do | ||
@server = Fog::Compute::Server.new | ||
end | ||
|
||
describe "#sshable?" do | ||
before do | ||
# I'm not sure why #sshable? depends on a method that's not defined except in implementing classes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question. Maybe we should define it in the base class also, but just have it always return false? That would clear up this confusion/oddity, hopefully. Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about a method that raises OTOH, http://chrisstump.online/2016/03/23/stop-abusing-notimplementederror/. Maybe we should just document that it must be implemented? |
||
def @server.ready?;end | ||
end | ||
|
||
describe "when the server is not ready" do | ||
it "is false" do | ||
@server.stub(:ready?, false) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
|
||
describe "when the server is ready" do | ||
describe "when the ssh_ip_address is nil" do | ||
it "is false" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, nil) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
|
||
|
||
describe "when the ssh_ip_address exists" do | ||
# Define these constants which would be imported by net-ssh once loaded | ||
module Net | ||
module SSH | ||
class AuthenticationFailed < RuntimeError | ||
end | ||
class Disconnect < RuntimeError | ||
end | ||
end | ||
end | ||
|
||
describe "and ssh times out" do | ||
it "is false" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raises_timeout = lambda { |_time| raise Timeout::Error.new } | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "and it raises Net::SSH::AuthenticationFailed" do | ||
it "is false" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raise_error = lambda { |_cmd, _options| raise Net::SSH::AuthenticationFailed.new } | ||
@server.stub(:ssh, raise_error) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
|
||
it "resets SSH timeout" do | ||
@server.instance_variable_set(:@sshable_timeout, 8) | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raise_error = lambda { |_cmd, _options| raise Net::SSH::AuthenticationFailed.new } | ||
@server.stub(:ssh, raise_error) do | ||
@server.sshable? | ||
assert_nil @server.instance_variable_get(:@sshable_timeout), nil | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "and it raises Net::SSH::Disconnect" do | ||
it "is false" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raise_error = lambda { |_cmd, _options| raise Net::SSH::Disconnect.new } | ||
@server.stub(:ssh, raise_error) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
|
||
it "resets SSH timeout" do | ||
@server.instance_variable_set(:@sshable_timeout, 8) | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raise_error = lambda { |_cmd, _options| raise Net::SSH::Disconnect.new } | ||
@server.stub(:ssh, raise_error) do | ||
@server.sshable? | ||
assert_nil @server.instance_variable_get(:@sshable_timeout), nil | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "and it raises SystemCallError" do | ||
it "is false" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raise_error = lambda { |_cmd, _options| raise SystemCallError.new("message, 0") } | ||
@server.stub(:ssh, raise_error) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
|
||
it "does not increase SSH timeout" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raise_error = lambda { |_cmd, _options| raise SystemCallError.new("message, 0") } | ||
@server.stub(:ssh, raise_error) do | ||
@server.sshable? | ||
assert_equal @server.instance_variable_get(:@sshable_timeout), 8 | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "and ssh completes within the designated timeout" do | ||
it "is true" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
@server.stub(:ssh, "datum") do | ||
assert @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "when called successively" do | ||
describe "and ssh times out" do | ||
it "increases the timeout factor by 1.5" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raises_timeout = lambda do |time| | ||
assert(time == 8) | ||
raise Timeout::Error.new | ||
end | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
|
||
raises_timeout = lambda do |time| | ||
assert_equal(12, time) | ||
raise Timeout::Error.new | ||
end | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
|
||
it "does not increase timeout beyond 60s" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raises_timeout = lambda { |_time| raise Timeout::Error.new } | ||
Timeout.stub(:timeout, raises_timeout) do | ||
5.times { refute @server.sshable? } | ||
end | ||
|
||
raises_timeout = lambda do |time| | ||
assert_equal(60, time) | ||
raise Timeout::Error.new | ||
end | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
|
||
raises_timeout = lambda do |time| | ||
assert_equal(60, time) | ||
raise Timeout::Error.new | ||
end | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe "when ssh eventually succeeds" do | ||
it "resets the timeout to the initial value" do | ||
@server.stub(:ready?, true) do | ||
@server.stub(:ssh_ip_address, "10.0.0.1") do | ||
raises_timeout = lambda do |time| | ||
assert(time == 8) | ||
raise Timeout::Error.new | ||
end | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
|
||
@server.stub(:ssh, "datum") do | ||
assert @server.sshable? | ||
end | ||
|
||
raises_timeout = lambda do |time| | ||
assert_equal(8, time) | ||
raise Timeout::Error.new | ||
end | ||
Timeout.stub(:timeout, raises_timeout) do | ||
refute @server.sshable? | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
end | ||
end | ||
|
||
end | ||
end | ||
|
||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think english is supported by older versions of ruby which fog-core still supports. Also, double quotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://travis-ci.org/fog/fog-core/jobs/257477755#L462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@icco Sorry about that. I was just trying to get rid of the warning that
$INPUT_RECORD_SEPARATOR
isn't defined. I'll back that out.