diff --git a/spec/sidekiq/rescue/config_spec.rb b/spec/sidekiq/rescue/config_spec.rb new file mode 100644 index 0000000..1152ea0 --- /dev/null +++ b/spec/sidekiq/rescue/config_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +RSpec.describe Sidekiq::Rescue::Config do + describe "#delay=" do + it "sets the delay value" do + config = described_class.new + config.delay = 30 + expect(config.delay).to eq(30) + end + + it "raises an ArgumentError if delay is not an Integer or Float" do + config = described_class.new + expect { config.delay = "invalid" }.to raise_error(ArgumentError) + end + end + + describe "#limit=" do + it "sets the limit value" do + config = described_class.new + config.limit = 5 + expect(config.limit).to eq(5) + end + + it "raises an ArgumentError if limit is not an Integer" do + config = described_class.new + expect { config.limit = "invalid" }.to raise_error(ArgumentError) + end + end + + describe "#logger=" do + it "sets the logger value" do + config = described_class.new + logger = Logger.new(nil) + config.logger = logger + expect(config.logger).to eq(logger) + end + + it "raises an ArgumentError if logger is not a Logger" do + config = described_class.new + expect { config.logger = "invalid" }.to raise_error(ArgumentError) + end + end +end diff --git a/spec/sidekiq/rescue/integration_spec.rb b/spec/sidekiq/rescue/integration_spec.rb new file mode 100644 index 0000000..1c99548 --- /dev/null +++ b/spec/sidekiq/rescue/integration_spec.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +RSpec.describe "Sidekiq::Rescue", :integration do + subject(:perform_async) do + job_class.perform_async(*args) + job_class.perform_one + end + + let(:args) { [1, 2, 3] } + let(:last_job) { job_class.jobs.last } + + context "with expected error" do + let(:job_class) { WithTestErrorJob } + + it "rescues the expected error" do + expect { perform_async }.not_to raise_error + expect(job_class.jobs.size).to eq(1) + end + + it "reschedules the job with correct arguments" do + perform_async + scheduled_job = last_job + expect(scheduled_job["args"]).to eq(args) + expect(scheduled_job["sidekiq_rescue_counter"]).to eq(1) + end + + it "reschedules the job with correct arguments and delay" do + perform_async + + delay = job_class.sidekiq_rescue_options[:delay] + expect(last_job["at"]).to be_within(10).of(Time.now.to_f + delay) + end + + it "increments the counter" do + perform_async + + expect(last_job["sidekiq_rescue_counter"]).to eq(1) + end + + it "raises an error if the counter is greater than the limit" do + limit = job_class.sidekiq_rescue_options[:limit] + + job_class.perform_async(*args) + limit.times { job_class.perform_one } + + expect { perform_async }.to raise_error(TestError, "TestError") + end + end + + context "with unexpected error" do + let(:job_class) { WithUnexpectedErrorJob } + + it "does not rescue the unexpected error" do + expect { perform_async }.to raise_error(UnexpectedError) + expect(job_class.jobs.size).to eq(0) + end + end + + context "with multiple errors" do + let(:job_class) { WithMultipleErrorsJob } + + it "rescues the expected error" do + expect { perform_async }.not_to raise_error + + expect(job_class.jobs.size).to eq(1) + end + end + + context "with child job" do + let(:job_class) { ChildJobWithExpectedError } + + it "rescues the expected error" do + expect { perform_async }.not_to raise_error + + expect(job_class.jobs.size).to eq(1) + end + end + + context "without rescue" do + let(:job_class) { WithTestErrorAndWithoutRescue } + + it "does not rescue the error" do + expect { perform_async }.to raise_error(TestError) + expect(job_class.jobs.size).to eq(0) + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 75be57e..f15751e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true require "sidekiq_rescue" +require "sidekiq/testing" + Dir[File.join(__dir__, "support/**/*.rb")].sort.each { |f| require f } RSpec.configure do |config| @@ -14,6 +16,18 @@ c.syntax = :expect end + config.before(:all) do + Sidekiq::Testing.fake! + + Sidekiq::Testing.server_middleware do |chain| + chain.add Sidekiq::Rescue::ServerMiddleware + end + end + + config.before(:each, :integration) do + Sidekiq::Queues.clear_all + end + if ENV["LOG"].nil? if defined?(Sidekiq::MAJOR) && Sidekiq::MAJOR >= 7 Sidekiq.default_configuration.logger = nil diff --git a/spec/support/jobs.rb b/spec/support/jobs.rb index 462883a..443d7b0 100644 --- a/spec/support/jobs.rb +++ b/spec/support/jobs.rb @@ -1,20 +1,11 @@ # frozen_string_literal: true -class WithTestErrorJob +class BaseJob include Sidekiq::Job include Sidekiq::Rescue::DSL - - sidekiq_rescue TestError - - def perform(*) - raise TestError - end end -class WithTestErrorWithoutResqueJob - include Sidekiq::Job - include Sidekiq::Rescue::DSL - +class WithTestErrorJob < BaseJob sidekiq_rescue TestError def perform(*) @@ -22,32 +13,13 @@ def perform(*) end end -class WithParentErrorJob - include Sidekiq::Job - include Sidekiq::Rescue::DSL - - sidekiq_rescue ParentError - +class WithTestErrorAndWithoutRescue < BaseJob def perform(*) - raise ParentError - end -end - -class WithChildErrorJob - include Sidekiq::Job - include Sidekiq::Rescue::DSL - - sidekiq_rescue ChildError - - def perform(*) - raise ChildError + raise TestError end end -class WithAllErrorJob - include Sidekiq::Job - include Sidekiq::Rescue::DSL - +class WithMultipleErrorsJob < BaseJob sidekiq_rescue [TestError, ParentError, ChildError] def perform(*) @@ -55,13 +27,12 @@ def perform(*) end end -class WithUnexpectedErrorJob - include Sidekiq::Job - include Sidekiq::Rescue::DSL - +class WithUnexpectedErrorJob < BaseJob sidekiq_rescue TestError def perform(*) raise UnexpectedError end end + +ChildJobWithExpectedError = Class.new(WithTestErrorJob)