require 'spec_helper' describe Sidekiq::Status::ServerMiddleware do let!(:redis) { Sidekiq.redis { |conn| conn } } let!(:job_id) { SecureRandom.hex(12) } describe "without :expiration parameter" do it "sets working/complete status" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do thread = redis_thread 4, "status_updates", "job_messages_#{job_id}" expect(ConfirmationJob.perform_async 'arg1' => 'val1').to eq(job_id) expect(thread.value).to eq([ job_id, job_id, "while in #perform, status = working", job_id ]) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('complete') expect(Sidekiq::Status::complete?(job_id)).to be_truthy end it "sets failed status" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(capture_status_updates(3) { expect(FailingJob.perform_async).to eq(job_id) }).to eq([job_id]*3) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('failed') expect(Sidekiq::Status::failed?(job_id)).to be_truthy end it "sets failed status when Exception raised" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(capture_status_updates(3) { expect(FailingHardJob.perform_async).to eq(job_id) }).to eq([job_id]*3) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('failed') expect(Sidekiq::Status::failed?(job_id)).to be_truthy end context "when Sidekiq::Status::Worker is not included in the job" do it "should not set a failed status" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(FailingNoStatusJob.perform_async).to eq(job_id) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil end it "should not set any status when Exception raised" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(FailingHardNoStatusJob.perform_async).to eq(job_id) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil end end context "sets interrupted status" do it "on system exit signal" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(capture_status_updates(3) { expect(ExitedJob.perform_async).to eq(job_id) }).to eq([job_id]*3) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('interrupted') expect(Sidekiq::Status::interrupted?(job_id)).to be_truthy end it "on interrupt signal" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(capture_status_updates(3) { expect(InterruptedJob.perform_async).to eq(job_id) }).to eq([job_id]*3) end expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('interrupted') expect(Sidekiq::Status::interrupted?(job_id)).to be_truthy end end it "sets status hash ttl" do allow(SecureRandom).to receive(:hex).once.and_return(job_id) start_server do expect(StubJob.perform_async 'arg1' => 'val1').to eq(job_id) end expect(1..Sidekiq::Status::DEFAULT_EXPIRY).to cover redis.ttl("sidekiq:status:#{job_id}") end end describe "with :expiration parameter" do let(:huge_expiration) { Sidekiq::Status::DEFAULT_EXPIRY * 100 } before do allow(SecureRandom).to receive(:hex).once.and_return(job_id) end it "overwrites default expiry value" do start_server(:expiration => huge_expiration) do StubJob.perform_async 'arg1' => 'val1' end expect((Sidekiq::Status::DEFAULT_EXPIRY-1)..huge_expiration).to cover redis.ttl("sidekiq:status:#{job_id}") end it "can be overwritten by worker expiration method" do overwritten_expiration = huge_expiration * 100 allow_any_instance_of(StubJob).to receive(:expiration).and_return(overwritten_expiration) start_server(:expiration => huge_expiration) do StubJob.perform_async 'arg1' => 'val1' end expect((huge_expiration+1)..overwritten_expiration).to cover redis.ttl("sidekiq:status:#{job_id}") end end end