OSDN Git Service

Replaced mongrel with thin
[redminele/redminele.git] / ruby / lib / ruby / gems / 1.8 / gems / eventmachine-0.12.10-x86-mswin32-60 / tests / test_basic.rb
1 # $Id$
2 #
3 # Author:: Francis Cianfrocca (gmail: blackhedd)
4 # Homepage::  http://rubyeventmachine.com
5 # Date:: 8 April 2006
6
7 # See EventMachine and EventMachine::Connection for documentation and
8 # usage examples.
9 #
10 #----------------------------------------------------------------------------
11 #
12 # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13 # Gmail: blackhedd
14
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of either: 1) the GNU General Public License
17 # as published by the Free Software Foundation; either version 2 of the
18 # License, or (at your option) any later version; or 2) Ruby's License.
19
20 # See the file COPYING for complete licensing information.
21 #
22 #---------------------------------------------------------------------------
23 #
24 #
25
26
27 $:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
28 require 'eventmachine'
29 require 'socket'
30 require 'test/unit'
31
32 class TestBasic < Test::Unit::TestCase
33
34   def setup
35     assert(!EM.reactor_running?)
36   end
37
38   def teardown
39     assert(!EM.reactor_running?)
40   end
41
42   #-------------------------------------
43
44   def test_libtype
45     lt = EventMachine.library_type
46     em_lib = (ENV["EVENTMACHINE_LIBRARY"] || $eventmachine_library || :xxx).to_sym
47
48     # Running from test runner, under jruby.
49     if RUBY_PLATFORM == 'java'
50       unless em_lib == :pure_ruby
51         assert_equal( :java, lt )
52         return
53       end
54     end
55
56     case em_lib
57     when :pure_ruby
58       assert_equal( :pure_ruby, lt )
59     when :extension
60       assert_equal( :extension, lt )
61     when :java
62       assert_equal( :java, lt )
63     else
64       # Running from jruby as a standalone test.
65       if RUBY_PLATFORM == 'java'
66         assert_equal( :java, lt )
67       else
68         assert_equal( :extension, lt )
69       end
70     end
71   end
72
73   #-------------------------------------
74
75
76   def test_em
77     EventMachine.run {
78       EventMachine.add_timer 0 do
79         EventMachine.stop
80       end
81     }
82   end
83
84   #-------------------------------------
85
86   def test_timer
87     n = 0
88     EventMachine.run {
89       EventMachine.add_periodic_timer(0.1) {
90         n += 1
91         EventMachine.stop if n == 2
92       }
93     }
94   end
95
96   #-------------------------------------
97
98   # This test once threw an already-running exception.
99   module Trivial
100     def post_init
101       EventMachine.stop
102     end
103   end
104
105   def test_server
106     EventMachine.run {
107       EventMachine.start_server "localhost", 9000, Trivial
108       EventMachine.connect "localhost", 9000
109     }
110     assert( true ) # make sure it halts
111   end
112
113   #--------------------------------------
114
115   # EventMachine#run_block starts the reactor loop, runs the supplied block, and then STOPS
116   # the loop automatically. Contrast with EventMachine#run, which keeps running the reactor
117   # even after the supplied block completes.
118   def test_run_block
119     assert !EM.reactor_running?
120     a = nil
121     EM.run_block { a = "Worked" }
122     assert a
123     assert !EM.reactor_running?
124   end
125
126
127   #--------------------------------------
128
129   # TODO! This is an unfinished edge case.
130   # EM mishandles uncaught Ruby exceptions that fire from within #unbind handlers.
131   # A uncaught Ruby exception results in a call to EM::release_machine (which is in an ensure
132   # block in EM::run). But if EM is processing an unbind request, the release_machine call
133   # will cause a segmentation fault.
134   #
135
136   TestHost = "127.0.0.1"
137   TestPort = 9070
138
139   class UnbindError < EM::Connection
140     def initialize *args
141       super
142     end
143     def connection_completed
144       close_connection_after_writing
145     end
146     def unbind
147       raise "Blooey"
148     end
149   end
150
151   def xxx_test_unbind_error
152     assert_raises( RuntimeError ) {
153       EM.run {
154         EM.start_server TestHost, TestPort
155         EM.connect TestHost, TestPort, UnbindError
156       }
157     }
158   end
159
160   #------------------------------------
161   #
162   # TODO. This is an unfinished bug fix.
163   # This case was originally reported by Dan Aquino. If you throw a Ruby exception
164   # in a post_init handler, it gets rethrown as a confusing reactor exception.
165   # The problem is in eventmachine.rb, which calls post_init within the private
166   # initialize method of the EM::Connection class. This happens in both the EM::connect
167   # method and in the code that responds to connection-accepted events.
168   # What happens is that we instantiate the new connection object, which calls
169   # initialize, and then after initialize returns, we stick the new connection object
170   # into EM's @conns hashtable.
171   # But the problem is that Connection::initialize calls #post_init before it returns,
172   # and this may be user-written code that may throw an uncaught Ruby exception.
173   # If that happens, the reactor will abort, and it will then try to run down open
174   # connections. Because @conns never got a chance to properly reflect the new connection
175   # (because initialize never returned), we throw a ConnectionNotBound error
176   # (eventmachine.rb line 1080).
177   # When the bug is fixed, activate this test case.
178   #
179
180   class PostInitError < EM::Connection
181     def post_init
182       aaa bbb # should produce a Ruby exception
183     end
184   end
185   # This test causes issues, the machine becomes unreleasable after 
186   # release_machine suffers an exception in event_callback.
187   def xxx_test_post_init_error
188     assert_raises( EventMachine::ConnectionNotBound ) {
189       EM.run {
190         EM::Timer.new(1) {EM.stop}
191         EM.start_server TestHost, TestPort
192         EM.connect TestHost, TestPort, PostInitError
193       }
194     }
195     EM.run {
196       EM.stop
197     }
198     assert !EM.reactor_running?
199   end
200
201   module BrsTestSrv
202     def receive_data data
203       $received << data
204     end
205     def unbind
206       EM.stop
207     end
208   end
209   module BrsTestCli
210     def post_init
211       send_data $sent
212       close_connection_after_writing
213     end
214   end
215
216   # From ticket #50
217   def test_byte_range_send
218     $received = ''
219     $sent = (0..255).to_a.pack('C*')
220     EM::run {
221       EM::start_server TestHost, TestPort, BrsTestSrv
222       EM::connect TestHost, TestPort, BrsTestCli
223
224       EM::add_timer(0.5) { assert(false, 'test timed out'); EM.stop; Kernel.warn "test timed out!" }
225     }
226     assert_equal($sent, $received)
227   end
228
229   def test_bind_connect
230     local_ip = UDPSocket.open {|s| s.connect('google.com', 80); s.addr.last }
231
232     bind_port = rand(33333)+1025
233
234     test = self
235     EM.run do
236       EM.start_server(TestHost, TestPort, Module.new do
237         define_method :post_init do
238           begin
239             test.assert_equal bind_port, Socket.unpack_sockaddr_in(get_peername).first
240             test.assert_equal local_ip, Socket.unpack_sockaddr_in(get_peername).last
241           ensure
242             EM.stop_event_loop
243           end
244         end
245       end)
246       EM.bind_connect local_ip, bind_port, TestHost, TestPort
247     end
248   end
249
250   def test_reactor_thread?
251     assert !EM.reactor_thread?
252     EM.run { assert EM.reactor_thread?; EM.stop }
253     assert !EM.reactor_thread?
254   end
255
256   def test_schedule_on_reactor_thread
257     x = false
258     EM.run do
259       EM.schedule { x = true }
260       EM.stop
261     end
262     assert x
263   end
264   
265   def test_schedule_from_thread
266     x = false
267     assert !x
268     EM.run do
269       Thread.new { EM.schedule { x = true; EM.stop } }.join
270     end
271     assert x
272   end
273
274   def test_set_heartbeat_interval
275     interval = 0.5
276     EM.run {
277       EM.set_heartbeat_interval interval
278       $interval = EM.get_heartbeat_interval
279       EM.stop
280     }
281     assert_equal(interval, $interval)
282   end
283 end
284