uv-rays 0.0.1

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.
@@ -0,0 +1,253 @@
1
+ require 'uv-rays'
2
+
3
+ describe UvRays::BufferedTokenizer do
4
+ describe 'delimiter' do
5
+
6
+ before :each do
7
+ @buffer = UvRays::BufferedTokenizer.new({
8
+ delimiter: "\n\r"
9
+ })
10
+ end
11
+
12
+
13
+ it "should not return anything when a complete message is not available" do
14
+ msg1 = "test"
15
+
16
+ result = @buffer.extract(msg1)
17
+ result.should == []
18
+ end
19
+
20
+ it "should tokenize messages where the data is a complete message" do
21
+ msg1 = "test\n\r"
22
+
23
+ result = @buffer.extract(msg1)
24
+ result.should == ['test']
25
+ end
26
+
27
+ it "should return multiple complete messages" do
28
+ msg1 = "test\n\rwhoa\n\r"
29
+
30
+ result = @buffer.extract(msg1)
31
+ result.should == ['test', 'whoa']
32
+ end
33
+
34
+ it "should tokenize messages where the delimiter is split" do
35
+ msg1 = "test\n"
36
+ msg2 = "\rwhoa\n\r"
37
+
38
+ result = @buffer.extract(msg1)
39
+ result.should == []
40
+ result = @buffer.extract(msg2)
41
+ result.should == ['test', 'whoa']
42
+
43
+
44
+ msg3 = "test\n"
45
+ msg4 = "\rwhoa\n"
46
+ msg5 = "\r"
47
+
48
+ result = @buffer.extract(msg3)
49
+ result.should == []
50
+ result = @buffer.extract(msg4)
51
+ result.should == ['test']
52
+
53
+ result = @buffer.extract(msg5)
54
+ result.should == ['whoa']
55
+ end
56
+ end
57
+
58
+ describe 'delimiter' do
59
+
60
+ before :each do
61
+ @buffer = UvRays::BufferedTokenizer.new({
62
+ delimiter: "\n\r"
63
+ })
64
+ end
65
+
66
+
67
+ it "should not return anything when a complete message is not available" do
68
+ msg1 = "test"
69
+
70
+ result = @buffer.extract(msg1)
71
+ result.should == []
72
+ end
73
+
74
+ it "should not return anything when the messages is empty" do
75
+ msg1 = ""
76
+
77
+ result = @buffer.extract(msg1)
78
+ result.should == []
79
+ end
80
+
81
+ it "should tokenize messages where the data is a complete message" do
82
+ msg1 = "test\n\r"
83
+
84
+ result = @buffer.extract(msg1)
85
+ result.should == ['test']
86
+ end
87
+
88
+ it "should return multiple complete messages" do
89
+ msg1 = "test\n\rwhoa\n\r"
90
+
91
+ result = @buffer.extract(msg1)
92
+ result.should == ['test', 'whoa']
93
+ end
94
+
95
+ it "should tokenize messages where the delimiter is split" do
96
+ msg1 = "test\n"
97
+ msg2 = "\rwhoa\n\r"
98
+
99
+ result = @buffer.extract(msg1)
100
+ result.should == []
101
+ result = @buffer.extract(msg2)
102
+ result.should == ['test', 'whoa']
103
+
104
+
105
+ msg3 = "test\n"
106
+ msg4 = "\rwhoa\n"
107
+ msg5 = "\r"
108
+
109
+ result = @buffer.extract(msg3)
110
+ result.should == []
111
+ result = @buffer.extract(msg4)
112
+ result.should == ['test']
113
+
114
+ result = @buffer.extract(msg5)
115
+ result.should == ['whoa']
116
+ end
117
+ end
118
+
119
+
120
+
121
+ describe 'indicator with delimiter' do
122
+
123
+ before :each do
124
+ @buffer = UvRays::BufferedTokenizer.new({
125
+ delimiter: "\n\r",
126
+ indicator: "GO"
127
+ })
128
+ end
129
+
130
+
131
+ it "should not return anything when a complete message is not available" do
132
+ msg1 = "GO-somedata"
133
+
134
+ result = @buffer.extract(msg1)
135
+ result.should == []
136
+ end
137
+
138
+ it "should not return anything when the messages is empty" do
139
+ msg1 = ""
140
+
141
+ result = @buffer.extract(msg1)
142
+ result.should == []
143
+ end
144
+
145
+ it "should tokenize messages where the data is a complete message" do
146
+ msg1 = "GOtest\n\r"
147
+
148
+ result = @buffer.extract(msg1)
149
+ result.should == ['test']
150
+ end
151
+
152
+ it "should discard data that is not relevant" do
153
+ msg1 = "1234-GOtest\n\r"
154
+
155
+ result = @buffer.extract(msg1)
156
+ result.should == ['test']
157
+ end
158
+
159
+ it "should return multiple complete messages" do
160
+ msg1 = "GOtest\n\rGOwhoa\n\r"
161
+
162
+ result = @buffer.extract(msg1)
163
+ result.should == ['test', 'whoa']
164
+ end
165
+
166
+ it "should discard data between multiple complete messages" do
167
+ msg1 = "1234-GOtest\n\r12345-GOwhoa\n\r"
168
+
169
+ result = @buffer.extract(msg1)
170
+ result.should == ['test', 'whoa']
171
+ end
172
+
173
+ it "should tokenize messages where the delimiter is split" do
174
+ msg1 = "GOtest\n"
175
+ msg2 = "\rGOwhoa\n\r"
176
+
177
+ result = @buffer.extract(msg1)
178
+ result.should == []
179
+ result = @buffer.extract(msg2)
180
+ result.should == ['test', 'whoa']
181
+
182
+
183
+ msg3 = "GOtest\n"
184
+ msg4 = "\rGOwhoa\n"
185
+ msg5 = "\r"
186
+
187
+ result = @buffer.extract(msg3)
188
+ result.should == []
189
+ result = @buffer.extract(msg4)
190
+ result.should == ['test']
191
+
192
+ result = @buffer.extract(msg5)
193
+ result.should == ['whoa']
194
+ end
195
+
196
+ it "should tokenize messages where the indicator is split" do
197
+ msg1 = "GOtest\n\rG"
198
+ msg2 = "Owhoa\n"
199
+ msg3 = "\rGOwhoa\n\r"
200
+
201
+ result = @buffer.extract(msg1)
202
+ result.should == ['test']
203
+ result = @buffer.extract(msg2)
204
+ result.should == []
205
+ result = @buffer.extract(msg3)
206
+ result.should == ['whoa', 'whoa']
207
+ end
208
+
209
+ it "should tokenize messages where the indicator is split and there is discard data" do
210
+ msg1 = "GOtest\n\r1234G"
211
+ msg2 = "Owhoa\n"
212
+ msg3 = "\r1234GOwhoa\n\r"
213
+
214
+ result = @buffer.extract(msg1)
215
+ result.should == ['test']
216
+ result = @buffer.extract(msg2)
217
+ result.should == []
218
+ result = @buffer.extract(msg3)
219
+ result.should == ['whoa', 'whoa']
220
+ end
221
+ end
222
+
223
+ describe 'buffer size limit with indicator' do
224
+ before :each do
225
+ @buffer = UvRays::BufferedTokenizer.new({
226
+ delimiter: "\n\r",
227
+ indicator: "Start",
228
+ size_limit: 10
229
+ })
230
+ end
231
+
232
+ it "should empty the buffer if the limit is exceeded" do
233
+ result = @buffer.extract('1234567890G')
234
+ result.should == []
235
+ @buffer.flush.should == '890G'
236
+ end
237
+ end
238
+
239
+ describe 'buffer size limit without indicator' do
240
+ before :each do
241
+ @buffer = UvRays::BufferedTokenizer.new({
242
+ delimiter: "\n\r",
243
+ size_limit: 10
244
+ })
245
+ end
246
+
247
+ it "should empty the buffer if the limit is exceeded" do
248
+ result = @buffer.extract('1234567890G')
249
+ result.should == []
250
+ @buffer.flush.should == ''
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,137 @@
1
+ require 'uv-rays'
2
+
3
+
4
+ module TestConnect
5
+ def post_init
6
+
7
+ end
8
+
9
+ def on_connect(connection)
10
+ @connected = true
11
+ end
12
+
13
+ def on_close
14
+ @disconnected = true
15
+ @loop.stop
16
+ end
17
+
18
+ def on_read(data, connection, port = nil)
19
+ @received = data
20
+ close_connection(:after_writing)
21
+ end
22
+
23
+ def check
24
+ return [@connected, @disconnected, @received]
25
+ end
26
+ end
27
+
28
+ module TestServer
29
+ def post_init *args
30
+ if args[0] == :use_tls
31
+ use_tls
32
+ end
33
+ end
34
+
35
+ def on_connect(conection)
36
+ write('hello')
37
+ end
38
+
39
+ def on_read(*args) #data, ip, port, conection)
40
+ #p "was sent #{data} from port #{port}"
41
+ #send_datagram(data, ip, port)
42
+ @loop.stop
43
+ end
44
+ end
45
+
46
+
47
+ describe UvRays::Connection do
48
+ before :each do
49
+ @loop = Libuv::Loop.new
50
+ @general_failure = []
51
+ @timeout = @loop.timer do
52
+ @loop.stop
53
+ @general_failure << "test timed out"
54
+ end
55
+ @timeout.start(5000)
56
+ end
57
+
58
+ after :each do
59
+ module TestConnect
60
+ remove_const :UR_CONNECTION_CLASS
61
+ end
62
+ module TestServer
63
+ remove_const :UR_CONNECTION_CLASS
64
+ end
65
+ end
66
+
67
+ describe 'basic tcp client server' do
68
+ it "should send some data and shutdown the socket", :network => true do
69
+ @loop.run { |logger|
70
+ logger.progress do |level, errorid, error|
71
+ begin
72
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
73
+ rescue Exception
74
+ @general_failure << 'error in logger'
75
+ end
76
+ end
77
+
78
+ UV.start_server '127.0.0.1', 3210, TestServer
79
+ @klass = UV.connect '127.0.0.1', 3210, TestConnect
80
+ }
81
+
82
+ @general_failure.should == []
83
+ res = @klass.check
84
+ res[0].should == true
85
+ res[1].should == true
86
+ res[2].should == 'hello'
87
+ end
88
+ end
89
+
90
+ describe 'basic tcp client server with tls' do
91
+ it "should send some data and shutdown the socket", :network => true do
92
+ @loop.run { |logger|
93
+ logger.progress do |level, errorid, error|
94
+ begin
95
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
96
+ rescue Exception
97
+ @general_failure << 'error in logger'
98
+ end
99
+ end
100
+
101
+ UV.start_server '127.0.0.1', 3212, TestServer, :use_tls
102
+ @klass = UV.connect '127.0.0.1', 3212, TestConnect
103
+ @klass.use_tls
104
+ }
105
+
106
+ @general_failure.should == []
107
+ res = @klass.check
108
+ res[0].should == true
109
+ res[1].should == true
110
+ res[2].should == 'hello'
111
+ end
112
+ end
113
+
114
+ describe 'basic udp client server' do
115
+ it "should send some data and close the socket", :network => true do
116
+ @loop.run { |logger|
117
+ logger.progress do |level, errorid, error|
118
+ begin
119
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
120
+ rescue Exception
121
+ @general_failure << 'error in logger'
122
+ end
123
+ end
124
+
125
+ UV.open_datagram_socket TestServer, '127.0.0.1', 3210
126
+ @klass = UV.open_datagram_socket TestConnect, '127.0.0.1', 3211
127
+ @klass.send_datagram('hello', '127.0.0.1', 3210)
128
+ }
129
+
130
+ @general_failure.should == []
131
+ res = @klass.check
132
+ res[0].should == nil
133
+ res[1].should == nil
134
+ res[2].should == nil #'hello' (libuv receive bug?)
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,279 @@
1
+ require 'uv-rays'
2
+
3
+
4
+ module HttpServer
5
+ def post_init
6
+ @parser = ::HttpParser::Parser.new(self)
7
+ @state = ::HttpParser::Parser.new_instance
8
+ @state.type = :request
9
+ end
10
+
11
+ def on_message_complete(parser)
12
+ write("HTTP/1.1 200 OK\r\nContent-type: text/html\r\nContent-length: 0\r\n\r\n")
13
+ end
14
+
15
+ def on_read(data, connection)
16
+ if @parser.parse(@state, data)
17
+ p 'parse error'
18
+ p @state.error
19
+ end
20
+ end
21
+ end
22
+
23
+ module OldServer
24
+ def post_init
25
+ @parser = ::HttpParser::Parser.new(self)
26
+ @state = ::HttpParser::Parser.new_instance
27
+ @state.type = :request
28
+ end
29
+
30
+ def on_message_complete(parser)
31
+ write("HTTP/1.0 200 OK\r\nContent-type: text/html\r\nContent-length: 0\r\n\r\n")
32
+ end
33
+
34
+ def on_read(data, connection)
35
+ if @parser.parse(@state, data)
36
+ p 'parse error'
37
+ p @state.error
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ describe UvRays::HttpEndpoint do
44
+ before :each do
45
+ @loop = Libuv::Loop.new
46
+ @general_failure = []
47
+ @timeout = @loop.timer do
48
+ @loop.stop
49
+ @general_failure << "test timed out"
50
+ end
51
+ @timeout.start(5000)
52
+
53
+ @request_failure = proc { |err|
54
+ @general_failure << err
55
+ @loop.stop
56
+ }
57
+ end
58
+
59
+ describe 'basic http request' do
60
+ it "should send a request then receive a response", :network => true do
61
+ @loop.run { |logger|
62
+ logger.progress do |level, errorid, error|
63
+ begin
64
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
65
+ rescue Exception
66
+ @general_failure << 'error in logger'
67
+ end
68
+ end
69
+
70
+ tcp = UV.start_server '127.0.0.1', 3250, HttpServer
71
+ server = UV::HttpEndpoint.new 'http://127.0.0.1:3250'
72
+
73
+ request = server.get(:path => '/')
74
+ request.then(proc { |response|
75
+ @response = response
76
+ tcp.close
77
+ @loop.stop
78
+ }, @request_failure)
79
+ }
80
+
81
+ @general_failure.should == []
82
+ @response[:headers][:"Content-type"].should == 'text/html'
83
+ @response[:headers].http_version.should == '1.1'
84
+ @response[:headers].status.should == 200
85
+ @response[:headers].cookies.should == {}
86
+ @response[:headers].keep_alive.should == true
87
+ end
88
+
89
+ it "should send multiple requests on the same connection", :network => true do
90
+ @loop.run { |logger|
91
+ logger.progress do |level, errorid, error|
92
+ begin
93
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
94
+ rescue Exception
95
+ @general_failure << 'error in logger'
96
+ end
97
+ end
98
+
99
+ tcp = UV.start_server '127.0.0.1', 3250, HttpServer
100
+ server = UV::HttpEndpoint.new 'http://127.0.0.1:3250'
101
+
102
+ request = server.get(:path => '/')
103
+ request.then(proc { |response|
104
+ @response = response
105
+ #@loop.stop
106
+ }, @request_failure)
107
+
108
+ request2 = server.get(:path => '/')
109
+ request2.then(proc { |response|
110
+ @response2 = response
111
+ tcp.close
112
+ @loop.stop
113
+ }, @request_failure)
114
+ }
115
+
116
+ @general_failure.should == []
117
+ @response[:headers][:"Content-type"].should == 'text/html'
118
+ @response[:headers].http_version.should == '1.1'
119
+ @response[:headers].status.should == 200
120
+ @response[:headers].cookies.should == {}
121
+ @response[:headers].keep_alive.should == true
122
+
123
+ @response2[:headers][:"Content-type"].should == 'text/html'
124
+ @response2[:headers].http_version.should == '1.1'
125
+ @response2[:headers].status.should == 200
126
+ @response2[:headers].cookies.should == {}
127
+ @response2[:headers].keep_alive.should == true
128
+ end
129
+
130
+ it "should send pipelined requests on the same connection", :network => true do
131
+ @loop.run { |logger|
132
+ logger.progress do |level, errorid, error|
133
+ begin
134
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
135
+ rescue Exception
136
+ @general_failure << 'error in logger'
137
+ end
138
+ end
139
+
140
+ tcp = UV.start_server '127.0.0.1', 3250, HttpServer
141
+ server = UV::HttpEndpoint.new 'http://127.0.0.1:3250'
142
+
143
+ request = server.get(:path => '/', :pipeline => true)
144
+ request.then(proc { |response|
145
+ @response = response
146
+ #@loop.stop
147
+ }, @request_failure)
148
+
149
+ request2 = server.get(:path => '/', :pipeline => true)
150
+ request2.then(proc { |response|
151
+ @response2 = response
152
+ tcp.close
153
+ @loop.stop
154
+ }, @request_failure)
155
+ }
156
+
157
+ @general_failure.should == []
158
+ @response[:headers][:"Content-type"].should == 'text/html'
159
+ @response[:headers].http_version.should == '1.1'
160
+ @response[:headers].status.should == 200
161
+ @response[:headers].cookies.should == {}
162
+ @response[:headers].keep_alive.should == true
163
+
164
+ @response2[:headers][:"Content-type"].should == 'text/html'
165
+ @response2[:headers].http_version.should == '1.1'
166
+ @response2[:headers].status.should == 200
167
+ @response2[:headers].cookies.should == {}
168
+ @response2[:headers].keep_alive.should == true
169
+ end
170
+ end
171
+
172
+ describe 'old http request' do
173
+ it "should send a request then receive a response", :network => true do
174
+ @loop.run { |logger|
175
+ logger.progress do |level, errorid, error|
176
+ begin
177
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
178
+ rescue Exception
179
+ @general_failure << 'error in logger'
180
+ end
181
+ end
182
+
183
+ tcp = UV.start_server '127.0.0.1', 3250, OldServer
184
+ server = UV::HttpEndpoint.new 'http://127.0.0.1:3250'
185
+
186
+ request = server.get(:path => '/')
187
+ request.then(proc { |response|
188
+ @response = response
189
+ tcp.close
190
+ @loop.stop
191
+ }, @request_failure)
192
+ }
193
+
194
+ @general_failure.should == []
195
+ @response[:headers][:"Content-type"].should == 'text/html'
196
+ @response[:headers].http_version.should == '1.0'
197
+ @response[:headers].status.should == 200
198
+ @response[:headers].cookies.should == {}
199
+ @response[:headers].keep_alive.should == false
200
+ end
201
+
202
+ it "should send multiple requests", :network => true do
203
+ @loop.run { |logger|
204
+ logger.progress do |level, errorid, error|
205
+ begin
206
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
207
+ rescue Exception
208
+ @general_failure << 'error in logger'
209
+ end
210
+ end
211
+
212
+ tcp = UV.start_server '127.0.0.1', 3250, OldServer
213
+ server = UV::HttpEndpoint.new 'http://127.0.0.1:3250'
214
+
215
+ request = server.get(:path => '/')
216
+ request.then(proc { |response|
217
+ @response = response
218
+ #@loop.stop
219
+ }, @request_failure)
220
+
221
+ request2 = server.get(:path => '/')
222
+ request2.then(proc { |response|
223
+ @response2 = response
224
+ tcp.close
225
+ @loop.stop
226
+ }, @request_failure)
227
+ }
228
+
229
+ @general_failure.should == []
230
+ @response[:headers][:"Content-type"].should == 'text/html'
231
+ @response[:headers].http_version.should == '1.0'
232
+ @response[:headers].status.should == 200
233
+ @response[:headers].cookies.should == {}
234
+ @response[:headers].keep_alive.should == false
235
+
236
+ @response2[:headers][:"Content-type"].should == 'text/html'
237
+ @response2[:headers].http_version.should == '1.0'
238
+ @response2[:headers].status.should == 200
239
+ @response2[:headers].cookies.should == {}
240
+ @response2[:headers].keep_alive.should == false
241
+ end
242
+
243
+ it "should fail to send pipelined requests", :network => true do
244
+ @loop.run { |logger|
245
+ logger.progress do |level, errorid, error|
246
+ begin
247
+ @general_failure << "Log called: #{level}: #{errorid}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
248
+ rescue Exception
249
+ @general_failure << 'error in logger'
250
+ end
251
+ end
252
+
253
+ tcp = UV.start_server '127.0.0.1', 3250, OldServer
254
+ server = UV::HttpEndpoint.new 'http://127.0.0.1:3250'
255
+
256
+ request = server.get(:path => '/', :pipeline => true)
257
+ request.then(proc { |response|
258
+ @response = response
259
+ #@loop.stop
260
+ }, @request_failure)
261
+
262
+ request2 = server.get(:path => '/', :pipeline => true)
263
+ request2.then(proc { |response|
264
+ @response2 = response
265
+ tcp.close
266
+ @loop.stop
267
+ }, @request_failure)
268
+ }
269
+
270
+ @general_failure.should == [:disconnected]
271
+ @response[:headers][:"Content-type"].should == 'text/html'
272
+ @response[:headers].http_version.should == '1.0'
273
+ @response[:headers].status.should == 200
274
+ @response[:headers].cookies.should == {}
275
+ @response[:headers].keep_alive.should == false
276
+ # Response 2 was the general failure
277
+ end
278
+ end
279
+ end