mt-uv-rays 2.4.7
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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +63 -0
- data/Rakefile +22 -0
- data/lib/faraday/adapter/mt-libuv.rb +89 -0
- data/lib/handsoap/http/drivers/mt-libuv_driver.rb +43 -0
- data/lib/httpi/adapter/mt-libuv.rb +69 -0
- data/lib/mt-uv-rays/abstract_tokenizer.rb +121 -0
- data/lib/mt-uv-rays/buffered_tokenizer.rb +176 -0
- data/lib/mt-uv-rays/connection.rb +190 -0
- data/lib/mt-uv-rays/http/encoding.rb +131 -0
- data/lib/mt-uv-rays/http/parser.rb +175 -0
- data/lib/mt-uv-rays/http/request.rb +262 -0
- data/lib/mt-uv-rays/http_endpoint.rb +336 -0
- data/lib/mt-uv-rays/ping.rb +189 -0
- data/lib/mt-uv-rays/scheduler/time.rb +307 -0
- data/lib/mt-uv-rays/scheduler.rb +386 -0
- data/lib/mt-uv-rays/tcp_server.rb +46 -0
- data/lib/mt-uv-rays/version.rb +5 -0
- data/lib/mt-uv-rays.rb +94 -0
- data/mt-uv-rays.gemspec +38 -0
- data/spec/abstract_tokenizer_spec.rb +129 -0
- data/spec/buffered_tokenizer_spec.rb +277 -0
- data/spec/connection_spec.rb +124 -0
- data/spec/http_endpoint_spec.rb +636 -0
- data/spec/ping_spec.rb +73 -0
- data/spec/scheduler_spec.rb +118 -0
- data/spec/scheduler_time_spec.rb +132 -0
- metadata +300 -0
@@ -0,0 +1,277 @@
|
|
1
|
+
require 'mt-uv-rays'
|
2
|
+
|
3
|
+
describe MTUV::BufferedTokenizer do
|
4
|
+
describe 'delimiter' do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
@buffer = MTUV::BufferedTokenizer.new({
|
8
|
+
delimiter: "\n\r",
|
9
|
+
encoding: "ASCII-8BIT"
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not return empty messages" do
|
14
|
+
msg1 = "\n\rtest\n\r\n\rwhoa\n\r\n\r"
|
15
|
+
|
16
|
+
result = @buffer.extract(msg1)
|
17
|
+
expect(result).to eq(['test', 'whoa'])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not return anything when a complete message is not available" do
|
21
|
+
msg1 = "test"
|
22
|
+
|
23
|
+
result = @buffer.extract(msg1)
|
24
|
+
expect(result).to eq([])
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not return anything when the messages is empty" do
|
28
|
+
msg1 = ""
|
29
|
+
|
30
|
+
result = @buffer.extract(msg1)
|
31
|
+
expect(result).to eq([])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should tokenize messages where the data is a complete message" do
|
35
|
+
msg1 = "test\n\r"
|
36
|
+
|
37
|
+
result = @buffer.extract(msg1)
|
38
|
+
expect(result).to eq(['test'])
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return multiple complete messages" do
|
42
|
+
msg1 = "test\n\rwhoa\n\r"
|
43
|
+
|
44
|
+
result = @buffer.extract(msg1)
|
45
|
+
expect(result).to eq(['test', 'whoa'])
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should tokenize messages where the delimiter is split" do
|
49
|
+
msg1 = "test\n"
|
50
|
+
msg2 = "\rwhoa\n\r"
|
51
|
+
|
52
|
+
result = @buffer.extract(msg1)
|
53
|
+
expect(result).to eq([])
|
54
|
+
result = @buffer.extract(msg2)
|
55
|
+
expect(result).to eq(['test', 'whoa'])
|
56
|
+
|
57
|
+
|
58
|
+
msg3 = "test\n"
|
59
|
+
msg4 = "\rwhoa\n"
|
60
|
+
msg5 = "\r"
|
61
|
+
|
62
|
+
result = @buffer.extract(msg3)
|
63
|
+
expect(result).to eq([])
|
64
|
+
result = @buffer.extract(msg4)
|
65
|
+
expect(result).to eq(['test'] )
|
66
|
+
|
67
|
+
result = @buffer.extract(msg5)
|
68
|
+
expect(result).to eq(['whoa'])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
describe 'indicator with delimiter' do
|
75
|
+
|
76
|
+
before :each do
|
77
|
+
@buffer = MTUV::BufferedTokenizer.new({
|
78
|
+
delimiter: "\n\r",
|
79
|
+
indicator: "GO"
|
80
|
+
})
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
it "should not return anything when a complete message is not available" do
|
85
|
+
msg1 = "GO-somedata"
|
86
|
+
|
87
|
+
result = @buffer.extract(msg1)
|
88
|
+
expect(result).to eq([])
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should not return anything when the messages is empty" do
|
92
|
+
msg1 = ""
|
93
|
+
|
94
|
+
result = @buffer.extract(msg1)
|
95
|
+
expect(result).to eq([])
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should tokenize messages where the data is a complete message" do
|
99
|
+
msg1 = "GOtest\n\r"
|
100
|
+
|
101
|
+
result = @buffer.extract(msg1)
|
102
|
+
expect(result).to eq(['test'])
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should discard data that is not relevant" do
|
106
|
+
msg1 = "1234-GOtest\n\r"
|
107
|
+
|
108
|
+
result = @buffer.extract(msg1)
|
109
|
+
expect(result).to eq(['test'])
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should return multiple complete messages" do
|
113
|
+
msg1 = "GOtest\n\rGOwhoa\n\r"
|
114
|
+
|
115
|
+
result = @buffer.extract(msg1)
|
116
|
+
expect(result).to eq(['test', 'whoa'])
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should discard data between multiple complete messages" do
|
120
|
+
msg1 = "1234-GOtest\n\r12345-GOwhoa\n\r"
|
121
|
+
|
122
|
+
result = @buffer.extract(msg1)
|
123
|
+
expect(result).to eq(['test', 'whoa'])
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should tokenize messages where the delimiter is split" do
|
127
|
+
msg1 = "GOtest\n"
|
128
|
+
msg2 = "\rGOwhoa\n\r"
|
129
|
+
|
130
|
+
result = @buffer.extract(msg1)
|
131
|
+
expect(result).to eq([])
|
132
|
+
result = @buffer.extract(msg2)
|
133
|
+
expect(result).to eq(['test', 'whoa'])
|
134
|
+
|
135
|
+
|
136
|
+
msg3 = "GOtest\n"
|
137
|
+
msg4 = "\rGOwhoa\n"
|
138
|
+
msg5 = "\r"
|
139
|
+
|
140
|
+
result = @buffer.extract(msg3)
|
141
|
+
expect(result).to eq([])
|
142
|
+
result = @buffer.extract(msg4)
|
143
|
+
expect(result).to eq(['test'] )
|
144
|
+
|
145
|
+
result = @buffer.extract(msg5)
|
146
|
+
expect(result).to eq(['whoa'])
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should tokenize messages where the indicator is split" do
|
150
|
+
msg1 = "GOtest\n\rG"
|
151
|
+
msg2 = "Owhoa\n"
|
152
|
+
msg3 = "\rGOwhoa\n\r"
|
153
|
+
|
154
|
+
result = @buffer.extract(msg1)
|
155
|
+
expect(result).to eq(['test'])
|
156
|
+
result = @buffer.extract(msg2)
|
157
|
+
expect(result).to eq([])
|
158
|
+
result = @buffer.extract(msg3)
|
159
|
+
expect(result).to eq(['whoa', 'whoa'])
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should tokenize messages where the indicator is split and there is discard data" do
|
163
|
+
msg1 = "GOtest\n\r1234G"
|
164
|
+
msg2 = "Owhoa\n"
|
165
|
+
msg3 = "\r1234GOwhoa\n\r"
|
166
|
+
|
167
|
+
result = @buffer.extract(msg1)
|
168
|
+
expect(result).to eq(['test'])
|
169
|
+
result = @buffer.extract(msg2)
|
170
|
+
expect(result).to eq([])
|
171
|
+
result = @buffer.extract(msg3)
|
172
|
+
expect(result).to eq(['whoa', 'whoa'])
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'indicator with length' do
|
177
|
+
before :each do
|
178
|
+
@buffer = MTUV::BufferedTokenizer.new({
|
179
|
+
indicator: "GO",
|
180
|
+
msg_length: 4 # length without the indicator
|
181
|
+
})
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should not return anything when a complete message is not available" do
|
185
|
+
msg1 = "GO123"
|
186
|
+
|
187
|
+
result = @buffer.extract(msg1)
|
188
|
+
expect(result).to eq([])
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should not return anything when the messages is empty" do
|
192
|
+
msg1 = ""
|
193
|
+
|
194
|
+
result = @buffer.extract(msg1)
|
195
|
+
expect(result).to eq([])
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should tokenize messages where the data is a complete message" do
|
199
|
+
msg1 = "GO1234"
|
200
|
+
|
201
|
+
result = @buffer.extract(msg1)
|
202
|
+
expect(result).to eq(['1234'])
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should discard data that is not relevant" do
|
206
|
+
msg1 = "1234-GO1234"
|
207
|
+
|
208
|
+
result = @buffer.extract(msg1)
|
209
|
+
expect(result).to eq(['1234'])
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should return multiple complete messages" do
|
213
|
+
msg1 = "GO1234GOhome"
|
214
|
+
|
215
|
+
result = @buffer.extract(msg1)
|
216
|
+
expect(result).to eq(['1234', 'home'])
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should discard data between multiple complete messages" do
|
220
|
+
msg1 = "1234-GO123412345-GOhome"
|
221
|
+
|
222
|
+
result = @buffer.extract(msg1)
|
223
|
+
expect(result).to eq(['1234', 'home'])
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should tokenize messages where the indicator is split" do
|
227
|
+
msg1 = "GOtestG"
|
228
|
+
msg2 = "Owhoa"
|
229
|
+
|
230
|
+
result = @buffer.extract(msg1)
|
231
|
+
expect(result).to eq(['test'])
|
232
|
+
result = @buffer.extract(msg2)
|
233
|
+
expect(result).to eq(['whoa'])
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should tokenize messages where the indicator is split and there is discard data" do
|
237
|
+
msg1 = "GOtest\n\r1234G"
|
238
|
+
msg2 = "Owhoa\n"
|
239
|
+
|
240
|
+
result = @buffer.extract(msg1)
|
241
|
+
expect(result).to eq(['test'])
|
242
|
+
result = @buffer.extract(msg2)
|
243
|
+
expect(result).to eq(['whoa'])
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe 'buffer size limit with indicator' do
|
248
|
+
before :each do
|
249
|
+
@buffer = MTUV::BufferedTokenizer.new({
|
250
|
+
delimiter: "\n\r",
|
251
|
+
indicator: "Start",
|
252
|
+
size_limit: 10
|
253
|
+
})
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should empty the buffer if the limit is exceeded" do
|
257
|
+
result = @buffer.extract('1234567890G')
|
258
|
+
expect(result).to eq([])
|
259
|
+
expect(@buffer.flush).to eq('890G')
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe 'buffer size limit without indicator' do
|
264
|
+
before :each do
|
265
|
+
@buffer = MTUV::BufferedTokenizer.new({
|
266
|
+
delimiter: "\n\r",
|
267
|
+
size_limit: 10
|
268
|
+
})
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should empty the buffer if the limit is exceeded" do
|
272
|
+
result = @buffer.extract('1234567890G')
|
273
|
+
expect(result).to eq([])
|
274
|
+
expect(@buffer.flush).to eq('')
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'mt-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
|
+
@reactor.stop
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_read(data, connection, port = nil, udp_test = nil)
|
19
|
+
@received = data
|
20
|
+
close_connection(:after_writing)
|
21
|
+
@reactor.stop if udp_test # misc is set when test connect is a UDP connection
|
22
|
+
end
|
23
|
+
|
24
|
+
def check
|
25
|
+
return [@connected, @disconnected, @received]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module TestServer
|
30
|
+
def post_init *args
|
31
|
+
if args[0] == :use_tls
|
32
|
+
use_tls
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_connect(conection)
|
37
|
+
write('hello')
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_read(data, ip, port, conection)
|
41
|
+
# ephemeral port is used for sending on windows and linux?
|
42
|
+
# Bound port seems to be used on OSX...
|
43
|
+
# TODO:: Needs investigation, might be a MTLibuv bug
|
44
|
+
send_datagram(data, ip, 3211)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
describe MTUV::Connection do
|
50
|
+
before :each do
|
51
|
+
@reactor = MTLibuv::Reactor.new
|
52
|
+
@reactor.notifier do |error, context|
|
53
|
+
begin
|
54
|
+
@general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
|
55
|
+
rescue Exception
|
56
|
+
@general_failure << "error in logger #{e.inspect}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
@general_failure = []
|
60
|
+
@timeout = @reactor.timer do
|
61
|
+
@reactor.stop
|
62
|
+
@general_failure << "test timed out"
|
63
|
+
end
|
64
|
+
@timeout.start(5000)
|
65
|
+
end
|
66
|
+
|
67
|
+
after :each do
|
68
|
+
module TestConnect
|
69
|
+
begin
|
70
|
+
remove_const :UR_CONNECTION_CLASS
|
71
|
+
rescue
|
72
|
+
end
|
73
|
+
end
|
74
|
+
module TestServer
|
75
|
+
begin
|
76
|
+
remove_const :UR_CONNECTION_CLASS
|
77
|
+
rescue
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'basic tcp client server' do
|
83
|
+
it "should send some data and shutdown the socket" do
|
84
|
+
@reactor.run { |reactor|
|
85
|
+
MTUV.start_server '127.0.0.1', 3210, TestServer
|
86
|
+
@klass = MTUV.connect '127.0.0.1', 3210, TestConnect
|
87
|
+
}
|
88
|
+
|
89
|
+
expect(@general_failure).to eq([])
|
90
|
+
res = @klass.check
|
91
|
+
expect(res[0]).to eq(true)
|
92
|
+
expect(res[1]).to eq(true)
|
93
|
+
expect(res[2]).to eq('hello')
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should not call connect on connection failure" do
|
97
|
+
@reactor.run { |reactor|
|
98
|
+
@klass = MTUV.connect '127.0.0.1', 8123, TestConnect
|
99
|
+
}
|
100
|
+
|
101
|
+
expect(@general_failure).to eq([])
|
102
|
+
res = @klass.check
|
103
|
+
expect(res[0]).to eq(nil)
|
104
|
+
expect(res[1]).to eq(true) # Disconnect
|
105
|
+
expect(res[2]).to eq(nil)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'basic udp client server' do
|
110
|
+
it "should send some data and close the socket" do
|
111
|
+
@reactor.run { |reactor|
|
112
|
+
MTUV.open_datagram_socket TestServer, '127.0.0.1', 3210
|
113
|
+
@klass = MTUV.open_datagram_socket TestConnect, '127.0.0.1', 3211
|
114
|
+
@klass.send_datagram('hello', '127.0.0.1', 3210)
|
115
|
+
}
|
116
|
+
|
117
|
+
expect(@general_failure).to eq([])
|
118
|
+
res = @klass.check
|
119
|
+
expect(res[0]).to eq(nil)
|
120
|
+
expect(res[1]).to eq(nil)
|
121
|
+
expect(res[2]).to eq('hello')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|