Skip to content

Commit

Permalink
tests: Run streaming tests in SSL mode
Browse files Browse the repository at this point in the history
Notice a couple of tests fail now
  • Loading branch information
vasi-stripe committed Nov 8, 2022
1 parent 8beb160 commit bd10b63
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 10 deletions.
13 changes: 10 additions & 3 deletions tests/basic_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@
end

Shindo.tests('Excon streaming basics') do
pending if RUBY_PLATFORM == 'java' # need to find suitable server for jruby
with_unicorn('streaming.ru') do
streaming_tests
tests('http') do
pending if RUBY_PLATFORM == 'java' # need to find suitable server for jruby
with_unicorn('streaming.ru') do
streaming_tests('http')
end
end
tests('https') do
with_ssl_streaming(9292, STREAMING_PIECES, STREAMING_TIMEOUT) do
streaming_tests('https')
end
end
end

Expand Down
69 changes: 62 additions & 7 deletions tests/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'excon'
require 'delorean'
require 'open4'
require 'webrick'

require './spec/helpers/warning_helpers.rb'

Expand Down Expand Up @@ -217,12 +218,18 @@ def basic_tests(url = 'http://127.0.0.1:9292', options = {})
STREAMING_PIECES = %w{Hello streamy world}
STREAMING_TIMEOUT = 0.1

def streaming_tests
def streaming_tests(protocol)
conn = nil
test do
conn = Excon.new("#{protocol}://127.0.0.1:9292/", :ssl_verify_peer => false)
true
end

# expect the full response as a string
# and expect it to take a (timeout * pieces) seconds
tests('simple blocking request on streaming endpoint').returns([STREAMING_PIECES.join(''),'response time ok']) do
start = Time.now
ret = Excon.get('http://127.0.0.1:9292/streamed/simple').body
ret = conn.request(:method => :get, :path => '/streamed/simple').body

if Time.now - start <= STREAMING_TIMEOUT*3
[ret, 'streaming response came too quickly']
Expand All @@ -235,7 +242,7 @@ def streaming_tests
# take a (timeout * pieces) seconds (with fixed Content-Length header)
tests('simple blocking request on streaming endpoint with fixed length').returns([STREAMING_PIECES.join(''),'response time ok']) do
start = Time.now
ret = Excon.get('http://127.0.0.1:9292/streamed/fixed_length').body
ret = conn.request(:method => :get, :path => '/streamed/fixed_length').body

if Time.now - start <= STREAMING_TIMEOUT*3
[ret, 'streaming response came too quickly']
Expand All @@ -246,11 +253,11 @@ def streaming_tests

# expect each response piece to arrive to the body right away
# and wait for timeout until next one arrives
def timed_streaming_test(endpoint, timeout)
def timed_streaming_test(conn, path, timeout)
ret = []
timing = 'response times ok'
start = Time.now
Excon.get(endpoint, :response_block => lambda do |c,r,t|
conn.request(:method => :get, :path => path, :response_block => lambda do |c,r,t|
# add the response
ret.push(c)
# check if the timing is ok
Expand All @@ -268,11 +275,11 @@ def timed_streaming_test(endpoint, timeout)
end

tests('simple request with response_block on streaming endpoint').returns([STREAMING_PIECES,'response times ok']) do
timed_streaming_test('http://127.0.0.1:9292/streamed/simple', STREAMING_TIMEOUT)
timed_streaming_test(conn, '/streamed/simple', STREAMING_TIMEOUT)
end

tests('simple request with response_block on streaming endpoint with fixed length').returns([STREAMING_PIECES,'response times ok']) do
timed_streaming_test('http://127.0.0.1:9292/streamed/fixed_length', STREAMING_TIMEOUT)
timed_streaming_test(conn, '/streamed/fixed_length', STREAMING_TIMEOUT)
end
end

Expand Down Expand Up @@ -393,3 +400,51 @@ def with_server(name)
ensure
cleanup_process(pid)
end

# A tiny fake SSL streaming server
def with_ssl_streaming(port, pieces, delay)
key_file = File.join(File.dirname(__FILE__), 'data', '127.0.0.1.cert.key')
cert_file = File.join(File.dirname(__FILE__), 'data', '127.0.0.1.cert.crt')

ctx = OpenSSL::SSL::SSLContext.new
ctx.key = OpenSSL::PKey::RSA.new(File.read(key_file))
ctx.cert = OpenSSL::X509::Certificate.new(File.read(cert_file))

tcp = TCPServer.new(port)
ssl = OpenSSL::SSL::SSLServer.new(tcp, ctx)

Thread.new do
loop do
begin
conn = ssl.accept
rescue IOError => e
# we're closing the socket from another thread, which makes `accept` complain
break if /stream closed/ =~ e.to_s
raise
end

Thread.new do
begin
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
req.parse(conn)

conn << "HTTP/1.1 200 OK\r\n\r\n"
if req.path == "streamed/fixed_length"
conn << "Content-Length: #{pieces.join.length}\r\n"
end
conn.flush

pieces.each do |piece|
sleep(delay)
conn.write(piece)
conn.flush
end
ensure
conn.close
end
end
end
end
yield
ssl.close
end

0 comments on commit bd10b63

Please sign in to comment.