PageRenderTime 50ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/test_basic.rb

http://github.com/eventmachine/eventmachine
Ruby | 321 lines | 267 code | 41 blank | 13 comment | 2 complexity | 4d3cfd5b36928ef777bb5ffcadbb54c2 MD5 | raw file
  1. require_relative 'em_test_helper'
  2. class TestBasic < Test::Unit::TestCase
  3. def setup
  4. @port = next_port
  5. end
  6. INVALID = "(not known|no data of the requested|No such host is known|Temporary failure in name resolution)"
  7. def test_connection_class_cache
  8. mod = Module.new
  9. a, b = nil, nil
  10. EM.run {
  11. EM.start_server '127.0.0.1', @port, mod
  12. a = EM.connect '127.0.0.1', @port, mod
  13. b = EM.connect '127.0.0.1', @port, mod
  14. EM.stop
  15. }
  16. assert_equal a.class, b.class
  17. assert_kind_of EM::Connection, a
  18. end
  19. #-------------------------------------
  20. def test_em
  21. assert_nothing_raised do
  22. EM.run {
  23. setup_timeout
  24. EM.add_timer 0 do
  25. EM.stop
  26. end
  27. }
  28. end
  29. end
  30. #-------------------------------------
  31. def test_timer
  32. assert_nothing_raised do
  33. EM.run {
  34. setup_timeout 0.4
  35. n = 0
  36. EM.add_periodic_timer(0.1) {
  37. n += 1
  38. EM.stop if n == 2
  39. }
  40. }
  41. end
  42. end
  43. #-------------------------------------
  44. # This test once threw an already-running exception.
  45. module Trivial
  46. def post_init
  47. EM.stop
  48. end
  49. end
  50. def test_server
  51. assert_nothing_raised do
  52. EM.run {
  53. setup_timeout
  54. EM.start_server "127.0.0.1", @port, Trivial
  55. EM.connect "127.0.0.1", @port
  56. }
  57. end
  58. end
  59. #--------------------------------------
  60. # EM#run_block starts the reactor loop, runs the supplied block, and then STOPS
  61. # the loop automatically. Contrast with EM#run, which keeps running the reactor
  62. # even after the supplied block completes.
  63. def test_run_block
  64. assert !EM.reactor_running?
  65. a = nil
  66. EM.run_block { a = "Worked" }
  67. assert a
  68. assert !EM.reactor_running?
  69. end
  70. class UnbindError < EM::Connection
  71. ERR = Class.new(StandardError)
  72. def initialize *args
  73. super
  74. end
  75. def connection_completed
  76. close_connection_after_writing
  77. end
  78. def unbind
  79. raise ERR
  80. end
  81. end
  82. def test_unbind_error_during_stop
  83. assert_raises( UnbindError::ERR ) {
  84. EM.run {
  85. EM.start_server "127.0.0.1", @port
  86. EM.connect "127.0.0.1", @port, UnbindError do
  87. EM.stop
  88. end
  89. }
  90. }
  91. end
  92. def test_unbind_error
  93. EM.run {
  94. EM.error_handler do |e|
  95. assert(e.is_a?(UnbindError::ERR))
  96. EM.stop
  97. end
  98. EM.start_server "127.0.0.1", @port
  99. EM.connect "127.0.0.1", @port, UnbindError
  100. }
  101. # Remove the error handler before the next test
  102. EM.error_handler(nil)
  103. end
  104. module BrsTestSrv
  105. def receive_data data
  106. $received << data
  107. end
  108. def unbind
  109. EM.stop
  110. end
  111. end
  112. module BrsTestCli
  113. def post_init
  114. send_data $sent
  115. close_connection_after_writing
  116. end
  117. end
  118. # From ticket #50
  119. def test_byte_range_send
  120. $received = ''
  121. $sent = (0..255).to_a.pack('C*')
  122. EM::run {
  123. EM::start_server "127.0.0.1", @port, BrsTestSrv
  124. EM::connect "127.0.0.1", @port, BrsTestCli
  125. setup_timeout
  126. }
  127. assert_equal($sent, $received)
  128. end
  129. def test_bind_connect
  130. local_ip = UDPSocket.open {|s| s.connect('localhost', 80); s.addr.last }
  131. bind_port = next_port
  132. port, ip = nil
  133. bound_server = Module.new do
  134. define_method :post_init do
  135. begin
  136. port, ip = Socket.unpack_sockaddr_in(get_peername)
  137. ensure
  138. EM.stop
  139. end
  140. end
  141. end
  142. EM.run do
  143. setup_timeout
  144. EM.start_server "127.0.0.1", @port, bound_server
  145. EM.bind_connect local_ip, bind_port, "127.0.0.1", @port
  146. end
  147. assert_equal bind_port, port
  148. assert_equal local_ip, ip
  149. end
  150. def test_invalid_address_bind_connect_dst
  151. pend("\nFIXME: Windows as of 2018-06-23 on 32 bit >= 2.4 (#{RUBY_VERSION} #{RUBY_PLATFORM})") if RUBY_PLATFORM[/i386-mingw/] && RUBY_VERSION >= '2.4'
  152. e = nil
  153. EM.run do
  154. begin
  155. EM.bind_connect('localhost', nil, 'invalid.invalid', 80)
  156. rescue Exception => e
  157. # capture the exception
  158. ensure
  159. EM.stop
  160. end
  161. end
  162. assert_kind_of(EventMachine::ConnectionError, e)
  163. assert_match(/unable to resolve address:.*#{INVALID}/, e.message)
  164. end
  165. def test_invalid_address_bind_connect_src
  166. pend("\nFIXME: Windows as of 2018-06-23 on 32 bit >= 2.4 (#{RUBY_VERSION} #{RUBY_PLATFORM})") if RUBY_PLATFORM[/i386-mingw/] && RUBY_VERSION >= '2.4'
  167. e = nil
  168. EM.run do
  169. begin
  170. EM.bind_connect('invalid.invalid', nil, 'localhost', 80)
  171. rescue Exception => e
  172. # capture the exception
  173. ensure
  174. EM.stop
  175. end
  176. end
  177. assert_kind_of(EventMachine::ConnectionError, e)
  178. assert_match(/invalid bind address:.*#{INVALID}/, e.message)
  179. end
  180. def test_reactor_thread?
  181. assert !EM.reactor_thread?
  182. EM.run { assert EM.reactor_thread?; EM.stop }
  183. assert !EM.reactor_thread?
  184. end
  185. def test_schedule_on_reactor_thread
  186. x = false
  187. EM.run do
  188. EM.schedule { x = true }
  189. EM.stop
  190. end
  191. assert x
  192. end
  193. def test_schedule_from_thread
  194. x = false
  195. EM.run do
  196. Thread.new { EM.schedule { x = true; EM.stop } }.join
  197. end
  198. assert x
  199. end
  200. def test_set_heartbeat_interval
  201. omit_if(jruby?)
  202. interval = 0.5
  203. EM.run {
  204. EM.set_heartbeat_interval interval
  205. $interval = EM.get_heartbeat_interval
  206. EM.stop
  207. }
  208. assert_equal(interval, $interval)
  209. end
  210. module PostInitRaiser
  211. ERR = Class.new(StandardError)
  212. def post_init
  213. raise ERR
  214. end
  215. end
  216. def test_bubble_errors_from_post_init
  217. assert_raises(PostInitRaiser::ERR) do
  218. EM.run do
  219. EM.start_server "127.0.0.1", @port
  220. EM.connect "127.0.0.1", @port, PostInitRaiser
  221. end
  222. end
  223. end
  224. module InitializeRaiser
  225. ERR = Class.new(StandardError)
  226. def initialize
  227. raise ERR
  228. end
  229. end
  230. def test_bubble_errors_from_initialize
  231. assert_raises(InitializeRaiser::ERR) do
  232. EM.run do
  233. EM.start_server "127.0.0.1", @port
  234. EM.connect "127.0.0.1", @port, InitializeRaiser
  235. end
  236. end
  237. end
  238. def test_schedule_close
  239. omit_if(jruby?)
  240. localhost, port = '127.0.0.1', 9000
  241. timer_ran = false
  242. num_close_scheduled = nil
  243. EM.run do
  244. assert_equal 0, EM.num_close_scheduled
  245. EM.add_timer(1) { timer_ran = true; EM.stop }
  246. EM.start_server localhost, port do |s|
  247. s.close_connection
  248. num_close_scheduled = EM.num_close_scheduled
  249. end
  250. EM.connect localhost, port do |c|
  251. def c.unbind
  252. EM.stop
  253. end
  254. end
  255. end
  256. assert !timer_ran
  257. assert_equal 1, num_close_scheduled
  258. end
  259. def test_error_handler_idempotent # issue 185
  260. errors = []
  261. ticks = []
  262. EM.error_handler do |e|
  263. errors << e
  264. end
  265. EM.run do
  266. EM.next_tick do
  267. ticks << :first
  268. raise
  269. end
  270. EM.next_tick do
  271. ticks << :second
  272. end
  273. EM.add_timer(0.001) { EM.stop }
  274. end
  275. # Remove the error handler before the next test
  276. EM.error_handler(nil)
  277. assert_equal 1, errors.size
  278. assert_equal [:first, :second], ticks
  279. end
  280. end