perfectqueue 0.8.44.1 → 0.8.45

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,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe PerfectQueue::Runner do
4
+ describe '#new' do
5
+ it 'creates with task' do
6
+ expect(PerfectQueue::Runner.new(double('task'))).to be_a(PerfectQueue::Runner)
7
+ end
8
+ end
9
+
10
+ describe '#task' do
11
+ let (:task) { double('task') }
12
+ let (:runner) { PerfectQueue::Runner.new(task) }
13
+ it 'returns given task' do
14
+ expect(runner.task).to eq(task)
15
+ end
16
+ end
17
+
18
+ describe '#queue' do
19
+ let (:runner) { PerfectQueue::Runner.new(double('task', client: 1)) }
20
+ it 'returns a queue' do
21
+ queue = runner.queue
22
+ expect(queue).to be_a(PerfectQueue::Queue)
23
+ end
24
+ end
25
+
26
+ describe '#kill' do
27
+ let (:runner) { PerfectQueue::Runner.new(double('task')) }
28
+ it 'always returns nil' do
29
+ expect(runner.kill(nil)).to be_nil
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe SignalThread do
4
+ before(:each) do
5
+ @th = SignalThread.new
6
+ end
7
+
8
+ after(:each) do
9
+ @th.trap('SIGUSR1')
10
+ @th.stop
11
+ @th.join
12
+ end
13
+
14
+ context('trap') do
15
+ it 'ignores Signal' do
16
+ old = @th.trap('SIGUSR1', 'IGNORE')
17
+ expect(old).to be_nil
18
+ expect(@th.handlers).to eq({})
19
+ end
20
+
21
+ it 'traps Signal' do
22
+ flag = false
23
+ pr = proc{flag=1;raise}
24
+ expect(@th.trap('SIGUSR1', &pr)).to be_nil
25
+ expect(@th.handlers).to eq({USR1: pr})
26
+ allow(STDERR).to receive(:write).at_least(:once)
27
+ Process.kill(:USR1, Process.pid)
28
+ Thread.pass until flag
29
+ expect(flag).to eq(1)
30
+ end
31
+ end
32
+
33
+ it 'queues signal' do
34
+ flag = false
35
+ pr = proc{flag=1;raise}
36
+ allow(@th).to receive(:enqueue){flag=2;raise}
37
+ expect(@th.trap('SIGUSR1', &pr)).to be_nil
38
+ allow(STDERR).to receive(:write).at_least(:once)
39
+ Process.kill(:USR1, Process.pid)
40
+ Thread.pass until flag
41
+ expect(flag).to eq(2)
42
+ end
43
+ end
@@ -21,7 +21,7 @@ describe Queue do
21
21
  loop_num.times do |i|
22
22
  queue.submit("#{thread_id}-#{i}", "type01", {}, :now=>now-10)
23
23
  task = queue.poll(:now=>now, :alive_time=>60)
24
- task.should_not == nil
24
+ expect(task).not_to eq(nil)
25
25
  task.heartbeat!(:now=>now, :alive_time=>70)
26
26
  task.finish!(:now=>now, :retention_time=>80)
27
27
  end
@@ -2,14 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  class TestHandler < PerfectQueue::Application::Base
4
4
  def run
5
- puts "TestHandler: #{task}"
5
+ #puts "TestHandler: #{task}"
6
6
  if task.data['raise_error']
7
7
  raise "expected error test"
8
8
  end
9
9
  if num = task.data['sleep']
10
10
  sleep num
11
11
  end
12
- puts "Task finished"
12
+ #puts "Task finished"
13
13
  end
14
14
 
15
15
  def kill(reason)
@@ -30,47 +30,202 @@ end
30
30
 
31
31
  describe Supervisor do
32
32
  include QueueTest
33
-
33
+ let (:logger) { double('logger').as_null_object }
34
34
  before do
35
- @sv = Supervisor.new(TestApp, queue_config)
36
- @thread = Thread.new {
37
- @sv.run
38
- }
35
+ object_double('PerfectQueue::DaemonsLogger', new: logger).as_stubbed_const
39
36
  end
