Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nest exception stub within job class and cleanup let! precedence to fix flakey JRuby tests #254

Merged
merged 2 commits into from May 18, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 27 additions & 26 deletions spec/lib/good_job/job_spec.rb
@@ -1,22 +1,20 @@
require 'rails_helper'

RSpec.describe GoodJob::Job do
let(:job) { described_class.create! }

before do
stub_const "RUN_JOBS", Concurrent::Array.new
stub_const 'ExpectedError', Class.new(StandardError)
stub_const 'ExampleJob', (Class.new(ActiveJob::Base) do
self.queue_name = 'test'
self.priority = 50

def perform(result_value = nil, raise_error: false)
RUN_JOBS << provider_job_id
raise ExpectedError, "Raised expected error" if raise_error
raise ExampleJob::ExpectedError, "Raised expected error" if raise_error

result_value
end
end)
stub_const 'ExampleJob::ExpectedError', Class.new(StandardError)
end

describe '.enqueue' do
Expand Down Expand Up @@ -80,7 +78,7 @@ def perform(result_value = nil, raise_error: false)

expect(result).to be_a GoodJob::ExecutionResult
expect(errored_result.value).to eq nil
expect(errored_result.unhandled_error).to be_an ExpectedError
expect(errored_result.unhandled_error).to be_an ExampleJob::ExpectedError
end
end

Expand Down Expand Up @@ -161,23 +159,25 @@ def perform(result_value = nil, raise_error: false)
end

describe '#executable?' do
let(:good_job) { described_class.create! }

it 'is true when locked' do
job.with_advisory_lock do
expect(job.executable?).to eq true
good_job.with_advisory_lock do
expect(good_job.executable?).to eq true
end
end

it 'is false when job no longer exists' do
job.with_advisory_lock do
job.destroy!
expect(job.executable?).to eq false
good_job.with_advisory_lock do
good_job.destroy!
expect(good_job.executable?).to eq false
end
end

it 'is false when the job has finished' do
job.with_advisory_lock do
job.update! finished_at: Time.current
expect(job.executable?).to eq false
good_job.with_advisory_lock do
good_job.update! finished_at: Time.current
expect(good_job.executable?).to eq false
end
end
end
Expand All @@ -196,22 +196,23 @@ def perform(result_value = nil, raise_error: false)

context 'when there is an error' do
let(:active_job) { ExampleJob.new("whoops", raise_error: true) }
let!(:good_job) { described_class.enqueue(active_job) }

it 'returns the error' do
result = good_job.perform

expect(result.value).to eq nil
expect(result.unhandled_error).to be_an_instance_of ExpectedError
expect(result.unhandled_error).to be_an_instance_of ExampleJob::ExpectedError
end

context 'when there is an retry handler with exhausted attempts' do
before do
ExampleJob.retry_on(ExpectedError, attempts: 1)
ExampleJob.retry_on(ExampleJob::ExpectedError, attempts: 1)

original_attr_readonly = described_class._attr_readonly
described_class._attr_readonly = Set.new

good_job.serialized_params["exception_executions"] = { "[ExpectedError]" => 1 }
good_job.serialized_params["exception_executions"] = { "[ExampleJob::ExpectedError]" => 1 }
good_job.save!

described_class._attr_readonly = original_attr_readonly
Expand All @@ -220,7 +221,7 @@ def perform(result_value = nil, raise_error: false)
it 'does not modify the good_job serialized params' do
expect do
good_job.perform
end.not_to change { good_job.reload.serialized_params["exception_executions"]["[ExpectedError]"] }
end.not_to change { good_job.reload.serialized_params["exception_executions"]["[ExampleJob::ExpectedError]"] }
end
end

Expand All @@ -243,7 +244,7 @@ def perform(result_value = nil, raise_error: false)
result = good_job.perform

expect(result.value).to eq nil
expect(result.unhandled_error).to be_an_instance_of ExpectedError
expect(result.unhandled_error).to be_an_instance_of ExampleJob::ExpectedError
end

if Gem::Version.new(Rails.version) > Gem::Version.new("6")
Expand All @@ -257,7 +258,7 @@ def perform(result_value = nil, raise_error: false)
result = good_job.perform

expect(result.value).to eq nil
expect(result.handled_error).to be_an_instance_of ExpectedError
expect(result.handled_error).to be_an_instance_of ExampleJob::ExpectedError
end
end

Expand All @@ -270,7 +271,7 @@ def perform(result_value = nil, raise_error: false)
result = good_job.perform

expect(result.value).to eq nil
expect(result.handled_error).to be_an_instance_of ExpectedError
expect(result.handled_error).to be_an_instance_of ExampleJob::ExpectedError
end
end
end
Expand Down Expand Up @@ -315,7 +316,7 @@ def perform(result_value = nil, raise_error: false)
result = good_job.perform

expect(result.value).to be_nil
expect(result.handled_error).to be_a(ExpectedError)
expect(result.handled_error).to be_a(ExampleJob::ExpectedError)
end

it 'destroys the job' do
Expand All @@ -330,7 +331,7 @@ def perform(result_value = nil, raise_error: false)
good_job.perform

expect(good_job.reload).to have_attributes(
error: "ExpectedError: Raised expected error",
error: "ExampleJob::ExpectedError: Raised expected error",
performed_at: within(1.second).of(Time.current),
finished_at: within(1.second).of(Time.current)
)
Expand All @@ -344,7 +345,7 @@ def perform(result_value = nil, raise_error: false)
result = good_job.perform

expect(result.value).to eq nil
expect(result.unhandled_error).to be_a(ExpectedError)
expect(result.unhandled_error).to be_a(ExampleJob::ExpectedError)
end

describe 'GoodJob.reperform_jobs_on_standard_error behavior' do
Expand All @@ -359,7 +360,7 @@ def perform(result_value = nil, raise_error: false)
good_job.perform

expect(good_job.reload).to have_attributes(
error: "ExpectedError: Raised expected error",
error: "ExampleJob::ExpectedError: Raised expected error",
performed_at: within(1.second).of(Time.current),
finished_at: nil
)
Expand Down Expand Up @@ -391,7 +392,7 @@ def perform(result_value = nil, raise_error: false)
good_job.perform

expect(good_job.reload).to have_attributes(
error: "ExpectedError: Raised expected error",
error: "ExampleJob::ExpectedError: Raised expected error",
performed_at: within(1.second).of(Time.current),
finished_at: within(1.second).of(Time.current)
)
Expand All @@ -402,7 +403,7 @@ def perform(result_value = nil, raise_error: false)
good_job.perform

expect(good_job.reload).to have_attributes(
error: "ExpectedError: Raised expected error",
error: "ExampleJob::ExpectedError: Raised expected error",
performed_at: within(1.second).of(Time.current),
finished_at: within(1.second).of(Time.current)
)
Expand Down