From 34678e895a5a40da6f444199983fee3f8ce518ee Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 27 Dec 2013 02:43:24 -0800 Subject: added some network tests for stunnel --- bin/run_tests | 87 ++++++++++++++++++++++++++++++++++++++++++++-- tests/white-box/dummy.rb | 24 ++++++++++--- tests/white-box/network.rb | 23 ++++++++++-- tests/white-box/webapp.rb | 8 +++-- 4 files changed, 131 insertions(+), 11 deletions(-) diff --git a/bin/run_tests b/bin/run_tests index 8c5fb492..89fbdb24 100755 --- a/bin/run_tests +++ b/bin/run_tests @@ -93,18 +93,99 @@ class LeapTest < MiniTest::Unit::TestCase yield nil, nil, exc end - def assert_get(url, params=nil) + def assert_get(url, params=nil, options=nil) + options ||= {} get(url, params) do |body, response, error| if body yield body elsif response - fail "Expected a 200 status code from #{url}, but got #{response.code} instead." + fail ["Expected a 200 status code from #{url}, but got #{response.code} instead.", options[:error_msg]].compact.join("\n") else - fail "Expected a response from #{url}, but got \"#{error}\" instead." + fail ["Expected a response from #{url}, but got \"#{error}\" instead.", options[:error_msg]].compact.join("\n") end end end + # + # test if a socket can be connected to + # + + # + # tcp connection helper with timeout + # + def try_tcp_connect(host, port, timeout = 5) + addr = Socket.getaddrinfo(host, nil) + sockaddr = Socket.pack_sockaddr_in(port, addr[0][3]) + + Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0).tap do |socket| + socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + begin + socket.connect_nonblock(sockaddr) + rescue IO::WaitReadable + if IO.select([socket], nil, nil, timeout) == nil + raise "Connection timeout" + else + socket.connect_nonblock(sockaddr) + end + rescue IO::WaitWritable + if IO.select(nil, [socket], nil, timeout) == nil + raise "Connection timeout" + else + socket.connect_nonblock(sockaddr) + end + end + return socket + end + end + + def try_tcp_write(socket, timeout = 5) + begin + socket.write_nonblock("\0") + rescue IO::WaitReadable + if IO.select([socket], nil, nil, timeout) == nil + raise "Write timeout" + else + retry + end + rescue IO::WaitWritable + if IO.select(nil, [socket], nil, timeout) == nil + raise "Write timeout" + else + retry + end + end + end + + def try_tcp_read(socket, timeout = 5) + begin + socket.read_nonblock(1) + rescue IO::WaitReadable + if IO.select([socket], nil, nil, timeout) == nil + raise "Read timeout" + else + retry + end + rescue IO::WaitWritable + if IO.select(nil, [socket], nil, timeout) == nil + raise "Read timeout" + else + retry + end + end + end + + def assert_tcp_socket(host, port, msg=nil) + begin + socket = try_tcp_connect(host, port, 1) + #try_tcp_write(socket,1) + #try_tcp_read(socket,1) + rescue StandardError => exc + fail ["Failed to open socket #{host}:#{port}", exc].join("\n") + ensure + socket.close if socket + end + end + # # Matches the regexp in the file, and returns the first matched string (or fails if no match). # diff --git a/tests/white-box/dummy.rb b/tests/white-box/dummy.rb index dd343769..6ca49754 100644 --- a/tests/white-box/dummy.rb +++ b/tests/white-box/dummy.rb @@ -26,8 +26,8 @@ class TestDummy < LeapTest pass end - def test_blah - fail "blah" #assert false + def test_fail + fail "fail" pass end @@ -36,8 +36,24 @@ class TestDummy < LeapTest pass end - def test_err - 12/0 + def test_socket_failure + assert_tcp_socket('localhost', 900000) + pass + end + + def test_socket_success + fork { + Socket.tcp_server_loop('localhost', 12345) do |sock, client_addrinfo| + begin + sock.write('hi') + ensure + sock.close + exit + end + end + } + sleep 0.2 + assert_tcp_socket('localhost', 12345) pass end diff --git a/tests/white-box/network.rb b/tests/white-box/network.rb index 9680cb5f..8ca56ffd 100644 --- a/tests/white-box/network.rb +++ b/tests/white-box/network.rb @@ -1,12 +1,31 @@ +require 'socket' + +raise SkipTest if $node["dummy"] + class TestNetwork < LeapTest def setup end # - # TODO: write an actual test to confirm the network is up and working. + # example properties: + # + # stunnel: + # couch_client: + # couch1_5984: + # accept_port: 4000 + # connect: couch1.bitmask.i + # connect_port: 15984 # - def test_working + def test_01_stunnel_is_running + if $node['stunnel'] + $node['stunnel'].values.each do |stunnel_type| + stunnel_type.values.each do |stunnel_conf| + assert port = stunnel_conf['accept_port'], 'Field `accept_port` must be present in `stunnel` property.' + assert_tcp_socket('localhost', port) + end + end + end pass end diff --git a/tests/white-box/webapp.rb b/tests/white-box/webapp.rb index 65f3217b..aaad4426 100644 --- a/tests/white-box/webapp.rb +++ b/tests/white-box/webapp.rb @@ -1,5 +1,7 @@ raise SkipTest unless $node["services"].include?("webapp") +require 'socket' + class TestWebapp < LeapTest depends_on "TestNetwork" @@ -18,12 +20,14 @@ class TestWebapp < LeapTest # connect: couch1.bitmask.i # connect_port: 15984 # - def test_01_stunnel_is_working + def test_01_can_contact_couchdb assert_property('stunnel.couch_client') $node['stunnel']['couch_client'].values.each do |stunnel_conf| assert port = stunnel_conf['accept_port'], 'Field `accept_port` must be present in `stunnel` property.' local_stunnel_url = "http://localhost:#{port}" - assert_get(local_stunnel_url) do |body| + remote_ip_address = TCPSocket.gethostbyname(stunnel_conf['connect']).last + msg = "(stunnel to %s:%s, aka %s)" % [stunnel_conf['connect'], stunnel_conf['connect_port'], remote_ip_address] + assert_get(local_stunnel_url, nil, error_msg: msg) do |body| assert_match /"couchdb":"Welcome"/, body, "Request to #{local_stunnel_url} should return couchdb welcome message." end end -- cgit v1.2.3