eventmachine 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- # $Id: stomp.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id: stomp.rb 738 2008-07-06 01:01:04Z francis $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -120,6 +120,9 @@ module EventMachine
120
120
  def subscribe dest, ack=false
121
121
  send_frame "SUBSCRIBE", {:destination=>dest, :ack=>(ack ? "client" : "auto")}
122
122
  end
123
+ def ack msgid
124
+ send_frame "ACK", { :'message-id'=> msgid }
125
+ end
123
126
 
124
127
  end
125
128
  end
@@ -0,0 +1,66 @@
1
+ # $Id: test_attach.rb 785 2008-09-15 09:46:23Z francis $
2
+ #
3
+ #----------------------------------------------------------------------------
4
+ #
5
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
6
+ # Gmail: blackhedd
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of either: 1) the GNU General Public License
10
+ # as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version; or 2) Ruby's License.
12
+ #
13
+ # See the file COPYING for complete licensing information.
14
+ #
15
+ #---------------------------------------------------------------------------
16
+ #
17
+
18
+ $:.unshift "../lib"
19
+ require 'eventmachine'
20
+ require 'socket'
21
+ require 'test/unit'
22
+
23
+
24
+ class TestAttach < Test::Unit::TestCase
25
+
26
+ Host = "127.0.0.1"
27
+ Port = 9550
28
+
29
+ class EchoServer < EM::Connection
30
+ def receive_data data
31
+ send_data data
32
+ end
33
+ end
34
+
35
+ class EchoClient < EM::Connection
36
+ def connection_completed
37
+ $sock.write("abc\n")
38
+ end
39
+
40
+ def notify_readable
41
+ $read = $sock.readline
42
+ $fd = detach
43
+ end
44
+
45
+ def unbind
46
+ EM.next_tick do
47
+ $sock.write("def\n")
48
+ EM.add_timer(0.5){ EM.stop }
49
+ end
50
+ end
51
+ end
52
+
53
+ def test_attach
54
+ EM.run{
55
+ EM.start_server Host, Port, EchoServer
56
+ $sock = TCPSocket.new Host, Port
57
+ EM.attach $sock, EchoClient
58
+ }
59
+
60
+ assert_equal $read, "abc\n"
61
+ assert_equal $fd, $sock.fileno
62
+ assert_equal false, $sock.closed?
63
+ assert_equal $sock.readline, "def\n"
64
+ end
65
+
66
+ end
@@ -1,4 +1,4 @@
1
- # $Id: test_basic.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id: test_basic.rb 735 2008-07-05 18:18:49Z francis $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -137,6 +137,42 @@ class TestBasic < Test::Unit::TestCase
137
137
  }
138
138
  end
139
139
 
140
- end
141
140
 
141
+ #------------------------------------
142
+ #
143
+ # TODO. This is an unfinished bug fix.
144
+ # This case was originally reported by Dan Aquino. If you throw a Ruby exception
145
+ # in a post_init handler, it gets rethrown as a confusing reactor exception.
146
+ # The problem is in eventmachine.rb, which calls post_init within the private
147
+ # initialize method of the EM::Connection class. This happens in both the EM::connect
148
+ # method and in the code that responds to connection-accepted events.
149
+ # What happens is that we instantiate the new connection object, which calls
150
+ # initialize, and then after initialize returns, we stick the new connection object
151
+ # into EM's @conns hashtable.
152
+ # But the problem is that Connection::initialize calls #post_init before it returns,
153
+ # and this may be user-written code that may throw an uncaught Ruby exception.
154
+ # If that happens, the reactor will abort, and it will then try to run down open
155
+ # connections. Because @conns never got a chance to properly reflect the new connection
156
+ # (because initialize never returned), we throw a ConnectionNotBound error
157
+ # (eventmachine.rb line 1080).
158
+ # When the bug is fixed, activate this test case.
159
+ #
160
+
161
+ class PostInitError < EM::Connection
162
+ def post_init
163
+ aaa bbb # should produce a Ruby exception
164
+ end
165
+ end
166
+ def test_post_init_error
167
+ assert_raise( NameError ) {
168
+ EM.run {
169
+ EM::Timer.new(1) {EM.stop}
170
+ EM.start_server TestHost, TestPort
171
+ EM.connect TestHost, TestPort, PostInitError
172
+ }
173
+ }
174
+ end
175
+
176
+
177
+ end
142
178
 
@@ -1,4 +1,4 @@
1
- # $Id: test_hc.rb 668 2008-01-04 23:00:34Z blackhedd $
1
+ # $Id: test_hc.rb 721 2008-06-21 00:45:57Z francis $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -33,119 +33,157 @@ require 'test/unit'
33
33
  # Part of it is thread race conditions. I added some sleeps to make these
34
34
  # tests work. Native threads do strange things when you do I/O on them.
35
35
  #
36
+ # And it's even worse in Java, where I/O on native threads doesn't seem
37
+ # to be reliable at all.
38
+ #
36
39
 
37
40
 
38
41
  class TestHeaderAndContentProtocol < Test::Unit::TestCase
39
42
 
40
- TestHost = "127.0.0.1"
41
- TestPort = 8905
43
+ TestHost = "127.0.0.1"
44
+ TestPort = 8905
42
45
 
43
46
 
44
- #--------------------------------------------------------------------
47
+ #--------------------------------------------------------------------
45
48
 
46
- class SimpleTest < EventMachine::Protocols::HeaderAndContentProtocol
47
- attr_reader :first_header, :my_headers, :request
49
+ class SimpleTest < EventMachine::Protocols::HeaderAndContentProtocol
50
+ attr_reader :first_header, :my_headers, :request
48
51
 
49
- def receive_first_header_line hdr
50
- @first_header ||= []
51
- @first_header << hdr
52
+ def receive_first_header_line hdr
53
+ @first_header ||= []
54
+ @first_header << hdr
55
+ end
56
+ def receive_headers hdrs
57
+ @my_headers ||= []
58
+ @my_headers << hdrs
59
+ end
60
+ def receive_request hdrs, content
61
+ @request ||= []
62
+ @request << [hdrs, content]
63
+ end
52
64
  end
53
- def receive_headers hdrs
54
- @my_headers ||= []
55
- @my_headers << hdrs
65
+
66
+
67
+ def test_no_content
68
+ Thread.abort_on_exception = true
69
+ the_connection = nil
70
+ EventMachine.run {
71
+ EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
72
+ the_connection = conn
73
+ end
74
+ EventMachine.add_timer(4) {raise "test timed out"}
75
+
76
+ pr = proc {
77
+ t = TCPSocket.new TestHost, TestPort
78
+ t.write [ "aaa\n", "bbb\r\n", "ccc\n", "\n" ].join
79
+ t.close
80
+ }
81
+
82
+ if RUBY_PLATFORM =~ /java/i
83
+ pr.call
84
+ EM.add_timer(0.5) {EM.stop}
85
+ else
86
+ EventMachine.defer proc {
87
+ pr.call
88
+ if RUBY_VERSION =~ /\A1\.9\./
89
+ sleep 0.1
90
+ STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
91
+ end
92
+ }, proc {
93
+ EventMachine.stop
94
+ }
95
+ end
96
+ }
97
+ assert_equal( ["aaa"], the_connection.first_header )
98
+ assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers )
99
+ assert_equal( [[%w(aaa bbb ccc), ""]], the_connection.request )
56
100
  end
