eventmachine 0.12.0 → 0.12.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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