40
37
 
41
- after do
42
- @sv.stop(true)
43
- @thread.join
38
+ context 'normal routing' do
39
+ before do
40
+ @sv = Supervisor.new(TestApp, queue_config)
41
+ @thread = Thread.new {
42
+ @sv.run
43
+ }
44
+ end
45
+
46
+ after do
47
+ @sv.stop(true)
48
+ @thread.join
49
+ end
50
+
51
+ it 'route' do
52
+ expect_any_instance_of(TestHandler).to receive(:run).once
53
+ expect_any_instance_of(RegexpHandler).to receive(:run).once
54
+ queue.submit('task01', 'test', {})
55
+ queue.submit('task02', 'reg01', {})
56
+ sleep 2
57
+ end
44
58
  end
45
59
 
46
- it 'route' do
47
- TestHandler.any_instance.should_receive(:run).once
48
- RegexpHandler.any_instance.should_receive(:run).once
49
- queue.submit('task01', 'test', {})
50
- queue.submit('task02', 'reg01', {})
51
- sleep 1
60
+ context 'listen_debug_server' do
61
+ after do
62
+ @sv.stop(true)
63
+ @thread.join
64
+ end
65
+
66
+ it 'listen_debug_server with UNIX Socket' do
67
+ Tempfile.open('supervisor') do |f|
68
+ config = queue_config.dup
69
+ config[:debug] = f.path
70
+ @sv = Supervisor.new(TestApp, config)
71
+ @thread = Thread.new {
72
+ @sv.run
73
+ }
74
+ sleep 2
75
+ end
76
+ end
77
+
78
+ it 'listen_debug_server with TCP with address:port' do
79
+ config = queue_config.dup
80
+ config[:debug] = '127.0.0.1:0'
81
+ @sv = Supervisor.new(TestApp, config)
82
+ @thread = Thread.new {
83
+ @sv.run
84
+ }
85
+ sleep 2
86
+ end
87
+
88
+ it 'listen_debug_server with TCP with port' do
89
+ config = queue_config.dup
90
+ config[:debug] = '0'
91
+ @sv = Supervisor.new(TestApp, config)
92
+ @thread = Thread.new {
93
+ @sv.run
94
+ }
95
+ sleep 2
96
+ end
52
97
  end
53
98
 
54
- it 'term signal' do
55
- sleep 1
56
- Process.kill(:TERM, Process.pid)
57
- puts "finish expected..."
58
- @thread.join
99
+ context 'replace' do
100
+ before do
101
+ @sv = Supervisor.new(TestApp, queue_config)
102
+ @thread = Thread.new {
103
+ @sv.run
104
+ }
105
+ Thread.pass until @sv.engine
106
+ end
107
+
108
+ after do
109
+ @sv.stop(true)
110
+ @thread.join
111
+ end
112
+
113
+ it 'replaces immediately' do
114
+ @sv.replace(true, ':')
115
+ end
116
+
117
+ it 'replaces not immediately' do
118
+ @sv.replace(false, ':')
119
+ end
120
+
121
+ it 'fails to replace' do
122
+ Thread.pass until @sv.engine
123
+ allow(@sv.engine).to receive(:replace) { raise }
124
+ @sv.replace(false, ':')
125
+ end
59
126
  end
60
127
 
