IsPortOpen utility
This commit is contained in:
parent
3877b71983
commit
d08a65e7f7
|
@ -0,0 +1,38 @@
|
||||||
|
require "socket"
|
||||||
|
require "timeout"
|
||||||
|
|
||||||
|
module Vagrant
|
||||||
|
module Util
|
||||||
|
# Contains the method {#is_ruby_open?} to check if a port is open
|
||||||
|
# (listening) or closed (not in use). This method isn't completely
|
||||||
|
# fool-proof, but it works enough of the time to be useful.
|
||||||
|
module IsPortOpen
|
||||||
|
# Checks if a port is open (listening) on a given host and port.
|
||||||
|
#
|
||||||
|
# @param [String] host Hostname or IP address.
|
||||||
|
# @param [Integer] port Port to check.
|
||||||
|
# @return [Boolean] `true` if the port is open (listening), `false`
|
||||||
|
# otherwise.
|
||||||
|
def is_port_open?(host, port)
|
||||||
|
# We wrap this in a timeout because once in awhile the TCPSocket
|
||||||
|
# _will_ hang, but this signals that the port is closed.
|
||||||
|
Timeout.timeout(1) do
|
||||||
|
# Attempt to make a connection
|
||||||
|
s = TCPSocket.new(host, port)
|
||||||
|
|
||||||
|
# A connection was made! Properly clean up the socket, not caring
|
||||||
|
# at all if any exception is raised, because we already know the
|
||||||
|
# result.
|
||||||
|
s.close rescue nil
|
||||||
|
|
||||||
|
# The port is open if we reached this point, since we were able
|
||||||
|
# to connect.
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
||||||
|
# Any of the above exceptions signal that the port is closed.
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,53 @@
|
||||||
|
require File.expand_path("../../../base", __FILE__)
|
||||||
|
|
||||||
|
require "socket"
|
||||||
|
|
||||||
|
require "vagrant/util/is_port_open"
|
||||||
|
|
||||||
|
describe Vagrant::Util::IsPortOpen do
|
||||||
|
let(:klass) do
|
||||||
|
Class.new do
|
||||||
|
extend Vagrant::Util::IsPortOpen
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:open_port) { 52811 }
|
||||||
|
let(:closed_port) { 52811 }
|
||||||
|
|
||||||
|
it "should report open ports" do
|
||||||
|
# Start a thread which listens on a port
|
||||||
|
thr = Thread.new do
|
||||||
|
server = TCPServer.new(open_port)
|
||||||
|
Thread.current[:running] = true
|
||||||
|
|
||||||
|
# Wait until we're told to die
|
||||||
|
Thread.current[:die] = false
|
||||||
|
while !Thread.current[:die]
|
||||||
|
Thread.pass
|
||||||
|
end
|
||||||
|
|
||||||
|
# Die!
|
||||||
|
server.close
|
||||||
|
end
|
||||||
|
|
||||||
|
# Wait until the server is running
|
||||||
|
while !thr[:running]
|
||||||
|
Thread.pass
|
||||||
|
end
|
||||||
|
|
||||||
|
# Verify that we report the port is open
|
||||||
|
klass.is_port_open?("localhost", open_port).should be
|
||||||
|
|
||||||
|
# Kill the thread
|
||||||
|
thr[:die] = true
|
||||||
|
thr.join
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should report closed ports" do
|
||||||
|
# This CAN fail, since port 52811 might actually be in use, but I'm
|
||||||
|
# not sure what to do except choose some random port and hope for the
|
||||||
|
# best, really.
|
||||||
|
klass.is_port_open?("localhost", closed_port).should_not be
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue