This commit is contained in:
Rafael Mendonça França 2022-01-06 16:53:27 +00:00
commit 6fb54c00e4
No known key found for this signature in database
GPG Key ID: FC23B6D0F1EEE948
3 changed files with 41 additions and 3 deletions

View File

@ -1,3 +1,32 @@
* Allow testing `discard_on/retry_on ActiveJob::DeserializationError`
Previously in `perform_enqueued_jobs`, `deserialize_arguments_if_needed`
was called before calling `perform_now`. When a record no longer exists
and is serialized using GlobalID this led to raising
an `ActiveJob::DeserializationError` before reaching `perform_now` call.
This behaviour makes difficult testing the job `discard_on/retry_on` logic.
Now `deserialize_arguments_if_needed` call is postponed to when `perform_now`
is called.
Example:
```ruby
class UpdateUserJob < ActiveJob::Base
discard_on ActiveJob::DeserializationError
def perform(user)
# ...
end
end
# In the test
User.destroy_all
assert_nothing_raised do
perform_enqueued_jobs only: UpdateUserJob
end
```
*Jacopo Beschi*
Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/activejob/CHANGELOG.md) for previous changes.

View File

@ -688,7 +688,7 @@ module ActiveJob
enqueued_jobs_with(only: only, except: except, queue: queue, at: at) do |payload|
queue_adapter.enqueued_jobs.delete(payload)
queue_adapter.performed_jobs << payload
instantiate_job(payload).perform_now
instantiate_job(payload, skip_deserialize_arguments: true).perform_now
end.count
end
@ -708,10 +708,10 @@ module ActiveJob
end
end
def instantiate_job(payload)
def instantiate_job(payload, skip_deserialize_arguments: false)
job = payload[:job].deserialize(payload)
job.scheduled_at = Time.at(payload[:at]) if payload.key?(:at)
job.send(:deserialize_arguments_if_needed)
job.send(:deserialize_arguments_if_needed) unless skip_deserialize_arguments
job
end

View File

@ -9,6 +9,7 @@ require "jobs/logging_job"
require "jobs/nested_job"
require "jobs/rescue_job"
require "jobs/raising_job"
require "jobs/retry_job"
require "jobs/inherited_job"
require "jobs/multiple_kwargs_job"
require "models/person"
@ -2027,6 +2028,14 @@ class PerformedJobsTest < ActiveJob::TestCase
assert_equal 2, queue_adapter.performed_jobs.count
end
test "perform_enqueued_jobs doesn't raise if discard_on ActiveJob::DeserializationError" do
RetryJob.perform_later Person.new(404), 1
assert_nothing_raised do
perform_enqueued_jobs(only: RetryJob)
end
end
test "TestAdapter respect max attempts" do
perform_enqueued_jobs(only: RaisingJob) do
assert_raises(RaisingJob::MyError) do