57
- def receive_request hdrs, content
58
- @request ||= []
59
- @request << [hdrs, content]
101
+
102
+
103
+
104
+
105
+ def test_content
106
+ Thread.abort_on_exception = true
107
+ the_connection = nil
108
+ content = "A" * 50
109
+ headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"]
110
+ EventMachine.run {
111
+ EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
112
+ the_connection = conn
113
+ end
114
+ EventMachine.add_timer(4) {raise "test timed out"}
115
+
116
+ pr = proc {
117
+ t = TCPSocket.new TestHost, TestPort
118
+ headers.each {|h| t.write "#{h}\r\n" }
119
+ t.write "\n"
120
+ t.write content
121
+ t.close
122
+ }
123
+
124
+ if RUBY_PLATFORM =~ /java/i
125
+ # I/O on threads seems completely unreliable in Java.
126
+ pr.call
127
+ EM.add_timer(0.5) {EM.stop}
128
+ else
129
+ EventMachine.defer proc {
130
+ pr.call
131
+ if RUBY_VERSION =~ /\A1\.9\./
132
+ sleep 0.1
133
+ STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
134
+ end
135
+ }, proc {
136
+ EM.stop
137
+ }
138
+ end
139
+ }
140
+ assert_equal( ["aaa"], the_connection.first_header )
141
+ assert_equal( [headers], the_connection.my_headers )
142
+ assert_equal( [[headers, content]], the_connection.request )
60
143
  end
61
- end
62
144
 
63
- def test_no_content
64
- Thread.abort_on_exception = true
65
- the_connection = nil
66
- EventMachine.run {
67
- EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
68
- the_connection = conn
69
- end
70
- EventMachine.add_timer(4) {raise "test timed out"}
71
- EventMachine.defer proc {
72
- t = TCPSocket.new TestHost, TestPort
73
- t.write [
74
- "aaa\n", "bbb\r\n", "ccc\n", "\n"
75
- ].join
76
- t.close
77
- if RUBY_VERSION =~ /\A1\.9\./
78
- sleep 0.1
79
- STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
80
- end
81
- }, proc {
82
- EventMachine.stop
83
- }
84
- }
85
- assert_equal( ["aaa"], the_connection.first_header )
86
- assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers )
87
- assert_equal( [[%w(aaa bbb ccc), ""]], the_connection.request )
88
- end
89
145
 
90
- def test_content
91
- Thread.abort_on_exception = true
92
- the_connection = nil
93
- content = "A" * 50
94
- headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"]
95
- EventMachine.run {
96
- EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
97
- the_connection = conn
98
- end
99
- EventMachine.add_timer(4) {raise "test timed out"}
100
- EventMachine.defer proc {
101
- t = TCPSocket.new TestHost, TestPort
102
- headers.each {|h| t.write "#{h}\r\n" }
103
- t.write "\n"
104
- t.write content
105
- t.close
106
- if RUBY_VERSION =~ /\A1\.9\./
107
- sleep 0.1
108
- STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
109
- end
110
- }, proc {
111
- EM.stop
112
- }
113
- }
114
- assert_equal( ["aaa"], the_connection.first_header )
115
- assert_equal( [headers], the_connection.my_headers )
116
- assert_equal( [[headers, content]], the_connection.request )
117
- end
118
146
 
119
- def test_several_requests
120
- Thread.abort_on_exception = true
121
- the_connection = nil
122
- content = "A" * 50
123
- headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"]
124
- EventMachine.run {
125
- EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
126
- the_connection = conn
127
- end
128
- EventMachine.add_timer(4) {raise "test timed out"}
129
- EventMachine.defer proc {
130
- t = TCPSocket.new TestHost, TestPort
131
- 5.times {
132
- headers.each {|h| t.write "#{h}\r\n" }
133
- t.write "\n"
134
- t.write content
147
+ def test_several_requests
148
+ Thread.abort_on_exception = true
149
+ the_connection = nil
150
+ content = "A" * 50
151
+ headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"]
152
+ EventMachine.run {
153
+ EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
154
+ the_connection = conn
155
+ end
156
+ EventMachine.add_timer(4) {raise "test timed out"}
157
+
158
+ pr = proc {
159
+ t = TCPSocket.new TestHost, TestPort
160
+ 5.times {
161
+ headers.each {|h| t.write "#{h}\r\n" }
162
+ t.write "\n"
163
+ t.write content
164
+ }
165
+ t.close
166
+ }
167
+
168
+ if RUBY_PLATFORM =~ /java/i
169
+ pr.call
170
+ EM.add_timer(1) {EM.stop}
171
+ else
172
+ EventMachine.defer proc {
173
+ pr.call
174
+ if RUBY_VERSION =~ /\A1\.9\./
175
+ sleep 0.1
176
+ STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
177
+ end
178
+ }, proc {
179
+ EventMachine.stop
180
+ }
181
+ end
135
182
  }
136
- t.close
137
- if RUBY_VERSION =~ /\A1\.9\./
138
- sleep 0.1
139
- STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
140
- end
141
- }, proc {
142
- EventMachine.stop
143
- }
144
- }
145
- assert_equal( ["aaa"] * 5, the_connection.first_header )
146
- assert_equal( [headers] * 5, the_connection.my_headers )
147
- assert_equal( [[headers, content]] * 5, the_connection.request )
148
- end
183
+ assert_equal( ["aaa"] * 5, the_connection.first_header )
184
+ assert_equal( [headers] * 5, the_connection.my_headers )
185
+ assert_equal( [[headers, content]] * 5, the_connection.request )
186
+ end
149
187
 
150
188
 
151
189
  def x_test_multiple_content_length_headers
@@ -171,50 +209,60 @@ class TestHeaderAndContentProtocol < Test::Unit::TestCase
171
209
  }
