322 lines
6.6 KiB
Ruby
322 lines
6.6 KiB
Ruby
|
require 'em_test_helper'
|
||
|
require 'socket'
|
||
|
|
||
|
class TestBasic < Test::Unit::TestCase
|
||
|
def setup
|
||
|
@port = next_port
|
||
|
end
|
||
|
|
||
|
def test_connection_class_cache
|
||
|
mod = Module.new
|
||
|
a, b = nil, nil
|
||
|
EM.run {
|
||
|
EM.start_server '127.0.0.1', @port, mod
|
||
|
a = EM.connect '127.0.0.1', @port, mod
|
||
|
b = EM.connect '127.0.0.1', @port, mod
|
||
|
EM.stop
|
||
|
}
|
||
|
assert_equal a.class, b.class
|
||
|
assert_kind_of EM::Connection, a
|
||
|
end
|
||
|
|
||
|
#-------------------------------------
|
||
|
|
||
|
|
||
|
def test_em
|
||
|
assert_nothing_raised do
|
||
|
EM.run {
|
||
|
setup_timeout
|
||
|
EM.add_timer 0 do
|
||
|
EM.stop
|
||
|
end
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
#-------------------------------------
|
||
|
|
||
|
def test_timer
|
||
|
assert_nothing_raised do
|
||
|
EM.run {
|
||
|
setup_timeout
|
||
|
n = 0
|
||
|
EM.add_periodic_timer(0.1) {
|
||
|
n += 1
|
||
|
EM.stop if n == 2
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
#-------------------------------------
|
||
|
|
||
|
# This test once threw an already-running exception.
|
||
|
module Trivial
|
||
|
def post_init
|
||
|
EM.stop
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_server
|
||
|
assert_nothing_raised do
|
||
|
EM.run {
|
||
|
setup_timeout
|
||
|
EM.start_server "127.0.0.1", @port, Trivial
|
||
|
EM.connect "127.0.0.1", @port
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
#--------------------------------------
|
||
|
|
||
|
# EM#run_block starts the reactor loop, runs the supplied block, and then STOPS
|
||
|
# the loop automatically. Contrast with EM#run, which keeps running the reactor
|
||
|
# even after the supplied block completes.
|
||
|
def test_run_block
|
||
|
assert !EM.reactor_running?
|
||
|
a = nil
|
||
|
EM.run_block { a = "Worked" }
|
||
|
assert a
|
||
|
assert !EM.reactor_running?
|
||
|
end
|
||
|
|
||
|
class UnbindError < EM::Connection
|
||
|
ERR = Class.new(StandardError)
|
||
|
def initialize *args
|
||
|
super
|
||
|
end
|
||
|
def connection_completed
|
||
|
close_connection_after_writing
|
||
|
end
|
||
|
def unbind
|
||
|
raise ERR
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_unbind_error_during_stop
|
||
|
assert_raises( UnbindError::ERR ) {
|
||
|
EM.run {
|
||
|
EM.start_server "127.0.0.1", @port
|
||
|
EM.connect "127.0.0.1", @port, UnbindError do
|
||
|
EM.stop
|
||
|
end
|
||
|
}
|
||
|
}
|
||
|
end
|
||
|
|
||
|
def test_unbind_error
|
||
|
EM.run {
|
||
|
EM.error_handler do |e|
|
||
|
assert(e.is_a?(UnbindError::ERR))
|
||
|
EM.stop
|
||
|
end
|
||
|
EM.start_server "127.0.0.1", @port
|
||
|
EM.connect "127.0.0.1", @port, UnbindError
|
||
|
}
|
||
|
|
||
|
# Remove the error handler before the next test
|
||
|
EM.error_handler(nil)
|
||
|
end
|
||
|
|
||
|
module BrsTestSrv
|
||
|
def receive_data data
|
||
|
$received << data
|
||
|
end
|
||
|
def unbind
|
||
|
EM.stop
|
||
|
end
|
||
|
end
|
||
|
module BrsTestCli
|
||
|
def post_init
|
||
|
send_data $sent
|
||
|
close_connection_after_writing
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# From ticket #50
|
||
|
def test_byte_range_send
|
||
|
$received = ''
|
||
|
$sent = (0..255).to_a.pack('C*')
|
||
|
EM::run {
|
||
|
EM::start_server "127.0.0.1", @port, BrsTestSrv
|
||
|
EM::connect "127.0.0.1", @port, BrsTestCli
|
||
|
|
||
|
setup_timeout
|
||
|
}
|
||
|
assert_equal($sent, $received)
|
||
|
end
|
||
|
|
||
|
def test_bind_connect
|
||
|
pend('FIXME: this test is broken on Windows') if windows?
|
||
|
|
||
|
local_ip = UDPSocket.open {|s| s.connect('localhost', 80); s.addr.last }
|
||
|
|
||
|
bind_port = next_port
|
||
|
|
||
|
port, ip = nil
|
||
|
bound_server = Module.new do
|
||
|
define_method :post_init do
|
||
|
begin
|
||
|
port, ip = Socket.unpack_sockaddr_in(get_peername)
|
||
|
ensure
|
||
|
EM.stop
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
EM.run do
|
||
|
setup_timeout
|
||
|
EM.start_server "127.0.0.1", @port, bound_server
|
||
|
EM.bind_connect local_ip, bind_port, "127.0.0.1", @port
|
||
|
end
|
||
|
|
||
|
assert_equal bind_port, port
|
||
|
assert_equal local_ip, ip
|
||
|
end
|
||
|
|
||
|
def test_invalid_address_bind_connect_dst
|
||
|
e = nil
|
||
|
EM.run do
|
||
|
begin
|
||
|
EM.bind_connect('localhost', nil, 'invalid.invalid', 80)
|
||
|
rescue Exception => e
|
||
|
# capture the exception
|
||
|
ensure
|
||
|
EM.stop
|
||
|
end
|
||
|
end
|
||
|
|
||
|
assert_kind_of(EventMachine::ConnectionError, e)
|
||
|
assert_match(/unable to resolve address:.*not known/, e.message)
|
||
|
end
|
||
|
|
||
|
def test_invalid_address_bind_connect_src
|
||
|
e = nil
|
||
|
EM.run do
|
||
|
begin
|
||
|
EM.bind_connect('invalid.invalid', nil, 'localhost', 80)
|
||
|
rescue Exception => e
|
||
|
# capture the exception
|
||
|
ensure
|
||
|
EM.stop
|
||
|
end
|
||
|
end
|
||
|
|
||
|
assert_kind_of(EventMachine::ConnectionError, e)
|
||
|
assert_match(/invalid bind address:.*not known/, e.message)
|
||
|
end
|
||
|
|
||
|
def test_reactor_thread?
|
||
|
assert !EM.reactor_thread?
|
||
|
EM.run { assert EM.reactor_thread?; EM.stop }
|
||
|
assert !EM.reactor_thread?
|
||
|
end
|
||
|
|
||
|
def test_schedule_on_reactor_thread
|
||
|
x = false
|
||
|
EM.run do
|
||
|
EM.schedule { x = true }
|
||
|
EM.stop
|
||
|
end
|
||
|
assert x
|
||
|
end
|
||
|
|
||
|
def test_schedule_from_thread
|
||
|
x = false
|
||
|
EM.run do
|
||
|
Thread.new { EM.schedule { x = true; EM.stop } }.join
|
||
|
end
|
||
|
assert x
|
||
|
end
|
||
|
|
||
|
def test_set_heartbeat_interval
|
||
|
omit_if(jruby?)
|
||
|
interval = 0.5
|
||
|
EM.run {
|
||
|
EM.set_heartbeat_interval interval
|
||
|
$interval = EM.get_heartbeat_interval
|
||
|
EM.stop
|
||
|
}
|
||
|
assert_equal(interval, $interval)
|
||
|
end
|
||
|
|
||
|
module PostInitRaiser
|
||
|
ERR = Class.new(StandardError)
|
||
|
def post_init
|
||
|
raise ERR
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_bubble_errors_from_post_init
|
||
|
assert_raises(PostInitRaiser::ERR) do
|
||
|
EM.run do
|
||
|
EM.start_server "127.0.0.1", @port
|
||
|
EM.connect "127.0.0.1", @port, PostInitRaiser
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
module InitializeRaiser
|
||
|
ERR = Class.new(StandardError)
|
||
|
def initialize
|
||
|
raise ERR
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_bubble_errors_from_initialize
|
||
|
assert_raises(InitializeRaiser::ERR) do
|
||
|
EM.run do
|
||
|
EM.start_server "127.0.0.1", @port
|
||
|
EM.connect "127.0.0.1", @port, InitializeRaiser
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def test_schedule_close
|
||
|
omit_if(jruby?)
|
||
|
localhost, port = '127.0.0.1', 9000
|
||
|
timer_ran = false
|
||
|
num_close_scheduled = nil
|
||
|
EM.run do
|
||
|
assert_equal 0, EM.num_close_scheduled
|
||
|
EM.add_timer(1) { timer_ran = true; EM.stop }
|
||
|
EM.start_server localhost, port do |s|
|
||
|
s.close_connection
|
||
|
num_close_scheduled = EM.num_close_scheduled
|
||
|
end
|
||
|
EM.connect localhost, port do |c|
|
||
|
def c.unbind
|
||
|
EM.stop
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
assert !timer_ran
|
||
|
assert_equal 1, num_close_scheduled
|
||
|
end
|
||
|
|
||
|
def test_error_handler_idempotent # issue 185
|
||
|
errors = []
|
||
|
ticks = []
|
||
|
EM.error_handler do |e|
|
||
|
errors << e
|
||
|
end
|
||
|
|
||
|
EM.run do
|
||
|
EM.next_tick do
|
||
|
ticks << :first
|
||
|
raise
|
||
|
end
|
||
|
EM.next_tick do
|
||
|
ticks << :second
|
||
|
end
|
||
|
EM.add_timer(0.001) { EM.stop }
|
||
|
end
|
||
|
|
||
|
# Remove the error handler before the next test
|
||
|
EM.error_handler(nil)
|
||
|
|
||
|
assert_equal 1, errors.size
|
||
|
assert_equal [:first, :second], ticks
|
||
|
end
|
||
|
end
|