mt-libuv 4.1.0
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/.gitignore +22 -0
- data/.gitmodules +6 -0
- data/.rspec +1 -0
- data/.travis.yml +24 -0
- data/Gemfile +9 -0
- data/LICENSE +24 -0
- data/README.md +195 -0
- data/Rakefile +31 -0
- data/ext/README.md +6 -0
- data/ext/Rakefile +28 -0
- data/lib/mt-libuv/async.rb +51 -0
- data/lib/mt-libuv/check.rb +59 -0
- data/lib/mt-libuv/coroutines.rb +79 -0
- data/lib/mt-libuv/dns.rb +98 -0
- data/lib/mt-libuv/error.rb +88 -0
- data/lib/mt-libuv/ext/ext.rb +322 -0
- data/lib/mt-libuv/ext/platform/darwin_x64.rb +61 -0
- data/lib/mt-libuv/ext/platform/unix.rb +69 -0
- data/lib/mt-libuv/ext/platform/windows.rb +83 -0
- data/lib/mt-libuv/ext/tasks/mac.rb +24 -0
- data/lib/mt-libuv/ext/tasks/unix.rb +42 -0
- data/lib/mt-libuv/ext/tasks/win.rb +29 -0
- data/lib/mt-libuv/ext/tasks.rb +27 -0
- data/lib/mt-libuv/ext/types.rb +253 -0
- data/lib/mt-libuv/fiber_pool.rb +83 -0
- data/lib/mt-libuv/file.rb +309 -0
- data/lib/mt-libuv/filesystem.rb +263 -0
- data/lib/mt-libuv/fs_event.rb +37 -0
- data/lib/mt-libuv/handle.rb +108 -0
- data/lib/mt-libuv/idle.rb +59 -0
- data/lib/mt-libuv/mixins/accessors.rb +41 -0
- data/lib/mt-libuv/mixins/assertions.rb +25 -0
- data/lib/mt-libuv/mixins/fs_checks.rb +96 -0
- data/lib/mt-libuv/mixins/listener.rb +69 -0
- data/lib/mt-libuv/mixins/net.rb +42 -0
- data/lib/mt-libuv/mixins/resource.rb +30 -0
- data/lib/mt-libuv/mixins/stream.rb +276 -0
- data/lib/mt-libuv/pipe.rb +217 -0
- data/lib/mt-libuv/prepare.rb +59 -0
- data/lib/mt-libuv/q.rb +475 -0
- data/lib/mt-libuv/reactor.rb +567 -0
- data/lib/mt-libuv/signal.rb +62 -0
- data/lib/mt-libuv/spawn.rb +113 -0
- data/lib/mt-libuv/tcp.rb +465 -0
- data/lib/mt-libuv/timer.rb +107 -0
- data/lib/mt-libuv/tty.rb +42 -0
- data/lib/mt-libuv/udp.rb +302 -0
- data/lib/mt-libuv/version.rb +5 -0
- data/lib/mt-libuv/work.rb +86 -0
- data/lib/mt-libuv.rb +80 -0
- data/mt-libuv.gemspec +62 -0
- data/spec/async_spec.rb +67 -0
- data/spec/coroutines_spec.rb +121 -0
- data/spec/cpu_spec.rb +10 -0
- data/spec/defer_spec.rb +906 -0
- data/spec/dns_spec.rb +110 -0
- data/spec/dsl_spec.rb +43 -0
- data/spec/filesystem_spec.rb +270 -0
- data/spec/idle_spec.rb +44 -0
- data/spec/pipe_spec.rb +151 -0
- data/spec/spawn_spec.rb +119 -0
- data/spec/tcp_spec.rb +272 -0
- data/spec/test.sh +4 -0
- data/spec/test_fail.sh +3 -0
- data/spec/test_read.sh +3 -0
- data/spec/timer_spec.rb +14 -0
- data/spec/udp_spec.rb +73 -0
- data/spec/zen_spec.rb +34 -0
- metadata +196 -0
data/spec/dns_spec.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'mt-libuv'
|
2
|
+
|
3
|
+
|
4
|
+
describe MTLibuv::Dns do
|
5
|
+
before :each do
|
6
|
+
@log = []
|
7
|
+
@general_failure = []
|
8
|
+
|
9
|
+
@reactor = MTLibuv::Reactor.default
|
10
|
+
@reactor.notifier do |error, context|
|
11
|
+
begin
|
12
|
+
puts "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n")}\n"
|
13
|
+
rescue Exception
|
14
|
+
puts 'error in logger'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@timeout = @reactor.timer do
|
18
|
+
@reactor.stop
|
19
|
+
@general_failure << "test timed out"
|
20
|
+
end
|
21
|
+
@timeout.start(5000)
|
22
|
+
|
23
|
+
@reactor.all(@server, @client, @timeout).catch do |reason|
|
24
|
+
@general_failure << reason.inspect
|
25
|
+
puts "Failed with: #{reason.message}\n#{reason.backtrace.join("\n")}\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
after :each do
|
30
|
+
@reactor.notifier
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should resolve localhost using IP4", :network => true do
|
34
|
+
@reactor.run { |reactor|
|
35
|
+
@reactor.lookup('localhost', wait: false).then proc { |addrinfo|
|
36
|
+
@result = addrinfo[0][0]
|
37
|
+
@timeout.close
|
38
|
+
@reactor.stop
|
39
|
+
}, proc { |err|
|
40
|
+
@general_failure << err
|
41
|
+
@timeout.close
|
42
|
+
@reactor.stop
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
expect(@general_failure).to eq([])
|
47
|
+
expect(@result).to eq('127.0.0.1')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should resolve localhost using IP6", :network => true do
|
51
|
+
@reactor.run { |reactor|
|
52
|
+
@reactor.lookup('localhost', :IPv6, wait: false).then proc { |addrinfo|
|
53
|
+
@result = addrinfo[0][0]
|
54
|
+
@timeout.close
|
55
|
+
@reactor.stop
|
56
|
+
}, proc { |err|
|
57
|
+
@general_failure << err
|
58
|
+
@timeout.close
|
59
|
+
@reactor.stop
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
expect(@general_failure).to eq([])
|
64
|
+
expect(@result).to eq('::1')
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should resolve reactor back" do
|
68
|
+
@reactor.run { |reactor|
|
69
|
+
@reactor.lookup('127.0.0.1', wait: false).then proc { |addrinfo|
|
70
|
+
@result = addrinfo[0][0]
|
71
|
+
@timeout.close
|
72
|
+
@reactor.stop
|
73
|
+
}, proc { |err|
|
74
|
+
@general_failure << err
|
75
|
+
@timeout.close
|
76
|
+
@reactor.stop
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
expect(@general_failure).to eq([])
|
81
|
+
expect(@result).to eq('127.0.0.1')
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should work with coroutines" do
|
85
|
+
@reactor.run { |reactor|
|
86
|
+
begin
|
87
|
+
addrinfo = @reactor.lookup('127.0.0.1')
|
88
|
+
@result = [addrinfo[0][0]]
|
89
|
+
|
90
|
+
begin
|
91
|
+
addrinfo = @reactor.lookup('test.fail.blah').results
|
92
|
+
@general_failure << "should have failed"
|
93
|
+
@timeout.close
|
94
|
+
@reactor.stop
|
95
|
+
rescue => err
|
96
|
+
@result << err.class
|
97
|
+
@timeout.close
|
98
|
+
@reactor.stop
|
99
|
+
end
|
100
|
+
rescue => err
|
101
|
+
@general_failure << err
|
102
|
+
@timeout.close
|
103
|
+
@reactor.stop
|
104
|
+
end
|
105
|
+
}
|
106
|
+
|
107
|
+
expect(@general_failure).to eq([])
|
108
|
+
expect(@result).to eq(['127.0.0.1', MTLibuv::Error::EAI_NONAME])
|
109
|
+
end
|
110
|
+
end
|
data/spec/dsl_spec.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'mt-libuv'
|
2
|
+
|
3
|
+
describe MTLibuv::Accessors do
|
4
|
+
describe 'basic usage' do
|
5
|
+
it 'should work seamlessly with the default thread' do
|
6
|
+
count = 0
|
7
|
+
reactor do |reactor|
|
8
|
+
reactor.timer {
|
9
|
+
count += 1
|
10
|
+
reactor.stop if count == 3
|
11
|
+
}.start(50, 10)
|
12
|
+
end
|
13
|
+
|
14
|
+
expect(count).to eq(3)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'work simply with new threads' do
|
18
|
+
count = 0
|
19
|
+
sig = ConditionVariable.new
|
20
|
+
mutex = Mutex.new
|
21
|
+
mutex.synchronize {
|
22
|
+
|
23
|
+
# This will run on a new thread
|
24
|
+
MTLibuv::Reactor.new do |reactor|
|
25
|
+
reactor.timer {
|
26
|
+
count += 1
|
27
|
+
|
28
|
+
if count == 3
|
29
|
+
reactor.stop
|
30
|
+
mutex.synchronize {
|
31
|
+
sig.signal
|
32
|
+
}
|
33
|
+
end
|
34
|
+
}.start(50, 10)
|
35
|
+
end
|
36
|
+
|
37
|
+
sig.wait(mutex)
|
38
|
+
}
|
39
|
+
|
40
|
+
expect(count).to eq(3)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'mt-libuv'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
|
5
|
+
describe MTLibuv::Filesystem do
|
6
|
+
before :each do
|
7
|
+
@log = []
|
8
|
+
@general_failure = []
|
9
|
+
|
10
|
+
@reactor = MTLibuv::Reactor.default
|
11
|
+
@filesystem = @reactor.filesystem
|
12
|
+
@timeout = @reactor.timer do
|
13
|
+
@reactor.stop
|
14
|
+
@general_failure << "test timed out"
|
15
|
+
end
|
16
|
+
@timeout.start(4000)
|
17
|
+
|
18
|
+
@reactor.notifier do |error, context|
|
19
|
+
begin
|
20
|
+
@general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
|
21
|
+
rescue Exception => e
|
22
|
+
@general_failure << "error in logger #{e.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
@thefile = "test-file.txt"
|
27
|
+
|
28
|
+
@reactor.all(@filesystem, @timeout).catch do |reason|
|
29
|
+
@general_failure << reason.inspect
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'directory navigation' do
|
34
|
+
it "should list the contents of a folder" do
|
35
|
+
@reactor.run { |reactor|
|
36
|
+
currentDir = Dir.pwd
|
37
|
+
listing = @filesystem.readdir(currentDir, wait: false)
|
38
|
+
listing.then do |result|
|
39
|
+
@log = result
|
40
|
+
end
|
41
|
+
listing.catch do |error|
|
42
|
+
@general_failure << error
|
43
|
+
end
|
44
|
+
listing.finally do
|
45
|
+
@timeout.close
|
46
|
+
@reactor.stop
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
expect(@general_failure).to eq([])
|
51
|
+
expect((@log.length > 0)).to eq(true)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'file manipulation' do
|
56
|
+
it "should create and write to a file" do
|
57
|
+
@reactor.run { |reactor|
|
58
|
+
file = @reactor.file(@thefile, File::CREAT|File::WRONLY)
|
59
|
+
begin
|
60
|
+
file.write('write some data to a file')
|
61
|
+
file.chmod(777)
|
62
|
+
@timeout.close
|
63
|
+
@reactor.stop
|
64
|
+
@log = :success
|
65
|
+
rescue => error
|
66
|
+
@general_failure << error
|
67
|
+
@timeout.close
|
68
|
+
@reactor.stop
|
69
|
+
ensure
|
70
|
+
file.close
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
74
|
+
expect(@general_failure).to eq([])
|
75
|
+
expect(@log).to eq(:success)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return stats on the file" do
|
79
|
+
@reactor.run { |reactor|
|
80
|
+
file = @reactor.file(@thefile, File::RDONLY)
|
81
|
+
begin
|
82
|
+
stats = file.stat
|
83
|
+
@timeout.close
|
84
|
+
@reactor.stop
|
85
|
+
@log << stats[:st_mtim][:tv_sec]
|
86
|
+
rescue => error
|
87
|
+
@general_failure << error
|
88
|
+
@timeout.close
|
89
|
+
@reactor.stop
|
90
|
+
ensure
|
91
|
+
file.close
|
92
|
+
end
|
93
|
+
}
|
94
|
+
|
95
|
+
expect(@general_failure).to eq([])
|
96
|
+
expect(@log[0]).to be_kind_of(Integer)
|
97
|
+
expect(@log.length).to eql(1)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should read from a file" do
|
101
|
+
@reactor.run { |reactor|
|
102
|
+
file = @reactor.file(@thefile, File::RDONLY)
|
103
|
+
begin
|
104
|
+
result = file.read(100)
|
105
|
+
@timeout.close
|
106
|
+
@reactor.stop
|
107
|
+
@log = result
|
108
|
+
rescue => error
|
109
|
+
@general_failure << error
|
110
|
+
@timeout.close
|
111
|
+
file.close
|
112
|
+
@reactor.stop
|
113
|
+
ensure
|
114
|
+
file.close
|
115
|
+
end
|
116
|
+
}
|
117
|
+
|
118
|
+
expect(@general_failure).to eq([])
|
119
|
+
expect(@log).to eq('write some data to a file')
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should delete a file" do
|
123
|
+
@reactor.run { |reactor|
|
124
|
+
op = @reactor.filesystem.unlink(@thefile, wait: false)
|
125
|
+
op.then do
|
126
|
+
@timeout.close
|
127
|
+
@reactor.stop
|
128
|
+
@log = :success
|
129
|
+
end
|
130
|
+
op.catch do |error|
|
131
|
+
@general_failure << error
|
132
|
+
@timeout.close
|
133
|
+
@reactor.stop
|
134
|
+
end
|
135
|
+
}
|
136
|
+
|
137
|
+
expect(@general_failure).to eq([])
|
138
|
+
expect(@log).to eq(:success)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'file streaming' do
|
143
|
+
it "should send a file over a stream", :network => true do
|
144
|
+
@reactor.run { |reactor|
|
145
|
+
@server = @reactor.tcp
|
146
|
+
@client = @reactor.tcp
|
147
|
+
|
148
|
+
@server.bind('127.0.0.1', 34570) do |client|
|
149
|
+
client.progress do |data|
|
150
|
+
file = @reactor.file('.rspec', File::RDONLY) do
|
151
|
+
file.send_file(client, wait: false).then(proc {
|
152
|
+
file.close
|
153
|
+
client.close
|
154
|
+
}, proc { |error|
|
155
|
+
@general_failure << error
|
156
|
+
})
|
157
|
+
end
|
158
|
+
file.catch do |error|
|
159
|
+
@general_failure << error.inspect
|
160
|
+
file.close
|
161
|
+
client.close
|
162
|
+
end
|
163
|
+
end
|
164
|
+
client.start_read
|
165
|
+
client.finally do
|
166
|
+
@timeout.close
|
167
|
+
@server.close
|
168
|
+
@reactor.stop
|
169
|
+
end
|
170
|
+
end
|
171
|
+
# catch errors
|
172
|
+
@server.catch do |reason|
|
173
|
+
@general_failure << reason.inspect
|
174
|
+
@reactor.stop
|
175
|
+
end
|
176
|
+
# start listening
|
177
|
+
@server.listen(5)
|
178
|
+
|
179
|
+
|
180
|
+
# connect client to server
|
181
|
+
@client.connect('127.0.0.1', 34570) do |client|
|
182
|
+
client.progress do |data|
|
183
|
+
@log << data
|
184
|
+
end
|
185
|
+
|
186
|
+
@client.start_read
|
187
|
+
@client.write('send file')
|
188
|
+
end
|
189
|
+
# catch errors
|
190
|
+
@client.catch do |reason|
|
191
|
+
@general_failure << reason.inspect
|
192
|
+
@server.close
|
193
|
+
@reactor.stop
|
194
|
+
end
|
195
|
+
}
|
196
|
+
|
197
|
+
expect(@general_failure).to eq([])
|
198
|
+
# Windows GIT adds the carriage return
|
199
|
+
if FFI::Platform.windows?
|
200
|
+
expect(@log).to eq(["--format progress\r\n"])
|
201
|
+
else
|
202
|
+
expect(@log).to eq(["--format progress\n"])
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should send a file as a HTTP chunked response", :network => true do
|
207
|
+
@reactor.run { |reactor|
|
208
|
+
@server = @reactor.tcp
|
209
|
+
@client = @reactor.tcp
|
210
|
+
|
211
|
+
@server.bind('127.0.0.1', 34568) do |client|
|
212
|
+
client.progress do |data|
|
213
|
+
file = @reactor.file('.rspec', File::RDONLY) do
|
214
|
+
file.send_file(client, using: :http, wait: false).then(proc {
|
215
|
+
file.close
|
216
|
+
client.close
|
217
|
+
}, proc { |error|
|
218
|
+
@general_failure << error
|
219
|
+
})
|
220
|
+
end
|
221
|
+
file.catch do |error|
|
222
|
+
@general_failure << error.inspect
|
223
|
+
file.close
|
224
|
+
client.close
|
225
|
+
end
|
226
|
+
end
|
227
|
+
client.start_read
|
228
|
+
client.finally do
|
229
|
+
@timeout.close
|
230
|
+
@server.close
|
231
|
+
@reactor.stop
|
232
|
+
end
|
233
|
+
end
|
234
|
+
# catch errors
|
235
|
+
@server.catch do |reason|
|
236
|
+
@general_failure << reason.inspect
|
237
|
+
@reactor.stop
|
238
|
+
end
|
239
|
+
# start listening
|
240
|
+
@server.listen(5)
|
241
|
+
|
242
|
+
|
243
|
+
# connect client to server
|
244
|
+
@client.connect('127.0.0.1', 34568) do |client|
|
245
|
+
client.progress do |data|
|
246
|
+
@log << data
|
247
|
+
end
|
248
|
+
|
249
|
+
@client.start_read
|
250
|
+
@client.write('send file')
|
251
|
+
end
|
252
|
+
# catch errors
|
253
|
+
@client.catch do |reason|
|
254
|
+
@general_failure << reason.inspect
|
255
|
+
@server.close
|
256
|
+
@reactor.stop
|
257
|
+
end
|
258
|
+
}
|
259
|
+
|
260
|
+
expect(@general_failure).to eq([])
|
261
|
+
|
262
|
+
# Windows GIT adds the carriage return
|
263
|
+
if FFI::Platform.windows?
|
264
|
+
expect(@log.join('')).to eq("13\r\n--format progress\r\n\r\n0\r\n\r\n")
|
265
|
+
else
|
266
|
+
expect(@log.join('')).to eq("12\r\n--format progress\n\r\n0\r\n\r\n")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
data/spec/idle_spec.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'mt-libuv'
|
2
|
+
|
3
|
+
|
4
|
+
describe MTLibuv::Idle do
|
5
|
+
before :each do
|
6
|
+
@log = []
|
7
|
+
@general_failure = []
|
8
|
+
|
9
|
+
@reactor = MTLibuv::Reactor.default
|
10
|
+
@reactor.notifier do |error, context|
|
11
|
+
begin
|
12
|
+
@general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
|
13
|
+
rescue Exception => e
|
14
|
+
@general_failure << "error in logger #{e.inspect}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@timeout = @reactor.timer {
|
18
|
+
@reactor.stop
|
19
|
+
@general_failure << "test timed out"
|
20
|
+
}.start(5000)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should increase the idle count when there is nothing to process" do
|
24
|
+
@reactor.run { |reactor|
|
25
|
+
@idle_calls = 0
|
26
|
+
|
27
|
+
idle = @reactor.idle { |e|
|
28
|
+
@idle_calls += 1
|
29
|
+
}.start
|
30
|
+
|
31
|
+
stopper = @reactor.timer {
|
32
|
+
idle.stop.close
|
33
|
+
stopper.close
|
34
|
+
@timeout.close
|
35
|
+
@reactor.stop
|
36
|
+
}.start(1000)
|
37
|
+
|
38
|
+
expect(@reactor.active_handles).to be >= 4
|
39
|
+
}
|
40
|
+
|
41
|
+
expect(@general_failure).to eq([])
|
42
|
+
expect((@idle_calls > 0)).to eq(true)
|
43
|
+
end
|
44
|
+
end
|
data/spec/pipe_spec.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'mt-libuv'
|
2
|
+
|
3
|
+
|
4
|
+
describe MTLibuv::Pipe do
|
5
|
+
before :each do
|
6
|
+
@log = []
|
7
|
+
@general_failure = []
|
8
|
+
|
9
|
+
@reactor = MTLibuv::Reactor.new
|
10
|
+
@server = @reactor.pipe
|
11
|
+
@client = @reactor.pipe
|
12
|
+
@timeout = @reactor.timer do
|
13
|
+
@reactor.stop
|
14
|
+
@general_failure << "test timed out"
|
15
|
+
end
|
16
|
+
@timeout.start(5000)
|
17
|
+
|
18
|
+
@pipefile = "/tmp/test-pipes.pipe"
|
19
|
+
|
20
|
+
@reactor.all(@server, @client, @timeout).catch do |reason|
|
21
|
+
@general_failure << reason.inspect
|
22
|
+
@general_failure << "Failed with: #{reason.message}\n#{reason.backtrace}\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
@reactor.notifier do |error, context|
|
26
|
+
begin
|
27
|
+
@general_failure << "Log called: #{context}\n#{error.message}\n#{error.backtrace.join("\n") if error.backtrace}\n"
|
28
|
+
rescue Exception => e
|
29
|
+
@general_failure << "error in logger #{e.inspect}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
File.unlink(@pipefile)
|
35
|
+
rescue
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
after :each do
|
40
|
+
begin
|
41
|
+
File.unlink(@pipefile)
|
42
|
+
rescue
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'bidirectional inter process communication' do
|
47
|
+
|
48
|
+
it "should send a ping and return a pong" do
|
49
|
+
@reactor.run { |reactor|
|
50
|
+
@server.bind(@pipefile) do |client|
|
51
|
+
client.progress do |data|
|
52
|
+
@log << data
|
53
|
+
client.write('pong')
|
54
|
+
end
|
55
|
+
client.start_read
|
56
|
+
end
|
57
|
+
|
58
|
+
# catch server errors
|
59
|
+
@server.catch do |reason|
|
60
|
+
@general_failure << reason.inspect
|
61
|
+
@reactor.stop
|
62
|
+
|
63
|
+
@general_failure << "Failed with: #{reason.message}\n#{reason.backtrace}\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
# start listening
|
67
|
+
@server.listen(1024)
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
# connect client to server
|
72
|
+
@client.connect(@pipefile) do |client|
|
73
|
+
@client.progress do |data|
|
74
|
+
@log << data
|
75
|
+
|
76
|
+
@client.close
|
77
|
+
end
|
78
|
+
|
79
|
+
@client.start_read
|
80
|
+
@client.write('ping')
|
81
|
+
end
|
82
|
+
|
83
|
+
@client.catch do |reason|
|
84
|
+
@general_failure << reason.inspect
|
85
|
+
@reactor.stop
|
86
|
+
|
87
|
+
@general_failure << "Failed with: #{reason.message}\n#{reason.backtrace}\n"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Stop the reactor once the client handle is closed
|
91
|
+
@client.finally do
|
92
|
+
@server.close
|
93
|
+
@reactor.stop
|
94
|
+
end
|
95
|
+
}
|
96
|
+
|
97
|
+
expect(@general_failure).to eq([])
|
98
|
+
expect(@log).to eq(['ping', 'pong'])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# This test won't pass on windows as pipes don't work like this on windows
|
103
|
+
describe 'unidirectional pipeline', :unix_only => true do
|
104
|
+
before :each do
|
105
|
+
system "/usr/bin/mkfifo", @pipefile
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should send work to a consumer" do
|
109
|
+
@reactor.run { |reactor|
|
110
|
+
heartbeat = @reactor.timer
|
111
|
+
@file1 = @reactor.file(@pipefile, File::RDWR|File::NONBLOCK) do
|
112
|
+
@server.open(@file1.fileno) do |server|
|
113
|
+
heartbeat.progress do
|
114
|
+
@server.write('workload').catch do |err|
|
115
|
+
@general_failure << err
|
116
|
+
end
|
117
|
+
end
|
118
|
+
heartbeat.start(0, 200)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
@file1.catch do |e|
|
122
|
+
@general_failure << "Log called: #{e.inspect} - #{e.message}\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
@file2 = @reactor.file(@pipefile, File::RDWR|File::NONBLOCK) do
|
126
|
+
# connect client to server
|
127
|
+
@client.open(@file2.fileno) do |consumer|
|
128
|
+
consumer.progress do |data|
|
129
|
+
@log = data
|
130
|
+
end
|
131
|
+
|
132
|
+
consumer.start_read
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
timeout = @reactor.timer do
|
138
|
+
@server.close
|
139
|
+
@client.close
|
140
|
+
timeout.close
|
141
|
+
heartbeat.close
|
142
|
+
@reactor.stop
|
143
|
+
end
|
144
|
+
timeout.start(1000)
|
145
|
+
}
|
146
|
+
|
147
|
+
expect(@general_failure).to eq([])
|
148
|
+
expect(@log).to eq('workload')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|