172
210
  end
173
211
 
174
- def test_interpret_headers
175
- Thread.abort_on_exception = true
176
- the_connection = nil
177
- content = "A" * 50
178
- headers = [
179
- "GET / HTTP/1.0",
180
- "Accept: aaa",
181
- "User-Agent: bbb",
182
- "Host: ccc",
183
- "x-tempest-header:ddd"
184
- ]
185
- EventMachine.run {
186
- EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
187
- the_connection = conn
188
- end
189
- EventMachine.add_timer(4) {raise "test timed out"}
190
- EventMachine.defer proc {
191
- t = TCPSocket.new TestHost, TestPort
192
- headers.each {|h| t.write "#{h}\r\n" }
193
- t.write "\n"
194
- t.write content
195
- t.close
196
- if RUBY_VERSION =~ /\A1\.9\./
197
- sleep 0.1
198
- STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
199
- end
200
- }, proc {
201
- EventMachine.stop
202
- }
203
- }
212
+ def test_interpret_headers
213
+ Thread.abort_on_exception = true
214
+ the_connection = nil
215
+ content = "A" * 50
216
+ headers = [
217
+ "GET / HTTP/1.0",
218
+ "Accept: aaa",
219
+ "User-Agent: bbb",
220
+ "Host: ccc",
221
+ "x-tempest-header:ddd"
222
+ ]
204
223
 
205
- hsh = the_connection.headers_2_hash( the_connection.my_headers.shift )
206
- assert_equal(
207
- {
208
- :accept => "aaa",
209
- :user_agent => "bbb",
210
- :host => "ccc",
211
- :x_tempest_header => "ddd"
212
- },
213
- hsh
214
- )
215
- end
224
+ EventMachine.run {
225
+ EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
226
+ the_connection = conn
227
+ end
228
+ EventMachine.add_timer(4) {raise "test timed out"}
229
+
230
+ pr = proc {
231
+ t = TCPSocket.new TestHost, TestPort
232
+ headers.each {|h| t.write "#{h}\r\n" }
233
+ t.write "\n"
234
+ t.write content
235
+ t.close
236
+ }
237
+
238
+ if RUBY_PLATFORM =~ /java/i
239
+ pr.call
240
+ EM.add_timer(0.5) {EM.stop}
241
+ else
242
+ EventMachine.defer proc {
243
+ pr.call
244
+ if RUBY_VERSION =~ /\A1\.9\./
245
+ sleep 0.1
246
+ STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
247
+ end
248
+ }, proc {
249
+ EventMachine.stop
250
+ }
251
+ end
252
+ }
253
+
254
+ hsh = the_connection.headers_2_hash( the_connection.my_headers.shift )
255
+ assert_equal(
256
+ {
257
+ :accept => "aaa",
258
+ :user_agent => "bbb",
259
+ :host => "ccc",
260
+ :x_tempest_header => "ddd"
261
+ },
262
+ hsh
263
+ )
264
+ end
216
265
 
217
- #--------------------------------------------------------------------
218
266
 
219
267
  end
220
268