2014-12-30 15:54:58 -05:00
|
|
|
require_relative 'helper'
|
2015-10-06 15:43:01 -04:00
|
|
|
require 'sidekiq/fetch'
|
|
|
|
require 'sidekiq/cli'
|
2012-01-26 15:45:04 -05:00
|
|
|
require 'sidekiq/processor'
|
|
|
|
|
2013-09-22 17:38:33 -04:00
|
|
|
class TestProcessor < Sidekiq::Test
|
2012-07-31 11:43:09 -04:00
|
|
|
TestException = Class.new(StandardError)
|
|
|
|
TEST_EXCEPTION = TestException.new("kerboom!")
|
|
|
|
|
2015-10-06 15:43:01 -04:00
|
|
|
describe 'processor' do
|
2012-01-26 15:45:04 -05:00
|
|
|
before do
|
|
|
|
$invokes = 0
|
2015-10-06 15:43:01 -04:00
|
|
|
@mgr = Minitest::Mock.new
|
2015-10-08 12:37:37 -04:00
|
|
|
@mgr.expect(:options, {:queues => ['default']})
|
|
|
|
@mgr.expect(:options, {:queues => ['default']})
|
2015-10-06 15:43:01 -04:00
|
|
|
@processor = ::Sidekiq::Processor.new(@mgr)
|
2012-01-26 15:45:04 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
class MockWorker
|
2012-02-11 02:16:12 -05:00
|
|
|
include Sidekiq::Worker
|
2012-01-26 15:45:04 -05:00
|
|
|
def perform(args)
|
2012-07-31 11:43:09 -04:00
|
|
|
raise TEST_EXCEPTION if args == 'boom'
|
2012-08-04 15:11:46 -04:00
|
|
|
args.pop if args.is_a? Array
|
2012-01-26 15:45:04 -05:00
|
|
|
$invokes += 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-01-06 00:17:08 -05:00
|
|
|
def work(msg, queue='queue:default')
|
|
|
|
Sidekiq::BasicFetch::UnitOfWork.new(queue, msg)
|
|
|
|
end
|
|
|
|
|
2012-01-26 15:45:04 -05:00
|
|
|
it 'processes as expected' do
|
2012-06-21 23:51:47 -04:00
|
|
|
msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['myarg'] })
|
2013-01-06 00:17:08 -05:00
|
|
|
@processor.process(work(msg))
|
2012-01-26 15:45:04 -05:00
|
|
|
assert_equal 1, $invokes
|
2012-07-31 11:43:09 -04:00
|
|
|
end
|
|
|
|
|
2014-09-09 21:57:39 -04:00
|
|
|
it 'executes a worker as expected' do
|
|
|
|
worker = Minitest::Mock.new
|
|
|
|
worker.expect(:perform, nil, [1, 2, 3])
|
|
|
|
@processor.execute_job(worker, [1, 2, 3])
|
|
|
|
end
|
|
|
|
|
2012-07-31 11:43:09 -04:00
|
|
|
it 're-raises exceptions after handling' do
|
|
|
|
msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
|
|
|
|
re_raise = false
|
|
|
|
|
|
|
|
begin
|
2013-01-06 00:17:08 -05:00
|
|
|
@processor.process(work(msg))
|
2015-10-06 15:43:01 -04:00
|
|
|
flunk "Expected exception"
|
2012-07-31 11:43:09 -04:00
|
|
|
rescue TestException
|
|
|
|
re_raise = true
|
|
|
|
end
|
|
|
|
|
2015-10-06 15:43:01 -04:00
|
|
|
assert_equal 0, $invokes
|
2012-07-31 11:43:09 -04:00
|
|
|
assert re_raise, "does not re-raise exceptions after handling"
|
2012-01-26 15:45:04 -05:00
|
|
|
end
|
2012-08-04 15:11:46 -04:00
|
|
|
|
|
|
|
it 'does not modify original arguments' do
|
|
|
|
msg = { 'class' => MockWorker.to_s, 'args' => [['myarg']] }
|
|
|
|
msgstr = Sidekiq.dump_json(msg)
|
2015-10-06 15:43:01 -04:00
|
|
|
@mgr.expect(:processor_done, nil, [@processor])
|
|
|
|
@processor.process(work(msgstr))
|
2012-08-04 15:11:46 -04:00
|
|
|
assert_equal [['myarg']], msg['args']
|
|
|
|
end
|
2012-12-05 20:35:49 -05:00
|
|
|
|
2015-09-04 20:13:09 -04:00
|
|
|
describe 'acknowledgement' do
|
|
|
|
class ExceptionRaisingMiddleware
|
|
|
|
def initialize(raise_before_yield, raise_after_yield, skip)
|
|
|
|
@raise_before_yield = raise_before_yield
|
|
|
|
@raise_after_yield = raise_after_yield
|
|
|
|
@skip = skip
|
|
|
|
end
|
|
|
|
|
|
|
|
def call(worker, item, queue)
|
|
|
|
raise TEST_EXCEPTION if @raise_before_yield
|
|
|
|
yield unless @skip
|
|
|
|
raise TEST_EXCEPTION if @raise_after_yield
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:raise_before_yield) { false }
|
|
|
|
let(:raise_after_yield) { false }
|
|
|
|
let(:skip_job) { false }
|
|
|
|
let(:worker_args) { ['myarg'] }
|
|
|
|
let(:work) { MiniTest::Mock.new }
|
|
|
|
|
|
|
|
before do
|
2015-10-06 15:43:01 -04:00
|
|
|
work.expect(:queue_name, 'queue:default')
|
2015-10-23 18:05:50 -04:00
|
|
|
work.expect(:job, Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => worker_args }))
|
2015-09-04 20:13:09 -04:00
|
|
|
Sidekiq.server_middleware do |chain|
|
|
|
|
chain.prepend ExceptionRaisingMiddleware, raise_before_yield, raise_after_yield, skip_job
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
|
|
|
Sidekiq.server_middleware do |chain|
|
|
|
|
chain.remove ExceptionRaisingMiddleware
|
|
|
|
end
|
|
|
|
work.verify
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'middleware throws an exception before processing the work' do
|
|
|
|
let(:raise_before_yield) { true }
|
|
|
|
|
|
|
|
it 'does not ack' do
|
|
|
|
begin
|
|
|
|
@processor.process(work)
|
|
|
|
flunk "Expected #process to raise exception"
|
|
|
|
rescue TestException
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'middleware throws an exception after processing the work' do
|
|
|
|
let(:raise_after_yield) { true }
|
|
|
|
|
|
|
|
it 'acks the job' do
|
|
|
|
work.expect(:acknowledge, nil)
|
|
|
|
begin
|
|
|
|
@processor.process(work)
|
|
|
|
flunk "Expected #process to raise exception"
|
|
|
|
rescue TestException
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'middleware decides to skip work' do
|
|
|
|
let(:skip_job) { true }
|
|
|
|
|
|
|
|
it 'acks the job' do
|
|
|
|
work.expect(:acknowledge, nil)
|
2015-10-06 15:43:01 -04:00
|
|
|
@mgr.expect(:processor_done, nil, [@processor])
|
2015-09-04 20:13:09 -04:00
|
|
|
@processor.process(work)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'worker raises an exception' do
|
|
|
|
let(:worker_args) { ['boom'] }
|
|
|
|
|
|
|
|
it 'acks the job' do
|
|
|
|
work.expect(:acknowledge, nil)
|
|
|
|
begin
|
|
|
|
@processor.process(work)
|
|
|
|
flunk "Expected #process to raise exception"
|
|
|
|
rescue TestException
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'everything goes well' do
|
|
|
|
it 'acks the job' do
|
|
|
|
work.expect(:acknowledge, nil)
|
2015-10-06 15:43:01 -04:00
|
|
|
@mgr.expect(:processor_done, nil, [@processor])
|
2015-09-04 20:13:09 -04:00
|
|
|
@processor.process(work)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-05 20:35:49 -05:00
|
|
|
describe 'stats' do
|
|
|
|
before do
|
|
|
|
Sidekiq.redis {|c| c.flushdb }
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'when successful' do
|
2015-09-22 15:48:43 -04:00
|
|
|
let(:processed_today_key) { "stat:processed:#{Time.now.utc.strftime("%Y-%m-%d")}" }
|
2013-05-31 12:02:27 -04:00
|
|
|
|
2012-12-05 20:35:49 -05:00
|
|
|
def successful_job
|
|
|
|
msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['myarg'] })
|
2015-10-06 15:43:01 -04:00
|
|
|
@mgr.expect(:processor_done, nil, [@processor])
|
2013-01-06 00:17:08 -05:00
|
|
|
@processor.process(work(msg))
|
2012-12-05 20:35:49 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'increments processed stat' do
|
2015-10-07 18:01:44 -04:00
|
|
|
Sidekiq::Processor::PROCESSED.value = 0
|
2012-12-05 20:35:49 -05:00
|
|
|
successful_job
|
2015-10-07 18:01:44 -04:00
|
|
|
assert_equal 1, Sidekiq::Processor::PROCESSED.value
|
2013-05-31 12:02:27 -04:00
|
|
|
end
|
2012-12-05 20:35:49 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
describe 'when failed' do
|
2015-09-22 15:48:43 -04:00
|
|
|
let(:failed_today_key) { "stat:failed:#{Time.now.utc.strftime("%Y-%m-%d")}" }
|
2013-05-31 12:02:27 -04:00
|
|
|
|
2012-12-05 20:35:49 -05:00
|
|
|
def failed_job
|
|
|
|
msg = Sidekiq.dump_json({ 'class' => MockWorker.to_s, 'args' => ['boom'] })
|
|
|
|
begin
|
2013-01-06 00:17:08 -05:00
|
|
|
@processor.process(work(msg))
|
2012-12-05 20:35:49 -05:00
|
|
|
rescue TestException
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'increments failed stat' do
|
2015-10-07 18:01:44 -04:00
|
|
|
Sidekiq::Processor::FAILURE.value = 0
|
2012-12-05 20:35:49 -05:00
|
|
|
failed_job
|
2015-10-07 18:01:44 -04:00
|
|
|
assert_equal 1, Sidekiq::Processor::FAILURE.value
|
2013-05-31 12:02:27 -04:00
|
|
|
end
|
|
|
|
end
|
2012-12-05 20:35:49 -05:00
|
|
|
end
|
2012-01-26 15:45:04 -05:00
|
|
|
end
|
|
|
|
end
|