61
- it 'quit signal' do
62
- sleep 1
63
- Process.kill(:QUIT, Process.pid)
64
- puts "finish expected..."
65
- @thread.join
128
+ context 'signal handling' do
129
+ before do
130
+ @sv = Supervisor.new(TestApp, queue_config)
131
+ @thread = Thread.new {
132
+ @sv.run
133
+ }
134
+ end
135
+
136
+ after do
137
+ @sv.stop(true)
138
+ @thread.join
139
+ end
140
+
141
+ it 'handles TERM signal' do
142
+ Thread.pass until @sv.engine
143
+ Process.kill(:TERM, Process.pid)
144
+ expect(@thread.join(3)).to eq(@thread)
145
+ end
146
+
147
+ it 'handles INT signal' do
148
+ Thread.pass until @sv.engine
149
+ Process.kill(:INT, Process.pid)
150
+ expect(@thread.join(3)).to eq(@thread)
151
+ end
152
+
153
+ it 'handles QUIT signal' do
154
+ Thread.pass until @sv.engine
155
+ Process.kill(:QUIT, Process.pid)
156
+ #puts "finish expected..."
157
+ expect(@thread.join(3)).to eq(@thread)
158
+ end
159
+
160
+ it 'handles USR1 signal' do
161
+ Thread.pass until @sv.engine
162
+ processors = @sv.engine.processors
163
+ Process.kill(:USR1, Process.pid)
164
+ expect(@sv.engine.processors).to eq(processors)
165
+ end
166
+
167
+ it 'handles HUP signal' do
168
+ Thread.pass until @sv.engine
169
+ processors = @sv.engine.processors
170
+ Process.kill(:HUP, Process.pid)
171
+ expect(@sv.engine.processors).to eq(processors)
172
+ end
173
+
174
+ it 'handles USR2 signal' do
175
+ Thread.pass until @sv.engine
176
+ allow(logger).to receive(:reopen!)
177
+ Process.kill(:USR2, Process.pid)
178
+ end
179
+
180
+ it 'kill reason' do
181
+ expect_any_instance_of(TestHandler).to receive(:kill).once #.with(kind_of(PerfectQueue::CancelRequestedError)) # FIXME 'with' dead locks
182
+ queue.submit('task01', 'test', {'sleep'=>4})
183
+ sleep 2
184
+ Process.kill(:TERM, Process.pid)
185
+ expect(@thread.join(3)).to eq(@thread)
186
+ end
187
+ end
188
+
189
+ describe '.run' do
190
+ let (:runner) { double('runner') }
191
+ let (:config) { double('config') }
192
+ before (:each) do
193
+ allow(Supervisor).to receive(:new) \
194
+ .with(runner, config) do |*args, &block|
195
+ expect(block).to be_a(Proc)
196
+ double('supervisor', run: nil)
197
+ end
198
+ end
199
+ it 'calls Supervisor.new.run' do
200
+ expect(Supervisor.run(runner, config){ }).to be_nil
201
+ end
66
202
  end
67
203
 
68
- it 'kill reason' do
69
- TestHandler.any_instance.should_receive(:kill).once #.with(kind_of(PerfectQueue::CancelRequestedError)) # FIXME 'with' dead locks
70
- queue.submit('task01', 'test', {'sleep'=>4})
71
- sleep 2
72
- Process.kill(:TERM, Process.pid)
73
- @thread.join
204
+ describe '#run' do
205
+ let (:supervisor) { Supervisor.new(double('runner')){raise} }
206
+ it 'rescues exception' do
207
+ expect(supervisor.run).to be_nil
208
+ end
74
209
  end
75
- end
76
210
 
