sanford 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/bench/report.rb +2 -0
- data/bench/report.txt +28 -37
- data/lib/sanford/connection_handler.rb +10 -3
- data/lib/sanford/error_handler.rb +4 -4
- data/lib/sanford/io_pipe.rb +40 -0
- data/lib/sanford/process.rb +108 -28
- data/lib/sanford/router.rb +5 -0
- data/lib/sanford/server.rb +133 -95
- data/lib/sanford/server_data.rb +27 -28
- data/lib/sanford/template_source.rb +2 -2
- data/lib/sanford/version.rb +1 -1
- data/sanford.gemspec +4 -5
- data/test/helper.rb +11 -0
- data/test/support/app_server.rb +6 -3
- data/test/support/factory.rb +7 -0
- data/test/system/server_tests.rb +21 -3
- data/test/system/service_handler_tests.rb +4 -4
- data/test/unit/cli_tests.rb +2 -2
- data/test/unit/connection_handler_tests.rb +107 -47
- data/test/unit/error_handler_tests.rb +11 -11
- data/test/unit/io_pipe_tests.rb +84 -0
- data/test/unit/process_tests.rb +266 -131
- data/test/unit/router_tests.rb +25 -7
- data/test/unit/server_data_tests.rb +68 -46
- data/test/unit/server_tests.rb +197 -240
- data/test/unit/template_engine_tests.rb +1 -1
- data/test/unit/template_source_tests.rb +6 -0
- data/test/unit/test_runner_tests.rb +0 -19
- metadata +12 -19
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'sanford/io_pipe'
|
3
|
+
|
4
|
+
require 'thread'
|
5
|
+
|
6
|
+
class Sanford::IOPipe
|
7
|
+
|
8
|
+
class UnitTests < Assert::Context
|
9
|
+
desc "Sanford::IOPipe"
|
10
|
+
setup do
|
11
|
+
# mimic how IO.select responds
|
12
|
+
@io_select_response = Factory.boolean ? [[NULL], [], []] : nil
|
13
|
+
@io_select_called_with = nil
|
14
|
+
Assert.stub(IO, :select) do |*args|
|
15
|
+
@io_select_called_with = args
|
16
|
+
@io_select_response
|
17
|
+
end
|
18
|
+
|
19
|
+
@io_pipe = Sanford::IOPipe.new
|
20
|
+
end
|
21
|
+
subject{ @io_pipe }
|
22
|
+
|
23
|
+
should have_readers :reader, :writer
|
24
|
+
should have_imeths :setup, :teardown
|
25
|
+
should have_imeths :read, :write, :wait
|
26
|
+
|
27
|
+
should "default its reader and writer" do
|
28
|
+
assert_same NULL, subject.reader
|
29
|
+
assert_same NULL, subject.writer
|
30
|
+
end
|
31
|
+
|
32
|
+
should "change its reader/writer to an IO pipe when setup" do
|
33
|
+
subject.setup
|
34
|
+
assert_not_same NULL, subject.reader
|
35
|
+
assert_not_same NULL, subject.writer
|
36
|
+
assert_instance_of IO, subject.reader
|
37
|
+
assert_instance_of IO, subject.writer
|
38
|
+
end
|
39
|
+
|
40
|
+
should "close its reader/writer and set them to defaults when torn down" do
|
41
|
+
subject.setup
|
42
|
+
reader = subject.reader
|
43
|
+
writer = subject.writer
|
44
|
+
|
45
|
+
subject.teardown
|
46
|
+
assert_true reader.closed?
|
47
|
+
assert_true writer.closed?
|
48
|
+
assert_same NULL, subject.reader
|
49
|
+
assert_same NULL, subject.writer
|
50
|
+
end
|
51
|
+
|
52
|
+
should "be able to read/write values" do
|
53
|
+
subject.setup
|
54
|
+
|
55
|
+
value = Factory.string(NUMBER_OF_BYTES)
|
56
|
+
subject.write(value)
|
57
|
+
assert_equal value, subject.read
|
58
|
+
end
|
59
|
+
|
60
|
+
should "only read/write a fixed number of bytes" do
|
61
|
+
subject.setup
|
62
|
+
|
63
|
+
value = Factory.string
|
64
|
+
subject.write(value)
|
65
|
+
assert_equal value[0, NUMBER_OF_BYTES], subject.read
|
66
|
+
end
|
67
|
+
|
68
|
+
should "be able to wait until there is something to read" do
|
69
|
+
subject.setup
|
70
|
+
|
71
|
+
result = subject.wait
|
72
|
+
exp = [[subject.reader], nil, nil, nil]
|
73
|
+
assert_equal exp, @io_select_called_with
|
74
|
+
assert_equal !!@io_select_response, result
|
75
|
+
|
76
|
+
timeout = Factory.integer
|
77
|
+
subject.wait(timeout)
|
78
|
+
exp = [[subject.reader], nil, nil, timeout]
|
79
|
+
assert_equal exp, @io_select_called_with
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/test/unit/process_tests.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'assert'
|
2
2
|
require 'sanford/process'
|
3
3
|
|
4
|
+
require 'sanford/io_pipe'
|
4
5
|
require 'sanford/server'
|
5
6
|
require 'test/support/pid_file_spy'
|
6
7
|
|
@@ -9,22 +10,37 @@ class Sanford::Process
|
|
9
10
|
class UnitTests < Assert::Context
|
10
11
|
desc "Sanford::Process"
|
11
12
|
setup do
|
13
|
+
@current_env_server_fd = ENV['SANFORD_SERVER_FD']
|
14
|
+
@current_env_client_fds = ENV['SANFORD_CLIENT_FDS']
|
15
|
+
@current_env_skip_daemonize = ENV['SANFORD_SKIP_DAEMONIZE']
|
16
|
+
ENV.delete('SANFORD_SERVER_FD')
|
17
|
+
ENV.delete('SANFORD_CLIENT_FDS')
|
18
|
+
ENV.delete('SANFORD_SKIP_DAEMONIZE')
|
19
|
+
|
12
20
|
@process_class = Sanford::Process
|
13
21
|
end
|
22
|
+
teardown do
|
23
|
+
ENV['SANFORD_SKIP_DAEMONIZE'] = @current_env_skip_daemonize
|
24
|
+
ENV['SANFORD_CLIENT_FDS'] = @current_env_client_fds
|
25
|
+
ENV['SANFORD_SERVER_FD'] = @current_env_server_fd
|
26
|
+
end
|
14
27
|
subject{ @process_class }
|
15
28
|
|
29
|
+
should "know its wait for signals timeout" do
|
30
|
+
assert_equal 15, WAIT_FOR_SIGNALS_TIMEOUT
|
31
|
+
end
|
32
|
+
|
33
|
+
should "know its signal strings" do
|
34
|
+
assert_equal 'H', HALT
|
35
|
+
assert_equal 'S', STOP
|
36
|
+
assert_equal 'R', RESTART
|
37
|
+
end
|
38
|
+
|
16
39
|
end
|
17
40
|
|
18
41
|
class InitTests < UnitTests
|
19
42
|
desc "when init"
|
20
43
|
setup do
|
21
|
-
@current_env_server_fd = ENV['SANFORD_SERVER_FD']
|
22
|
-
@current_env_client_fds = ENV['SANFORD_CLIENT_FDS']
|
23
|
-
@current_env_skip_daemonize = ENV['SANFORD_SKIP_DAEMONIZE']
|
24
|
-
ENV.delete('SANFORD_SERVER_FD')
|
25
|
-
ENV.delete('SANFORD_CLIENT_FDS')
|
26
|
-
ENV.delete('SANFORD_SKIP_DAEMONIZE')
|
27
|
-
|
28
44
|
@server_spy = ServerSpy.new
|
29
45
|
|
30
46
|
@pid_file_spy = PIDFileSpy.new(Factory.integer)
|
@@ -37,14 +53,9 @@ class Sanford::Process
|
|
37
53
|
|
38
54
|
@process = @process_class.new(@server_spy)
|
39
55
|
end
|
40
|
-
teardown do
|
41
|
-
ENV['SANFORD_SKIP_DAEMONIZE'] = @current_env_skip_daemonize
|
42
|
-
ENV['SANFORD_CLIENT_FDS'] = @current_env_client_fds
|
43
|
-
ENV['SANFORD_SERVER_FD'] = @current_env_server_fd
|
44
|
-
end
|
45
56
|
subject{ @process }
|
46
57
|
|
47
|
-
should have_readers :server, :name, :pid_file, :restart_cmd
|
58
|
+
should have_readers :server, :name, :pid_file, :signal_io, :restart_cmd
|
48
59
|
should have_readers :server_ip, :server_port, :server_fd, :client_fds
|
49
60
|
should have_imeths :run, :daemonize?
|
50
61
|
|
@@ -52,16 +63,17 @@ class Sanford::Process
|
|
52
63
|
assert_equal @server_spy, subject.server
|
53
64
|
end
|
54
65
|
|
55
|
-
should "know its name, pid file and restart cmd" do
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
assert_equal @pid_file_spy,
|
60
|
-
|
66
|
+
should "know its name, pid file, signal io and restart cmd" do
|
67
|
+
exp = "sanford: #{@server_spy.process_label}"
|
68
|
+
assert_equal exp, subject.name
|
69
|
+
|
70
|
+
assert_equal @pid_file_spy, subject.pid_file
|
71
|
+
assert_instance_of Sanford::IOPipe, subject.signal_io
|
72
|
+
assert_equal @restart_cmd_spy, subject.restart_cmd
|
61
73
|
end
|
62
74
|
|
63
75
|
should "know its server ip, port and file descriptor" do
|
64
|
-
assert_equal @server_spy.configured_ip,
|
76
|
+
assert_equal @server_spy.configured_ip, subject.server_ip
|
65
77
|
assert_equal @server_spy.configured_port, subject.server_port
|
66
78
|
assert_nil subject.server_fd
|
67
79
|
end
|
@@ -124,28 +136,14 @@ class Sanford::Process
|
|
124
136
|
|
125
137
|
@current_process_name = $0
|
126
138
|
|
127
|
-
@
|
128
|
-
|
129
|
-
|
130
|
-
@term_signal_trap_block = block
|
131
|
-
@term_signal_trap_called = true
|
132
|
-
end
|
133
|
-
|
134
|
-
@int_signal_trap_block = nil
|
135
|
-
@int_signal_trap_called = false
|
136
|
-
Assert.stub(::Signal, :trap).with("INT") do |&block|
|
137
|
-
@int_signal_trap_block = block
|
138
|
-
@int_signal_trap_called = true
|
139
|
-
end
|
140
|
-
|
141
|
-
@usr2_signal_trap_block = nil
|
142
|
-
@usr2_signal_trap_called = false
|
143
|
-
Assert.stub(::Signal, :trap).with("USR2") do |&block|
|
144
|
-
@usr2_signal_trap_block = block
|
145
|
-
@usr2_signal_trap_called = true
|
139
|
+
@signal_traps = []
|
140
|
+
Assert.stub(::Signal, :trap) do |signal, &block|
|
141
|
+
@signal_traps << SignalTrap.new(signal, block)
|
146
142
|
end
|
147
143
|
end
|
148
144
|
teardown do
|
145
|
+
@process.signal_io.write(HALT)
|
146
|
+
@thread.join if @thread
|
149
147
|
$0 = @current_process_name
|
150
148
|
end
|
151
149
|
|
@@ -154,58 +152,74 @@ class Sanford::Process
|
|
154
152
|
class RunTests < RunSetupTests
|
155
153
|
desc "and run"
|
156
154
|
setup do
|
157
|
-
@
|
155
|
+
@wait_timeout = nil
|
156
|
+
Assert.stub(@process.signal_io, :wait) do |timeout|
|
157
|
+
@wait_timeout = timeout
|
158
|
+
sleep 2*JOIN_SECONDS
|
159
|
+
false
|
160
|
+
end
|
161
|
+
|
162
|
+
@thread = Thread.new{ @process.run }
|
163
|
+
@thread.join(JOIN_SECONDS)
|
164
|
+
end
|
165
|
+
teardown do
|
166
|
+
# manually unstub or the process thread will hang forever
|
167
|
+
Assert.unstub(@process.signal_io, :wait)
|
158
168
|
end
|
159
169
|
|
160
|
-
should "not
|
170
|
+
should "not daemonize the process" do
|
161
171
|
assert_false @daemonize_called
|
162
172
|
end
|
163
173
|
|
164
|
-
should "
|
174
|
+
should "start the server listening" do
|
165
175
|
assert_true @server_spy.listen_called
|
166
|
-
|
167
|
-
assert_equal
|
176
|
+
exp = [subject.server_ip, subject.server_port]
|
177
|
+
assert_equal exp, @server_spy.listen_args
|
168
178
|
end
|
169
179
|
|
170
|
-
should "
|
180
|
+
should "set the process name" do
|
171
181
|
assert_equal $0, subject.name
|
172
182
|
end
|
173
183
|
|
174
|
-
should "
|
184
|
+
should "write its PID file" do
|
175
185
|
assert_true @pid_file_spy.write_called
|
176
186
|
end
|
177
187
|
|
178
|
-
should "
|
179
|
-
|
180
|
-
|
181
|
-
@term_signal_trap_block.call
|
182
|
-
assert_true @server_spy.stop_called
|
183
|
-
|
184
|
-
assert_true @int_signal_trap_called
|
185
|
-
assert_false @server_spy.halt_called
|
186
|
-
@int_signal_trap_block.call
|
187
|
-
assert_true @server_spy.halt_called
|
188
|
-
|
189
|
-
assert_true @usr2_signal_trap_called
|
190
|
-
assert_false @server_spy.pause_called
|
191
|
-
@usr2_signal_trap_block.call
|
192
|
-
assert_true @server_spy.pause_called
|
188
|
+
should "trap signals" do
|
189
|
+
assert_equal 3, @signal_traps.size
|
190
|
+
assert_equal ['INT', 'TERM', 'USR2'], @signal_traps.map(&:signal)
|
193
191
|
end
|
194
192
|
|
195
|
-
should "
|
193
|
+
should "start the server" do
|
196
194
|
assert_true @server_spy.start_called
|
197
195
|
end
|
198
196
|
|
199
|
-
should "
|
200
|
-
|
197
|
+
should "sleep its thread waiting for signals" do
|
198
|
+
assert_equal WAIT_FOR_SIGNALS_TIMEOUT, @wait_timeout
|
199
|
+
assert_equal 'sleep', @thread.status
|
201
200
|
end
|
202
201
|
|
203
202
|
should "not run the restart cmd" do
|
204
|
-
|
203
|
+
assert_nil @restart_cmd_spy.run_called_for
|
205
204
|
end
|
206
205
|
|
207
|
-
|
208
|
-
|
206
|
+
end
|
207
|
+
|
208
|
+
class SignalTrapsTests < RunSetupTests
|
209
|
+
desc "signal traps"
|
210
|
+
setup do
|
211
|
+
# setup the io pipe so we can see whats written to it
|
212
|
+
@process.signal_io.setup
|
213
|
+
end
|
214
|
+
teardown do
|
215
|
+
@process.signal_io.teardown
|
216
|
+
end
|
217
|
+
|
218
|
+
should "write the signals to processes signal IO" do
|
219
|
+
@signal_traps.each do |signal_trap|
|
220
|
+
signal_trap.block.call
|
221
|
+
assert_equal signal_trap.signal, subject.signal_io.read
|
222
|
+
end
|
209
223
|
end
|
210
224
|
|
211
225
|
end
|
@@ -214,7 +228,8 @@ class Sanford::Process
|
|
214
228
|
desc "that should daemonize is run"
|
215
229
|
setup do
|
216
230
|
Assert.stub(@process, :daemonize?){ true }
|
217
|
-
@process.run
|
231
|
+
@thread = Thread.new{ @process.run }
|
232
|
+
@thread.join(JOIN_SECONDS)
|
218
233
|
end
|
219
234
|
|
220
235
|
should "have daemonized the process" do
|
@@ -228,13 +243,14 @@ class Sanford::Process
|
|
228
243
|
setup do
|
229
244
|
ENV['SANFORD_SERVER_FD'] = Factory.integer.to_s
|
230
245
|
@process = @process_class.new(@server_spy)
|
231
|
-
@process.run
|
246
|
+
@thread = Thread.new{ @process.run }
|
247
|
+
@thread.join(JOIN_SECONDS)
|
232
248
|
end
|
233
249
|
|
234
250
|
should "have used the file descriptor when listening" do
|
235
251
|
assert_true @server_spy.listen_called
|
236
|
-
|
237
|
-
assert_equal
|
252
|
+
exp = [@process.server_fd]
|
253
|
+
assert_equal exp, @server_spy.listen_args
|
238
254
|
end
|
239
255
|
|
240
256
|
end
|
@@ -245,7 +261,8 @@ class Sanford::Process
|
|
245
261
|
@client_fds = [ Factory.integer, Factory.integer ]
|
246
262
|
ENV['SANFORD_CLIENT_FDS'] = @client_fds.join(',')
|
247
263
|
@process = @process_class.new(@server_spy)
|
248
|
-
@process.run
|
264
|
+
@thread = Thread.new{ @process.run }
|
265
|
+
@thread.join(JOIN_SECONDS)
|
249
266
|
end
|
250
267
|
|
251
268
|
should "have used the client file descriptors when starting" do
|
@@ -255,25 +272,120 @@ class Sanford::Process
|
|
255
272
|
|
256
273
|
end
|
257
274
|
|
258
|
-
class
|
259
|
-
desc "
|
275
|
+
class RunAndHaltTests < RunSetupTests
|
276
|
+
desc "and run with a halt signal"
|
260
277
|
setup do
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
278
|
+
@thread = Thread.new{ @process.run }
|
279
|
+
@thread.join(JOIN_SECONDS)
|
280
|
+
@process.signal_io.write(HALT)
|
281
|
+
@thread.join(JOIN_SECONDS)
|
282
|
+
end
|
283
|
+
|
284
|
+
should "halt its server" do
|
285
|
+
assert_true @server_spy.halt_called
|
286
|
+
assert_equal [true], @server_spy.halt_args
|
287
|
+
end
|
288
|
+
|
289
|
+
should "not set the env var to skip daemonize" do
|
290
|
+
assert_equal @current_env_skip_daemonize, ENV['SANFORD_SKIP_DAEMONIZE']
|
291
|
+
end
|
292
|
+
|
293
|
+
should "not run the restart cmd" do
|
294
|
+
assert_nil @restart_cmd_spy.run_called_for
|
295
|
+
end
|
296
|
+
|
297
|
+
should "remove the PID file" do
|
298
|
+
assert_true @pid_file_spy.remove_called
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
class RunAndStopTests < RunSetupTests
|
304
|
+
desc "and run with a stop signal"
|
305
|
+
setup do
|
306
|
+
@thread = Thread.new{ @process.run }
|
307
|
+
@thread.join(JOIN_SECONDS)
|
308
|
+
@process.signal_io.write(STOP)
|
309
|
+
@thread.join(JOIN_SECONDS)
|
310
|
+
end
|
311
|
+
|
312
|
+
should "stop its server" do
|
313
|
+
assert_true @server_spy.stop_called
|
314
|
+
assert_equal [true], @server_spy.stop_args
|
315
|
+
end
|
316
|
+
|
317
|
+
should "not set the env var to skip daemonize" do
|
318
|
+
assert_equal @current_env_skip_daemonize, ENV['SANFORD_SKIP_DAEMONIZE']
|
319
|
+
end
|
320
|
+
|
321
|
+
should "not run the restart cmd" do
|
322
|
+
assert_nil @restart_cmd_spy.run_called_for
|
323
|
+
end
|
324
|
+
|
325
|
+
should "remove the PID file" do
|
326
|
+
assert_true @pid_file_spy.remove_called
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
265
330
|
|
266
|
-
|
267
|
-
|
268
|
-
|
331
|
+
class RunAndRestartTests < RunSetupTests
|
332
|
+
desc "and run with a restart signal"
|
333
|
+
setup do
|
334
|
+
@thread = Thread.new{ @process.run }
|
335
|
+
@thread.join(JOIN_SECONDS)
|
336
|
+
@process.signal_io.write(RESTART)
|
337
|
+
@thread.join(JOIN_SECONDS)
|
269
338
|
end
|
270
339
|
|
271
|
-
should "
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
340
|
+
should "pause its server" do
|
341
|
+
assert_true @server_spy.pause_called
|
342
|
+
assert_equal [true], @server_spy.pause_args
|
343
|
+
end
|
344
|
+
|
345
|
+
should "run the restart cmd" do
|
346
|
+
assert_equal @server_spy, @restart_cmd_spy.run_called_for
|
347
|
+
end
|
348
|
+
|
349
|
+
end
|
350
|
+
|
351
|
+
class RunWithServerCrashTests < RunSetupTests
|
352
|
+
desc "and run with the server crashing"
|
353
|
+
setup do
|
354
|
+
Assert.stub(@process.signal_io, :wait) do |timeout|
|
355
|
+
sleep JOIN_SECONDS * 0.5 # ensure this has time to run before the thread
|
356
|
+
# joins below
|
357
|
+
false
|
358
|
+
end
|
359
|
+
|
360
|
+
@thread = Thread.new{ @process.run }
|
361
|
+
@thread.join(JOIN_SECONDS)
|
362
|
+
@server_spy.start_called = false
|
363
|
+
@thread.join(JOIN_SECONDS)
|
364
|
+
end
|
365
|
+
teardown do
|
366
|
+
# manually unstub or the process thread will hang forever
|
367
|
+
Assert.unstub(@process.signal_io, :wait)
|
368
|
+
end
|
369
|
+
|
370
|
+
should "re-start its server" do
|
371
|
+
assert_true @server_spy.start_called
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|
375
|
+
|
376
|
+
class RunWithInvalidSignalTests < RunSetupTests
|
377
|
+
desc "and run with unsupported signals"
|
378
|
+
setup do
|
379
|
+
# ruby throws an argument error if the OS doesn't support a signal
|
380
|
+
Assert.stub(::Signal, :trap){ raise ArgumentError }
|
381
|
+
|
382
|
+
@thread = Thread.new{ @process.run }
|
383
|
+
@thread.join(JOIN_SECONDS)
|
384
|
+
end
|
385
|
+
|
386
|
+
should "start normally" do
|
387
|
+
assert_true @server_spy.start_called
|
388
|
+
assert_equal 'sleep', @thread.status
|
277
389
|
end
|
278
390
|
|
279
391
|
end
|
@@ -289,6 +401,12 @@ class Sanford::Process
|
|
289
401
|
Assert.stub(File, :stat).with(Dir.pwd){ @ruby_pwd_stat }
|
290
402
|
Assert.stub(File, :stat).with(ENV['PWD']){ env_pwd_stat }
|
291
403
|
|
404
|
+
@server_spy = ServerSpy.new
|
405
|
+
server_fd = Factory.integer
|
406
|
+
Assert.stub(@server_spy, :file_descriptor){ server_fd }
|
407
|
+
client_fds = Factory.integer(3).times.map{ Factory.integer }
|
408
|
+
Assert.stub(@server_spy, :client_file_descriptors){ client_fds }
|
409
|
+
|
292
410
|
@chdir_called_with = nil
|
293
411
|
Assert.stub(Dir, :chdir){ |*args| @chdir_called_with = args }
|
294
412
|
|
@@ -317,10 +435,38 @@ class Sanford::Process
|
|
317
435
|
assert_equal [Gem.ruby, $0, ARGV].flatten, subject.argv
|
318
436
|
end
|
319
437
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
438
|
+
if RUBY_VERSION == '1.8.7'
|
439
|
+
|
440
|
+
should "set env vars, change the dir and kernel exec when run" do
|
441
|
+
subject.run(@server_spy)
|
442
|
+
|
443
|
+
assert_equal @server_spy.file_descriptor.to_s, ENV['SANFORD_SERVER_FD']
|
444
|
+
exp = @server_spy.client_file_descriptors.join(',')
|
445
|
+
assert_equal exp, ENV['SANFORD_CLIENT_FDS']
|
446
|
+
assert_equal 'yes', ENV['SANFORD_SKIP_DAEMONIZE']
|
447
|
+
|
448
|
+
assert_equal [subject.dir], @chdir_called_with
|
449
|
+
assert_equal subject.argv, @exec_called_with
|
450
|
+
end
|
451
|
+
|
452
|
+
else
|
453
|
+
|
454
|
+
should "kernel exec when run" do
|
455
|
+
subject.run(@server_spy)
|
456
|
+
|
457
|
+
env = {
|
458
|
+
'SANFORD_SERVER_FD' => @server_spy.file_descriptor.to_s,
|
459
|
+
'SANFORD_CLIENT_FDS' => @server_spy.client_file_descriptors.join(','),
|
460
|
+
'SANFORD_SKIP_DAEMONIZE' => 'yes'
|
461
|
+
}
|
462
|
+
fd_redirects = (
|
463
|
+
[@server_spy.file_descriptor] +
|
464
|
+
@server_spy.client_file_descriptors
|
465
|
+
).inject({}){ |h, fd| h.merge!(fd => fd) }
|
466
|
+
options = { :chdir => subject.dir }.merge!(fd_redirects)
|
467
|
+
assert_equal ([env] + subject.argv + [options]), @exec_called_with
|
468
|
+
end
|
469
|
+
|
324
470
|
end
|
325
471
|
|
326
472
|
end
|
@@ -364,31 +510,35 @@ class Sanford::Process
|
|
364
510
|
|
365
511
|
end
|
366
512
|
|
513
|
+
SignalTrap = Struct.new(:signal, :block)
|
514
|
+
|
367
515
|
class ServerSpy
|
368
516
|
include Sanford::Server
|
369
517
|
|
370
|
-
name
|
371
|
-
ip
|
372
|
-
port
|
518
|
+
name Factory.string
|
519
|
+
ip Factory.string
|
520
|
+
port Factory.integer
|
373
521
|
pid_file Factory.file_path
|
374
522
|
|
375
|
-
|
376
|
-
|
377
|
-
attr_reader :listen_args, :start_args
|
378
|
-
attr_reader :thread
|
523
|
+
attr_accessor :process_label, :listen_called
|
524
|
+
attr_accessor :start_called, :stop_called, :halt_called, :pause_called
|
525
|
+
attr_reader :listen_args, :start_args, :stop_args, :halt_args, :pause_args
|
379
526
|
|
380
527
|
def initialize(*args)
|
381
528
|
super
|
382
|
-
@listen_called = false
|
383
|
-
@start_called = false
|
384
|
-
@stop_called = false
|
385
|
-
@halt_called = false
|
386
|
-
@pause_called = false
|
387
529
|
|
388
|
-
@
|
389
|
-
@start_args = nil
|
530
|
+
@process_label = Factory.string
|
390
531
|
|
391
|
-
@
|
532
|
+
@listen_args = nil
|
533
|
+
@listen_called = false
|
534
|
+
@start_args = nil
|
535
|
+
@start_called = false
|
536
|
+
@stop_args = nil
|
537
|
+
@stop_called = false
|
538
|
+
@halt_args = nil
|
539
|
+
@halt_called = false
|
540
|
+
@pause_args = nil
|
541
|
+
@pause_called = false
|
392
542
|
end
|
393
543
|
|
394
544
|
def listen(*args)
|
@@ -399,53 +549,38 @@ class Sanford::Process
|
|
399
549
|
def start(*args)
|
400
550
|
@start_args = args
|
401
551
|
@start_called = true
|
402
|
-
@thread
|
403
552
|
end
|
404
553
|
|
405
554
|
def stop(*args)
|
555
|
+
@stop_args = args
|
406
556
|
@stop_called = true
|
407
557
|
end
|
408
558
|
|
409
559
|
def halt(*args)
|
560
|
+
@halt_args = args
|
410
561
|
@halt_called = true
|
411
562
|
end
|
412
563
|
|
564
|
+
|
413
565
|
def pause(*args)
|
566
|
+
@pause_args = args
|
414
567
|
@pause_called = true
|
415
568
|
end
|
416
569
|
|
417
|
-
def
|
418
|
-
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
class ThreadSpy
|
423
|
-
attr_reader :join_called, :on_join_proc
|
424
|
-
|
425
|
-
def initialize
|
426
|
-
@join_called = false
|
427
|
-
@on_join_proc = proc{ }
|
428
|
-
end
|
429
|
-
|
430
|
-
def on_join(&block)
|
431
|
-
@on_join_proc = block
|
432
|
-
end
|
433
|
-
|
434
|
-
def join
|
435
|
-
@join_called = true
|
436
|
-
@on_join_proc.call
|
570
|
+
def running?
|
571
|
+
!!@start_called
|
437
572
|
end
|
438
573
|
end
|
439
574
|
|
440
575
|
class RestartCmdSpy
|
441
|
-
attr_reader :
|
576
|
+
attr_reader :run_called_for
|
442
577
|
|
443
578
|
def initialize
|
444
|
-
@
|
579
|
+
@run_called_for = nil
|
445
580
|
end
|
446
581
|
|
447
|
-
def run
|
448
|
-
@
|
582
|
+
def run(server)
|
583
|
+
@run_called_for = server
|
449
584
|
end
|
450
585
|
end
|
451
586
|
|