qs 0.0.1 → 0.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.
- data/.gitignore +1 -0
- data/Gemfile +6 -1
- data/LICENSE.txt +1 -1
- data/bench/config.qs +46 -0
- data/bench/queue.rb +8 -0
- data/bench/report.rb +114 -0
- data/bench/report.txt +11 -0
- data/bin/qs +7 -0
- data/lib/qs/cli.rb +124 -0
- data/lib/qs/client.rb +121 -0
- data/lib/qs/config_file.rb +79 -0
- data/lib/qs/daemon.rb +350 -0
- data/lib/qs/daemon_data.rb +46 -0
- data/lib/qs/error_handler.rb +58 -0
- data/lib/qs/job.rb +70 -0
- data/lib/qs/job_handler.rb +90 -0
- data/lib/qs/logger.rb +23 -0
- data/lib/qs/payload_handler.rb +136 -0
- data/lib/qs/pid_file.rb +42 -0
- data/lib/qs/process.rb +136 -0
- data/lib/qs/process_signal.rb +20 -0
- data/lib/qs/qs_runner.rb +49 -0
- data/lib/qs/queue.rb +69 -0
- data/lib/qs/redis_item.rb +33 -0
- data/lib/qs/route.rb +52 -0
- data/lib/qs/runner.rb +26 -0
- data/lib/qs/test_helpers.rb +17 -0
- data/lib/qs/test_runner.rb +43 -0
- data/lib/qs/version.rb +1 -1
- data/lib/qs.rb +92 -2
- data/qs.gemspec +7 -2
- data/test/helper.rb +8 -1
- data/test/support/app_daemon.rb +74 -0
- data/test/support/config.qs +7 -0
- data/test/support/config_files/empty.qs +0 -0
- data/test/support/config_files/invalid.qs +1 -0
- data/test/support/config_files/valid.qs +7 -0
- data/test/support/config_invalid_run.qs +3 -0
- data/test/support/config_no_run.qs +0 -0
- data/test/support/factory.rb +14 -0
- data/test/support/pid_file_spy.rb +19 -0
- data/test/support/runner_spy.rb +17 -0
- data/test/system/daemon_tests.rb +226 -0
- data/test/unit/cli_tests.rb +188 -0
- data/test/unit/client_tests.rb +269 -0
- data/test/unit/config_file_tests.rb +59 -0
- data/test/unit/daemon_data_tests.rb +96 -0
- data/test/unit/daemon_tests.rb +702 -0
- data/test/unit/error_handler_tests.rb +163 -0
- data/test/unit/job_handler_tests.rb +253 -0
- data/test/unit/job_tests.rb +132 -0
- data/test/unit/logger_tests.rb +38 -0
- data/test/unit/payload_handler_tests.rb +276 -0
- data/test/unit/pid_file_tests.rb +70 -0
- data/test/unit/process_signal_tests.rb +61 -0
- data/test/unit/process_tests.rb +371 -0
- data/test/unit/qs_runner_tests.rb +166 -0
- data/test/unit/qs_tests.rb +217 -0
- data/test/unit/queue_tests.rb +132 -0
- data/test/unit/redis_item_tests.rb +49 -0
- data/test/unit/route_tests.rb +81 -0
- data/test/unit/runner_tests.rb +63 -0
- data/test/unit/test_helper_tests.rb +61 -0
- data/test/unit/test_runner_tests.rb +128 -0
- metadata +180 -15
@@ -0,0 +1,371 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/process'
|
3
|
+
|
4
|
+
require 'qs/daemon'
|
5
|
+
require 'test/support/pid_file_spy'
|
6
|
+
|
7
|
+
class Qs::Process
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Qs::Process"
|
11
|
+
setup do
|
12
|
+
@process_class = Qs::Process
|
13
|
+
end
|
14
|
+
subject{ @process_class }
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class InitTests < UnitTests
|
19
|
+
desc "when init"
|
20
|
+
setup do
|
21
|
+
@current_env_process_name = ENV['QS_PROCESS_NAME']
|
22
|
+
@current_env_skip_daemonize = ENV['QS_SKIP_DAEMONIZE']
|
23
|
+
ENV.delete('QS_PROCESS_NAME')
|
24
|
+
ENV.delete('QS_SKIP_DAEMONIZE')
|
25
|
+
|
26
|
+
@daemon_spy = DaemonSpy.new
|
27
|
+
|
28
|
+
@pid_file_spy = PIDFileSpy.new(Factory.integer)
|
29
|
+
Assert.stub(Qs::PIDFile, :new).with(@daemon_spy.pid_file) do
|
30
|
+
@pid_file_spy
|
31
|
+
end
|
32
|
+
|
33
|
+
@restart_cmd_spy = RestartCmdSpy.new
|
34
|
+
Assert.stub(Qs::RestartCmd, :new){ @restart_cmd_spy }
|
35
|
+
|
36
|
+
@process = @process_class.new(@daemon_spy)
|
37
|
+
end
|
38
|
+
teardown do
|
39
|
+
ENV['QS_SKIP_DAEMONIZE'] = @current_env_skip_daemonize
|
40
|
+
ENV['QS_PROCESS_NAME'] = @current_env_process_name
|
41
|
+
end
|
42
|
+
subject{ @process }
|
43
|
+
|
44
|
+
should have_readers :daemon, :name, :pid_file, :restart_cmd
|
45
|
+
should have_imeths :run, :daemonize?, :restart?
|
46
|
+
|
47
|
+
should "know its daemon" do
|
48
|
+
assert_equal @daemon_spy, subject.daemon
|
49
|
+
end
|
50
|
+
|
51
|
+
should "know its name, pid file and restart cmd" do
|
52
|
+
assert_equal "qs-#{@daemon_spy.name}", subject.name
|
53
|
+
assert_equal @pid_file_spy, subject.pid_file
|
54
|
+
assert_equal @restart_cmd_spy, subject.restart_cmd
|
55
|
+
end
|
56
|
+
|
57
|
+
should "set its name using env vars" do
|
58
|
+
ENV['QS_PROCESS_NAME'] = Factory.string
|
59
|
+
process = @process_class.new(@daemon_spy)
|
60
|
+
assert_equal ENV['QS_PROCESS_NAME'], process.name
|
61
|
+
end
|
62
|
+
|
63
|
+
should "ignore blank env values for its name" do
|
64
|
+
ENV['QS_PROCESS_NAME'] = ''
|
65
|
+
process = @process_class.new(@daemon_spy)
|
66
|
+
assert_equal "qs-#{@daemon_spy.name}", process.name
|
67
|
+
end
|
68
|
+
|
69
|
+
should "not daemonize by default" do
|
70
|
+
process = @process_class.new(@daemon_spy)
|
71
|
+
assert_false process.daemonize?
|
72
|
+
end
|
73
|
+
|
74
|
+
should "daemonize if turned on" do
|
75
|
+
process = @process_class.new(@daemon_spy, :daemonize => true)
|
76
|
+
assert_true process.daemonize?
|
77
|
+
end
|
78
|
+
|
79
|
+
should "not daemonize if skipped via the env var" do
|
80
|
+
ENV['QS_SKIP_DAEMONIZE'] = 'yes'
|
81
|
+
process = @process_class.new(@daemon_spy)
|
82
|
+
assert_false process.daemonize?
|
83
|
+
process = @process_class.new(@daemon_spy, :daemonize => true)
|
84
|
+
assert_false process.daemonize?
|
85
|
+
end
|
86
|
+
|
87
|
+
should "ignore blank env values for skip daemonize" do
|
88
|
+
ENV['QS_SKIP_DAEMONIZE'] = ''
|
89
|
+
process = @process_class.new(@daemon_spy, :daemonize => true)
|
90
|
+
assert_true process.daemonize?
|
91
|
+
end
|
92
|
+
|
93
|
+
should "not restart by default" do
|
94
|
+
assert_false subject.restart?
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
class RunSetupTests < InitTests
|
100
|
+
setup do
|
101
|
+
@daemonize_called = false
|
102
|
+
Assert.stub(::Process, :daemon).with(true){ @daemonize_called = true }
|
103
|
+
|
104
|
+
@current_process_name = $0
|
105
|
+
|
106
|
+
@term_signal_trap_block = nil
|
107
|
+
@term_signal_trap_called = false
|
108
|
+
Assert.stub(::Signal, :trap).with("TERM") do |&block|
|
109
|
+
@term_signal_trap_block = block
|
110
|
+
@term_signal_trap_called = true
|
111
|
+
end
|
112
|
+
|
113
|
+
@int_signal_trap_block = nil
|
114
|
+
@int_signal_trap_called = false
|
115
|
+
Assert.stub(::Signal, :trap).with("INT") do |&block|
|
116
|
+
@int_signal_trap_block = block
|
117
|
+
@int_signal_trap_called = true
|
118
|
+
end
|
119
|
+
|
120
|
+
@usr2_signal_trap_block = nil
|
121
|
+
@usr2_signal_trap_called = false
|
122
|
+
Assert.stub(::Signal, :trap).with("USR2") do |&block|
|
123
|
+
@usr2_signal_trap_block = block
|
124
|
+
@usr2_signal_trap_called = true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
teardown do
|
128
|
+
$0 = @current_process_name
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
class RunTests < RunSetupTests
|
134
|
+
desc "and run"
|
135
|
+
setup do
|
136
|
+
@process.run
|
137
|
+
end
|
138
|
+
|
139
|
+
should "not have daemonized the process" do
|
140
|
+
assert_false @daemonize_called
|
141
|
+
end
|
142
|
+
|
143
|
+
should "have set the process name" do
|
144
|
+
assert_equal $0, subject.name
|
145
|
+
end
|
146
|
+
|
147
|
+
should "have written the PID file" do
|
148
|
+
assert_true @pid_file_spy.write_called
|
149
|
+
end
|
150
|
+
|
151
|
+
should "have trapped signals" do
|
152
|
+
assert_true @term_signal_trap_called
|
153
|
+
assert_false @daemon_spy.stop_called
|
154
|
+
@term_signal_trap_block.call
|
155
|
+
assert_true @daemon_spy.stop_called
|
156
|
+
|
157
|
+
assert_true @int_signal_trap_called
|
158
|
+
assert_false @daemon_spy.halt_called
|
159
|
+
@int_signal_trap_block.call
|
160
|
+
assert_true @daemon_spy.halt_called
|
161
|
+
|
162
|
+
@daemon_spy.stop_called = false
|
163
|
+
|
164
|
+
assert_true @usr2_signal_trap_called
|
165
|
+
assert_false subject.restart?
|
166
|
+
@usr2_signal_trap_block.call
|
167
|
+
assert_true @daemon_spy.stop_called
|
168
|
+
assert_true subject.restart?
|
169
|
+
end
|
170
|
+
|
171
|
+
should "have started the daemon" do
|
172
|
+
assert_true @daemon_spy.start_called
|
173
|
+
end
|
174
|
+
|
175
|
+
should "have joined the daemon thread" do
|
176
|
+
assert_true @daemon_spy.thread.join_called
|
177
|
+
end
|
178
|
+
|
179
|
+
should "not run the restart cmd" do
|
180
|
+
assert_false @restart_cmd_spy.run_called
|
181
|
+
end
|
182
|
+
|
183
|
+
should "have removed the PID file" do
|
184
|
+
assert_true @pid_file_spy.remove_called
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
class RunWithDaemonizeTests < RunSetupTests
|
190
|
+
desc "that should daemonize is run"
|
191
|
+
setup do
|
192
|
+
Assert.stub(@process, :daemonize?){ true }
|
193
|
+
@process.run
|
194
|
+
end
|
195
|
+
|
196
|
+
should "have daemonized the process" do
|
197
|
+
assert_true @daemonize_called
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
class RunAndDaemonPausedTests < RunSetupTests
|
203
|
+
desc "then run and sent a restart signal"
|
204
|
+
setup do
|
205
|
+
# mimicing pause being called by a signal, after the thread is joined
|
206
|
+
@daemon_spy.thread.on_join{ @usr2_signal_trap_block.call }
|
207
|
+
@process.run
|
208
|
+
end
|
209
|
+
|
210
|
+
should "set env vars for restarting and run the restart cmd" do
|
211
|
+
assert_equal 'yes', ENV['QS_SKIP_DAEMONIZE']
|
212
|
+
assert_true @restart_cmd_spy.run_called
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
class RestartCmdTests < UnitTests
|
218
|
+
desc "RestartCmd"
|
219
|
+
setup do
|
220
|
+
@current_pwd = ENV['PWD']
|
221
|
+
ENV['PWD'] = Factory.path
|
222
|
+
|
223
|
+
@ruby_pwd_stat = File.stat(Dir.pwd)
|
224
|
+
env_pwd_stat = File.stat('/dev/null')
|
225
|
+
Assert.stub(File, :stat).with(Dir.pwd){ @ruby_pwd_stat }
|
226
|
+
Assert.stub(File, :stat).with(ENV['PWD']){ env_pwd_stat }
|
227
|
+
|
228
|
+
@chdir_called_with = nil
|
229
|
+
Assert.stub(Dir, :chdir){ |*args| @chdir_called_with = args }
|
230
|
+
|
231
|
+
@exec_called_with = false
|
232
|
+
Assert.stub(Kernel, :exec){ |*args| @exec_called_with = args }
|
233
|
+
|
234
|
+
@cmd_class = Qs::RestartCmd
|
235
|
+
end
|
236
|
+
teardown do
|
237
|
+
ENV['PWD'] = @current_pwd
|
238
|
+
end
|
239
|
+
subject{ @restart_cmd }
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
class RestartCmdInitTests < RestartCmdTests
|
244
|
+
desc "when init"
|
245
|
+
setup do
|
246
|
+
@restart_cmd = @cmd_class.new
|
247
|
+
end
|
248
|
+
|
249
|
+
should have_readers :argv, :dir
|
250
|
+
should have_imeths :run
|
251
|
+
|
252
|
+
should "know its argv" do
|
253
|
+
assert_equal [Gem.ruby, $0, ARGV].flatten, subject.argv
|
254
|
+
end
|
255
|
+
|
256
|
+
should "change the dir and run a kernel exec when run" do
|
257
|
+
subject.run
|
258
|
+
assert_equal [subject.dir], @chdir_called_with
|
259
|
+
assert_equal subject.argv, @exec_called_with
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
class RestartCmdWithPWDEnvNoMatchTests < RestartCmdTests
|
265
|
+
desc "when init with a PWD env variable that doesn't point to ruby working dir"
|
266
|
+
setup do
|
267
|
+
@restart_cmd = @cmd_class.new
|
268
|
+
end
|
269
|
+
|
270
|
+
should "know its dir" do
|
271
|
+
assert_equal Dir.pwd, subject.dir
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
class RestartCmdWithPWDEnvInitTests < RestartCmdTests
|
277
|
+
desc "when init with a PWD env variable that points to the ruby working dir"
|
278
|
+
setup do
|
279
|
+
# make ENV['PWD'] point to the same file as Dir.pwd
|
280
|
+
Assert.stub(File, :stat).with(ENV['PWD']){ @ruby_pwd_stat }
|
281
|
+
@restart_cmd = @cmd_class.new
|
282
|
+
end
|
283
|
+
|
284
|
+
should "know its dir" do
|
285
|
+
assert_equal ENV['PWD'], subject.dir
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
class RestartCmdWithNoPWDEnvInitTests < RestartCmdTests
|
291
|
+
desc "when init with a PWD env variable set"
|
292
|
+
setup do
|
293
|
+
ENV.delete('PWD')
|
294
|
+
@restart_cmd = @cmd_class.new
|
295
|
+
end
|
296
|
+
|
297
|
+
should "know its dir" do
|
298
|
+
assert_equal Dir.pwd, subject.dir
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
class DaemonSpy
|
304
|
+
include Qs::Daemon
|
305
|
+
|
306
|
+
name Factory.string
|
307
|
+
pid_file Factory.file_path
|
308
|
+
|
309
|
+
queue Qs::Queue.new{ name Factory.string }
|
310
|
+
|
311
|
+
attr_accessor :start_called, :stop_called, :halt_called
|
312
|
+
attr_reader :start_args
|
313
|
+
attr_reader :thread
|
314
|
+
|
315
|
+
def initialize(*args)
|
316
|
+
super
|
317
|
+
@start_called = false
|
318
|
+
@stop_called = false
|
319
|
+
@halt_called = false
|
320
|
+
|
321
|
+
@start_args = nil
|
322
|
+
|
323
|
+
@thread = ThreadSpy.new
|
324
|
+
end
|
325
|
+
|
326
|
+
def start(*args)
|
327
|
+
@start_args = args
|
328
|
+
@start_called = true
|
329
|
+
@thread
|
330
|
+
end
|
331
|
+
|
332
|
+
def stop(*args)
|
333
|
+
@stop_called = true
|
334
|
+
end
|
335
|
+
|
336
|
+
def halt(*args)
|
337
|
+
@halt_called = true
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
class ThreadSpy
|
342
|
+
attr_reader :join_called, :on_join_proc
|
343
|
+
|
344
|
+
def initialize
|
345
|
+
@join_called = false
|
346
|
+
@on_join_proc = proc{ }
|
347
|
+
end
|
348
|
+
|
349
|
+
def on_join(&block)
|
350
|
+
@on_join_proc = block
|
351
|
+
end
|
352
|
+
|
353
|
+
def join
|
354
|
+
@join_called = true
|
355
|
+
@on_join_proc.call
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
class RestartCmdSpy
|
360
|
+
attr_reader :run_called
|
361
|
+
|
362
|
+
def initialize
|
363
|
+
@run_called = false
|
364
|
+
end
|
365
|
+
|
366
|
+
def run
|
367
|
+
@run_called = true
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/qs_runner'
|
3
|
+
|
4
|
+
require 'qs'
|
5
|
+
require 'qs/job_handler'
|
6
|
+
|
7
|
+
class Qs::QsRunner
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Qs::QsRunner"
|
11
|
+
setup do
|
12
|
+
Qs.config.timeout = Factory.integer
|
13
|
+
@runner_class = Qs::QsRunner
|
14
|
+
end
|
15
|
+
teardown do
|
16
|
+
Qs.reset!
|
17
|
+
Qs.init
|
18
|
+
end
|
19
|
+
subject{ @runner_class }
|
20
|
+
|
21
|
+
should "be a runner" do
|
22
|
+
assert_true subject < Qs::Runner
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class InitTests < UnitTests
|
28
|
+
desc "when init"
|
29
|
+
setup do
|
30
|
+
@handler_class = TestJobHandler
|
31
|
+
@runner = @runner_class.new(@handler_class)
|
32
|
+
end
|
33
|
+
subject{ @runner }
|
34
|
+
|
35
|
+
should have_readers :timeout
|
36
|
+
should have_imeths :run
|
37
|
+
|
38
|
+
should "know its timeout" do
|
39
|
+
assert_equal TestJobHandler.timeout, subject.timeout
|
40
|
+
handler_class = Class.new{ include Qs::JobHandler }
|
41
|
+
runner = @runner_class.new(handler_class)
|
42
|
+
assert_equal Qs.config.timeout, runner.timeout
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class RunSetupTests < InitTests
|
48
|
+
desc "and run"
|
49
|
+
setup do
|
50
|
+
@timeout_called_with = nil
|
51
|
+
Assert.stub(OptionalTimeout, :new) do |*args, &block|
|
52
|
+
@timeout_called_with = args
|
53
|
+
block.call
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class RunTests < RunSetupTests
|
60
|
+
setup do
|
61
|
+
@handler = @runner.handler
|
62
|
+
@runner.run
|
63
|
+
end
|
64
|
+
|
65
|
+
should "run the handler in an optional timeout" do
|
66
|
+
assert_equal [@runner.timeout], @timeout_called_with
|
67
|
+
end
|
68
|
+
|
69
|
+
should "run the handlers before callbacks" do
|
70
|
+
assert_equal 1, @handler.first_before_call_order
|
71
|
+
assert_equal 2, @handler.second_before_call_order
|
72
|
+
end
|
73
|
+
|
74
|
+
should "call the handlers init and run methods" do
|
75
|
+
assert_equal 3, @handler.init_call_order
|
76
|
+
assert_equal 4, @handler.run_call_order
|
77
|
+
end
|
78
|
+
|
79
|
+
should "run the handlers after callbacks" do
|
80
|
+
assert_equal 5, @handler.first_after_call_order
|
81
|
+
assert_equal 6, @handler.second_after_call_order
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
class RunWithTimeoutErrorTests < RunSetupTests
|
87
|
+
setup do
|
88
|
+
Assert.stub(OptionalTimeout, :new){ raise Qs::TimeoutError }
|
89
|
+
end
|
90
|
+
|
91
|
+
should "raise a timeout error with a good message" do
|
92
|
+
exception = nil
|
93
|
+
begin; @runner.run; rescue StandardError => exception; end
|
94
|
+
|
95
|
+
assert_kind_of Qs::TimeoutError, exception
|
96
|
+
exp = "#{@handler_class} timed out (#{@runner.timeout}s)"
|
97
|
+
assert_equal exp, exception.message
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
class OptionalTimeoutTests < UnitTests
|
103
|
+
desc "OptionalTimeout"
|
104
|
+
setup do
|
105
|
+
@timeout_called_with = nil
|
106
|
+
Assert.stub(SystemTimer, :timeout_after) do |*args, &block|
|
107
|
+
@timeout_called_with = args
|
108
|
+
block.call
|
109
|
+
end
|
110
|
+
end
|
111
|
+
subject{ OptionalTimeout }
|
112
|
+
|
113
|
+
should have_imeths :new
|
114
|
+
|
115
|
+
should "use a system timer timeout when provided a non-`nil` value" do
|
116
|
+
value = Factory.integer
|
117
|
+
block_run = false
|
118
|
+
|
119
|
+
subject.new(value){ block_run = true }
|
120
|
+
assert_equal [value, Qs::TimeoutError], @timeout_called_with
|
121
|
+
assert_true block_run
|
122
|
+
end
|
123
|
+
|
124
|
+
should "call the block when provided a `nil` value" do
|
125
|
+
block_run = false
|
126
|
+
|
127
|
+
subject.new(nil){ block_run = true }
|
128
|
+
assert_nil @timeout_called_with
|
129
|
+
assert_true block_run
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
class TestJobHandler
|
135
|
+
include Qs::JobHandler
|
136
|
+
|
137
|
+
attr_reader :first_before_call_order, :second_before_call_order
|
138
|
+
attr_reader :first_after_call_order, :second_after_call_order
|
139
|
+
attr_reader :init_call_order, :run_call_order
|
140
|
+
attr_reader :response_data
|
141
|
+
|
142
|
+
timeout Factory.integer
|
143
|
+
|
144
|
+
before{ @first_before_call_order = next_call_order }
|
145
|
+
before{ @second_before_call_order = next_call_order }
|
146
|
+
|
147
|
+
after{ @first_after_call_order = next_call_order }
|
148
|
+
after{ @second_after_call_order = next_call_order }
|
149
|
+
|
150
|
+
def init!
|
151
|
+
@init_call_order = next_call_order
|
152
|
+
end
|
153
|
+
|
154
|
+
def run!
|
155
|
+
@run_call_order = next_call_order
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def next_call_order
|
161
|
+
@order ||= 0
|
162
|
+
@order += 1
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|