211
+ describe '#stop' do
212
+ let (:supervisor) { Supervisor.new(double('runner')){} }
213
+ it 'return nil without engine' do
214
+ expect(supervisor.run).to be_nil
215
+ end
216
+ it 'rescues exception' do
217
+ supervisor.instance_variable_set(:@engine, true) # dummy
218
+ expect(supervisor.stop(true)).to be false
219
+ end
220
+ end
221
+
222
+ describe '#restart' do
223
+ let (:supervisor) { Supervisor.new(double('runner')){} }
224
+ it 'return nil without engine' do
225
+ expect(supervisor.run).to be_nil
226
+ end
227
+ it 'rescues exception' do
228
+ expect(supervisor.restart(true)).to be false
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe PerfectQueue::TaskMetadata do
4
+ let (:attributes){ double('attributes', delete: nil) }
5
+ describe '#task' do
6
+ it 'returns a task' do
7
+ client = double('client')
8
+ key = double('key')
9
+ tm = TaskMetadata.new(client, key, attributes)
10
+ task = tm.task
11
+ expect(task).to be_a(Task)
12
+ expect(task.client).to eq(client)
13
+ expect(task.key).to eq(key)
14
+ end
15
+ end
16
+
17
+ describe '#inspect' do
18
+ it 'returns inspected string' do
19
+ client = double('client')
20
+ key = double('key')
21
+ tm = TaskMetadata.new(client, key, attributes)
22
+ expect(tm.inspect).to eq("#<PerfectQueue::TaskMetadata @key=#{key.inspect} @attributes=#{attributes.inspect}>")
23
+ end
24
+ end
25
+
26
+ describe 'running?' do
27
+ it 'returns true on running' do
28
+ tm = TaskMetadata.new(double, double, status: TaskStatus::RUNNING)
29
+ expect(tm.running?).to be true
30
+ end
31
+
32
+ it 'returns false on finished' do
33
+ tm = TaskMetadata.new(double, double, status: TaskStatus::FINISHED)
34
+ expect(tm.running?).to be false
35
+ end
36
+ end
37
+
38
+ describe 'message' do
39
+ it 'returns given message' do
40
+ message = double('message')
41
+ tm = TaskMetadata.new(double, double, message: message)
42
+ expect(tm.message).to eq(message)
43
+ end
44
+ end
45
+
46
+ describe 'user' do
47
+ it 'returns given user' do
48
+ user = double('user')
49
+ tm = TaskMetadata.new(double, double, user: user)
50
+ expect(tm.user).to eq(user)
51
+ end
52
+ end
53
+
54
+ describe 'created_at' do
55
+ it 'returns a time of given created_at' do
56
+ epoch = 42
57
+ tm = TaskMetadata.new(double, double, created_at: epoch)
58
+ expect(tm.created_at).to eq(Time.at(epoch))
59
+ end
60
+ end
61
+
62
+ describe 'timeout' do
63
+ it 'returns a time of given timeout' do
64
+ epoch = 72
65
+ tm = TaskMetadata.new(double, double, timeout: epoch)
66
+ expect(tm.timeout).to eq(Time.at(epoch))
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe PerfectQueue::TaskMonitor do
4
+ describe '#kill_task' do
5
+ it 'rescues exception' do
6
+ tm = PerfectQueue::TaskMonitor.new(logger: double('logger').as_null_object)
7
+ task = double('task')
8
+ reason = double('reason')
9
+ allow(task).to receive_message_chain(:runner, :kill) \
10
+ .with(no_args).with(reason){raise}
11
+ tm.instance_variable_set(:@task, task)
12
+ expect{tm.kill_task(reason)}.to raise_error(RuntimeError)
13
+ end
14
+ end
15
+
16
+ describe '#external_task_heartbeat' do
17
+ it 'rescues exception' do
18
+ tm = PerfectQueue::TaskMonitor.new(logger: double('logger').as_null_object)
19
+ task = double('task')
20
+ reason = double('reason')
21
+ allow(task).to receive_message_chain(:runner, :kill) \
22
+ .with(no_args).with(reason){raise}
23
+ epoch = double('epoch')
24
+ allow(Time).to receive_message_chain(:now, :to_i){epoch}
25
+ ret = double('ret')
26
+ tm.instance_variable_set(:@task, task)
27
+ expect(tm.external_task_heartbeat(task){ret}).to eq(ret)
28
+ expect(tm.instance_variable_get(:@last_task_heartbeat)).to eq(epoch)
29
+ end
30
+ end
31
+
32
+ describe '#run' do
33
+ it 'rescues exception' do
34
+ config = {logger: double('logger').as_null_object}
35
+ force_stop = double('force_stop')
36
+ expect(force_stop).to receive(:call).with(no_args).exactly(:once)
37
+ tm = PerfectQueue::TaskMonitor.new(config, nil, force_stop)
38
+ allow(Time).to receive(:now){raise}
39
+ tm.run
40
+ end
41
+ end
42
+ end