diff options
Diffstat (limited to 'activejob')
22 files changed, 473 insertions, 63 deletions
diff --git a/activejob/CHANGELOG.md b/activejob/CHANGELOG.md index 77dfdefc05..0c69a5c663 100644 --- a/activejob/CHANGELOG.md +++ b/activejob/CHANGELOG.md @@ -1,8 +1,5 @@ -* Change logging instrumentation to log errors when a job raises an exception. - - Fixes #26848. - - *Steven Bull* +* Support redis-rb 4.0. + *Jeremy Daer* Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/activejob/CHANGELOG.md) for previous changes. diff --git a/activejob/README.md b/activejob/README.md index 8becac7753..8a9a23929b 100644 --- a/activejob/README.md +++ b/activejob/README.md @@ -108,7 +108,7 @@ Source code can be downloaded as part of the Rails project on GitHub Active Job is released under the MIT license: -* http://www.opensource.org/licenses/MIT +* https://opensource.org/licenses/MIT ## Support diff --git a/activejob/lib/active_job.rb b/activejob/lib/active_job.rb index 56dab66544..1f5bd7b3e9 100644 --- a/activejob/lib/active_job.rb +++ b/activejob/lib/active_job.rb @@ -25,7 +25,7 @@ require "active_support" require "active_support/rails" -require_relative "active_job/version" +require "active_job/version" require "global_id" module ActiveJob diff --git a/activejob/lib/active_job/base.rb b/activejob/lib/active_job/base.rb index 6af41260db..ae112abb2c 100644 --- a/activejob/lib/active_job/base.rb +++ b/activejob/lib/active_job/base.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true -require_relative "core" -require_relative "queue_adapter" -require_relative "queue_name" -require_relative "queue_priority" -require_relative "enqueuing" -require_relative "execution" -require_relative "callbacks" -require_relative "exceptions" -require_relative "logging" -require_relative "translation" +require "active_job/core" +require "active_job/queue_adapter" +require "active_job/queue_name" +require "active_job/queue_priority" +require "active_job/enqueuing" +require "active_job/execution" +require "active_job/callbacks" +require "active_job/exceptions" +require "active_job/logging" +require "active_job/translation" module ActiveJob #:nodoc: # = Active Job diff --git a/activejob/lib/active_job/enqueuing.rb b/activejob/lib/active_job/enqueuing.rb index ad32d3065b..53cb98fc71 100644 --- a/activejob/lib/active_job/enqueuing.rb +++ b/activejob/lib/active_job/enqueuing.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative "arguments" +require "active_job/arguments" module ActiveJob # Provides behavior for enqueuing jobs. @@ -10,7 +10,7 @@ module ActiveJob # Includes the +perform_later+ method for job initialization. module ClassMethods # Push a job onto the queue. The arguments must be legal JSON types - # (string, int, float, nil, true, false, hash or array) or + # (+string+, +int+, +float+, +nil+, +true+, +false+, +hash+ or +array+) or # GlobalID::Identification instances. Arbitrary Ruby objects # are not supported. # diff --git a/activejob/lib/active_job/exceptions.rb b/activejob/lib/active_job/exceptions.rb index dfc74deb1a..8b4a88ba6a 100644 --- a/activejob/lib/active_job/exceptions.rb +++ b/activejob/lib/active_job/exceptions.rb @@ -49,7 +49,7 @@ module ActiveJob retry_job wait: determine_delay(wait), queue: queue, priority: priority else if block_given? - yield self, exception + yield self, error else logger.error "Stopped retrying #{self.class} due to a #{exception}, which reoccurred on #{executions} attempts. The original exception was #{error.cause.inspect}." raise error diff --git a/activejob/lib/active_job/execution.rb b/activejob/lib/active_job/execution.rb index 85e050b489..d75be376ec 100644 --- a/activejob/lib/active_job/execution.rb +++ b/activejob/lib/active_job/execution.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "active_support/rescuable" -require_relative "arguments" +require "active_job/arguments" module ActiveJob module Execution diff --git a/activejob/lib/active_job/queue_adapters/async_adapter.rb b/activejob/lib/active_job/queue_adapters/async_adapter.rb index eec9ae08bb..ebf6f384e3 100644 --- a/activejob/lib/active_job/queue_adapters/async_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/async_adapter.rb @@ -31,7 +31,7 @@ module ActiveJob # jobs. Since jobs share a single thread pool, long-running jobs will block # short-lived jobs. Fine for dev/test; bad for production. class AsyncAdapter - # See {Concurrent::ThreadPoolExecutor}[http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadPoolExecutor.html] for executor options. + # See {Concurrent::ThreadPoolExecutor}[https://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ThreadPoolExecutor.html] for executor options. def initialize(**executor_options) @scheduler = Scheduler.new(**executor_options) end diff --git a/activejob/lib/active_job/queue_adapters/test_adapter.rb b/activejob/lib/active_job/queue_adapters/test_adapter.rb index 43566b433c..885f9ff01c 100644 --- a/activejob/lib/active_job/queue_adapters/test_adapter.rb +++ b/activejob/lib/active_job/queue_adapters/test_adapter.rb @@ -12,7 +12,7 @@ module ActiveJob # # Rails.application.config.active_job.queue_adapter = :test class TestAdapter - attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter) + attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject) attr_writer(:enqueued_jobs, :performed_jobs) # Provides a store of all the enqueued jobs with the TestAdapter so you can check them. @@ -54,7 +54,13 @@ module ActiveJob end def filtered?(job) - filter && !Array(filter).include?(job.class) + if filter + !Array(filter).include?(job.class) + elsif reject + Array(reject).include?(job.class) + else + false + end end end end diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb index 1807521d04..1cd2c40c15 100644 --- a/activejob/lib/active_job/test_helper.rb +++ b/activejob/lib/active_job/test_helper.rb @@ -89,7 +89,7 @@ module ActiveJob # end # end # - # The number of times a specific job is enqueued can be asserted. + # The number of times a specific job was enqueued can be asserted. # # def test_logging_job # assert_enqueued_jobs 1, only: LoggingJob do @@ -98,6 +98,15 @@ module ActiveJob # end # end # + # The number of times a job except specific class was enqueued can be asserted. + # + # def test_logging_job + # assert_enqueued_jobs 1, except: HelloJob do + # LoggingJob.perform_later + # HelloJob.perform_later('jeremy') + # end + # end + # # The number of times a job is enqueued to a specific queue can also be asserted. # # def test_logging_job @@ -106,14 +115,14 @@ module ActiveJob # HelloJob.perform_later('elfassy') # end # end - def assert_enqueued_jobs(number, only: nil, queue: nil) + def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil) if block_given? - original_count = enqueued_jobs_size(only: only, queue: queue) + original_count = enqueued_jobs_size(only: only, except: except, queue: queue) yield - new_count = enqueued_jobs_size(only: only, queue: queue) + new_count = enqueued_jobs_size(only: only, except: except, queue: queue) assert_equal number, new_count - original_count, "#{number} jobs expected, but #{new_count - original_count} were enqueued" else - actual_count = enqueued_jobs_size(only: only, queue: queue) + actual_count = enqueued_jobs_size(only: only, except: except, queue: queue) assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued" end end @@ -142,11 +151,19 @@ module ActiveJob # end # end # + # It can be asserted that no jobs except specific class are enqueued: + # + # def test_no_logging + # assert_no_enqueued_jobs except: HelloJob do + # HelloJob.perform_later('jeremy') + # end + # end + # # Note: This assertion is simply a shortcut for: # # assert_enqueued_jobs 0, &block - def assert_no_enqueued_jobs(only: nil, &block) - assert_enqueued_jobs 0, only: only, &block + def assert_no_enqueued_jobs(only: nil, except: nil, &block) + assert_enqueued_jobs 0, only: only, except: except, &block end # Asserts that the number of performed jobs matches the given number. @@ -191,6 +208,16 @@ module ActiveJob # end # end # + # Also if the :except option is specified, + # then the job(s) except specific class will be performed. + # + # def test_hello_job + # assert_performed_jobs 1, except: LoggingJob do + # HelloJob.perform_later('jeremy') + # LoggingJob.perform_later + # end + # end + # # An array may also be specified, to support testing multiple jobs. # # def test_hello_and_logging_jobs @@ -202,10 +229,10 @@ module ActiveJob # end # end # end - def assert_performed_jobs(number, only: nil) + def assert_performed_jobs(number, only: nil, except: nil) if block_given? original_count = performed_jobs.size - perform_enqueued_jobs(only: only) { yield } + perform_enqueued_jobs(only: only, except: except) { yield } new_count = performed_jobs.size assert_equal number, new_count - original_count, "#{number} jobs expected, but #{new_count - original_count} were performed" @@ -243,11 +270,20 @@ module ActiveJob # end # end # + # Also if the :except option is specified, + # then the job(s) except specific class will not be performed. + # + # def test_no_logging + # assert_no_performed_jobs except: HelloJob do + # HelloJob.perform_later('jeremy') + # end + # end + # # Note: This assertion is simply a shortcut for: # # assert_performed_jobs 0, &block - def assert_no_performed_jobs(only: nil, &block) - assert_performed_jobs 0, only: only, &block + def assert_no_performed_jobs(only: nil, except: nil, &block) + assert_performed_jobs 0, only: only, except: except, &block end # Asserts that the job passed in the block has been enqueued with the given arguments. @@ -317,20 +353,36 @@ module ActiveJob # end # assert_performed_jobs 1 # end - def perform_enqueued_jobs(only: nil) + # + # Also if the +:except+ option is specified, + # then the job(s) except specific class will be performed. + # + # def test_perform_enqueued_jobs_with_except + # perform_enqueued_jobs(except: HelloJob) do + # MyJob.perform_later(1, 2, 3) # will be performed + # HelloJob.perform_later(1, 2, 3) # will not be performed + # end + # assert_performed_jobs 1 + # end + # + def perform_enqueued_jobs(only: nil, except: nil) + validate_option(only: only, except: except) old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs old_filter = queue_adapter.filter + old_reject = queue_adapter.reject begin queue_adapter.perform_enqueued_jobs = true queue_adapter.perform_enqueued_at_jobs = true queue_adapter.filter = only + queue_adapter.reject = except yield ensure queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs queue_adapter.filter = old_filter + queue_adapter.reject = old_reject end end @@ -352,11 +404,14 @@ module ActiveJob performed_jobs.clear end - def enqueued_jobs_size(only: nil, queue: nil) + def enqueued_jobs_size(only: nil, except: nil, queue: nil) + validate_option(only: only, except: except) enqueued_jobs.count do |job| job_class = job.fetch(:job) if only next false unless Array(only).include?(job_class) + elsif except + next false if Array(except).include?(job_class) end if queue next false unless queue.to_s == job.fetch(:queue, job_class.queue_name) @@ -385,5 +440,9 @@ module ActiveJob klass.singleton_class.public_instance_methods(false).include?(:_queue_adapter) end end + + def validate_option(only: nil, except: nil) + raise ArgumentError, "Cannot specify both `:only` and `:except` options." if only && except + end end end diff --git a/activejob/lib/rails/generators/job/templates/application_job.rb b/activejob/lib/rails/generators/job/templates/application_job.rb.tt index f93745a31a..f93745a31a 100644 --- a/activejob/lib/rails/generators/job/templates/application_job.rb +++ b/activejob/lib/rails/generators/job/templates/application_job.rb.tt diff --git a/activejob/lib/rails/generators/job/templates/job.rb b/activejob/lib/rails/generators/job/templates/job.rb.tt index 4ad2914a45..4ad2914a45 100644 --- a/activejob/lib/rails/generators/job/templates/job.rb +++ b/activejob/lib/rails/generators/job/templates/job.rb.tt diff --git a/activejob/test/cases/exceptions_test.rb b/activejob/test/cases/exceptions_test.rb index 7a3c372143..22fed0a808 100644 --- a/activejob/test/cases/exceptions_test.rb +++ b/activejob/test/cases/exceptions_test.rb @@ -61,7 +61,7 @@ class ExceptionsTest < ActiveJob::TestCase test "custom handling of job that exceeds retry attempts" do perform_enqueued_jobs do RetryJob.perform_later "CustomCatchError", 6 - assert_equal "Dealt with a job that failed to retry in a custom way after 6 attempts", JobBuffer.last_value + assert_equal "Dealt with a job that failed to retry in a custom way after 6 attempts. Message: CustomCatchError", JobBuffer.last_value end end diff --git a/activejob/test/cases/test_helper_test.rb b/activejob/test/cases/test_helper_test.rb index 2e1d8cf81d..66bcd8f3a0 100644 --- a/activejob/test/cases/test_helper_test.rb +++ b/activejob/test/cases/test_helper_test.rb @@ -108,8 +108,31 @@ class EnqueuedJobsTest < ActiveJob::TestCase assert_enqueued_jobs 1, only: HelloJob do HelloJob.perform_later("jeremy") LoggingJob.perform_later + LoggingJob.perform_later + end + end + end + + def test_assert_enqueued_jobs_with_except_option + assert_nothing_raised do + assert_enqueued_jobs 1, except: LoggingJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + LoggingJob.perform_later + end + end + end + + def test_assert_enqueued_jobs_with_only_and_except_option + error = assert_raise ArgumentError do + assert_enqueued_jobs 1, only: HelloJob, except: HelloJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + LoggingJob.perform_later end end + + assert_match(/`:only` and `:except`/, error.message) end def test_assert_enqueued_jobs_with_only_and_queue_option @@ -122,6 +145,28 @@ class EnqueuedJobsTest < ActiveJob::TestCase end end + def test_assert_enqueued_jobs_with_except_and_queue_option + assert_nothing_raised do + assert_enqueued_jobs 1, except: LoggingJob, queue: :some_queue do + HelloJob.set(queue: :some_queue).perform_later + HelloJob.set(queue: :other_queue).perform_later + LoggingJob.perform_later + end + end + end + + def test_assert_enqueued_jobs_with_only_and_except_and_queue_option + error = assert_raise ArgumentError do + assert_enqueued_jobs 1, only: HelloJob, except: HelloJob, queue: :some_queue do + HelloJob.set(queue: :some_queue).perform_later + HelloJob.set(queue: :other_queue).perform_later + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_enqueued_jobs_with_queue_option assert_nothing_raised do assert_enqueued_jobs 2, queue: :default do @@ -143,6 +188,26 @@ class EnqueuedJobsTest < ActiveJob::TestCase assert_match(/1 .* but 0/, error.message) end + def test_assert_enqueued_jobs_with_except_option_and_none_sent + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_enqueued_jobs 1, except: LoggingJob do + LoggingJob.perform_later + end + end + + assert_match(/1 .* but 0/, error.message) + end + + def test_assert_enqueued_jobs_with_only_and_except_option_and_none_sent + error = assert_raise ArgumentError do + assert_enqueued_jobs 1, only: HelloJob, except: HelloJob do + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_enqueued_jobs_with_only_option_and_too_few_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_enqueued_jobs 5, only: HelloJob do @@ -154,6 +219,28 @@ class EnqueuedJobsTest < ActiveJob::TestCase assert_match(/5 .* but 1/, error.message) end + def test_assert_enqueued_jobs_with_except_option_and_too_few_sent + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_enqueued_jobs 5, except: LoggingJob do + HelloJob.perform_later("jeremy") + 4.times { LoggingJob.perform_later } + end + end + + assert_match(/5 .* but 1/, error.message) + end + + def test_assert_enqueued_jobs_with_only_and_except_option_and_too_few_sent + error = assert_raise ArgumentError do + assert_enqueued_jobs 5, only: HelloJob, except: HelloJob do + HelloJob.perform_later("jeremy") + 4.times { LoggingJob.perform_later } + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_enqueued_jobs_with_only_option_and_too_many_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_enqueued_jobs 1, only: HelloJob do @@ -164,6 +251,26 @@ class EnqueuedJobsTest < ActiveJob::TestCase assert_match(/1 .* but 2/, error.message) end + def test_assert_enqueued_jobs_with_except_option_and_too_many_sent + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_enqueued_jobs 1, except: LoggingJob do + 2.times { HelloJob.perform_later("jeremy") } + end + end + + assert_match(/1 .* but 2/, error.message) + end + + def test_assert_enqueued_jobs_with_only_and_except_option_and_too_many_sent + error = assert_raise ArgumentError do + assert_enqueued_jobs 1, only: HelloJob, except: HelloJob do + 2.times { HelloJob.perform_later("jeremy") } + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_enqueued_jobs_with_only_option_as_array assert_nothing_raised do assert_enqueued_jobs 2, only: [HelloJob, LoggingJob] do @@ -174,6 +281,28 @@ class EnqueuedJobsTest < ActiveJob::TestCase end end + def test_assert_enqueued_jobs_with_except_option_as_array + assert_nothing_raised do + assert_enqueued_jobs 1, except: [HelloJob, LoggingJob] do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later("stewie") + RescueJob.perform_later("david") + end + end + end + + def test_assert_enqueued_jobs_with_only_and_except_option_as_array + error = assert_raise ArgumentError do + assert_enqueued_jobs 2, only: [HelloJob, LoggingJob], except: [HelloJob, LoggingJob] do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later("stewie") + RescueJob.perform_later("david") + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_no_enqueued_jobs_with_only_option assert_nothing_raised do assert_no_enqueued_jobs only: HelloJob do @@ -182,6 +311,24 @@ class EnqueuedJobsTest < ActiveJob::TestCase end end + def test_assert_no_enqueued_jobs_with_except_option + assert_nothing_raised do + assert_no_enqueued_jobs except: LoggingJob do + LoggingJob.perform_later + end + end + end + + def test_assert_no_enqueued_jobs_with_only_and_except_option + error = assert_raise ArgumentError do + assert_no_enqueued_jobs only: HelloJob, except: HelloJob do + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_no_enqueued_jobs_with_only_option_failure error = assert_raise ActiveSupport::TestCase::Assertion do assert_no_enqueued_jobs only: HelloJob do @@ -193,6 +340,28 @@ class EnqueuedJobsTest < ActiveJob::TestCase assert_match(/0 .* but 1/, error.message) end + def test_assert_no_enqueued_jobs_with_except_option_failure + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_no_enqueued_jobs except: LoggingJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + end + end + + assert_match(/0 .* but 1/, error.message) + end + + def test_assert_no_enqueued_jobs_with_only_and_except_option_failure + error = assert_raise ArgumentError do + assert_no_enqueued_jobs only: HelloJob, except: HelloJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_no_enqueued_jobs_with_only_option_as_array assert_nothing_raised do assert_no_enqueued_jobs only: [HelloJob, RescueJob] do @@ -201,6 +370,25 @@ class EnqueuedJobsTest < ActiveJob::TestCase end end + def test_assert_no_enqueued_jobs_with_except_option_as_array + assert_nothing_raised do + assert_no_enqueued_jobs except: [HelloJob, RescueJob] do + HelloJob.perform_later + RescueJob.perform_later + end + end + end + + def test_assert_no_enqueued_jobs_with_only_and_except_option_as_array + error = assert_raise ArgumentError do + assert_no_enqueued_jobs only: [HelloJob, RescueJob], except: [HelloJob, RescueJob] do + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_enqueued_job assert_enqueued_with(job: LoggingJob, queue: "default") do LoggingJob.set(wait_until: Date.tomorrow.noon).perform_later @@ -286,6 +474,14 @@ class PerformedJobsTest < ActiveJob::TestCase assert_nil queue_adapter.filter end + def test_performed_enqueue_jobs_with_except_option_doesnt_leak_outside_the_block + assert_nil queue_adapter.reject + perform_enqueued_jobs except: HelloJob do + assert_equal HelloJob, queue_adapter.reject + end + assert_nil queue_adapter.reject + end + def test_assert_performed_jobs assert_nothing_raised do assert_performed_jobs 1 do @@ -391,6 +587,26 @@ class PerformedJobsTest < ActiveJob::TestCase end end + def test_assert_performed_jobs_with_except_option + assert_nothing_raised do + assert_performed_jobs 1, except: LoggingJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + end + end + end + + def test_assert_performed_jobs_with_only_and_except_option + error = assert_raise ArgumentError do + assert_performed_jobs 1, only: HelloJob, except: HelloJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_performed_jobs_with_only_option_as_array assert_nothing_raised do assert_performed_jobs 2, only: [HelloJob, LoggingJob] do @@ -401,6 +617,28 @@ class PerformedJobsTest < ActiveJob::TestCase end end + def test_assert_performed_jobs_with_except_option_as_array + assert_nothing_raised do + assert_performed_jobs 1, except: [LoggingJob, RescueJob] do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later("stewie") + RescueJob.perform_later("david") + end + end + end + + def test_assert_performed_jobs_with_only_and_except_option_as_array + error = assert_raise ArgumentError do + assert_performed_jobs 2, only: [HelloJob, LoggingJob], except: [HelloJob, LoggingJob] do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later("stewie") + RescueJob.perform_later("david") + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_performed_jobs_with_only_option_and_none_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_performed_jobs 1, only: HelloJob do @@ -411,6 +649,26 @@ class PerformedJobsTest < ActiveJob::TestCase assert_match(/1 .* but 0/, error.message) end + def test_assert_performed_jobs_with_except_option_and_none_sent + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_performed_jobs 1, except: LoggingJob do + LoggingJob.perform_later + end + end + + assert_match(/1 .* but 0/, error.message) + end + + def test_assert_performed_jobs_with_only_and_except_option_and_none_sent + error = assert_raise ArgumentError do + assert_performed_jobs 1, only: HelloJob, except: HelloJob do + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_performed_jobs_with_only_option_and_too_few_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_performed_jobs 5, only: HelloJob do @@ -422,6 +680,28 @@ class PerformedJobsTest < ActiveJob::TestCase assert_match(/5 .* but 1/, error.message) end + def test_assert_performed_jobs_with_except_option_and_too_few_sent + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_performed_jobs 5, except: LoggingJob do + HelloJob.perform_later("jeremy") + 4.times { LoggingJob.perform_later } + end + end + + assert_match(/5 .* but 1/, error.message) + end + + def test_assert_performed_jobs_with_only_and_except_option_and_too_few_sent + error = assert_raise ArgumentError do + assert_performed_jobs 5, only: HelloJob, except: HelloJob do + HelloJob.perform_later("jeremy") + 4.times { LoggingJob.perform_later } + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_performed_jobs_with_only_option_and_too_many_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_performed_jobs 1, only: HelloJob do @@ -432,6 +712,26 @@ class PerformedJobsTest < ActiveJob::TestCase assert_match(/1 .* but 2/, error.message) end + def test_assert_performed_jobs_with_except_option_and_too_many_sent + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_performed_jobs 1, except: LoggingJob do + 2.times { HelloJob.perform_later("jeremy") } + end + end + + assert_match(/1 .* but 2/, error.message) + end + + def test_assert_performed_jobs_with_only_and_except_option_and_too_many_sent + error = assert_raise ArgumentError do + assert_performed_jobs 1, only: HelloJob, except: HelloJob do + 2.times { HelloJob.perform_later("jeremy") } + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_no_performed_jobs_with_only_option assert_nothing_raised do assert_no_performed_jobs only: HelloJob do @@ -440,6 +740,24 @@ class PerformedJobsTest < ActiveJob::TestCase end end + def test_assert_no_performed_jobs_with_except_option + assert_nothing_raised do + assert_no_performed_jobs except: LoggingJob do + LoggingJob.perform_later + end + end + end + + def test_assert_no_performed_jobs_with_only_and_except_option + error = assert_raise ArgumentError do + assert_no_performed_jobs only: HelloJob, except: HelloJob do + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_no_performed_jobs_with_only_option_as_array assert_nothing_raised do assert_no_performed_jobs only: [HelloJob, RescueJob] do @@ -448,6 +766,25 @@ class PerformedJobsTest < ActiveJob::TestCase end end + def test_assert_no_performed_jobs_with_except_option_as_array + assert_nothing_raised do + assert_no_performed_jobs except: [HelloJob, RescueJob] do + HelloJob.perform_later + RescueJob.perform_later + end + end + end + + def test_assert_no_performed_jobs_with_only_and_except_option_as_array + error = assert_raise ArgumentError do + assert_no_performed_jobs only: [HelloJob, RescueJob], except: [HelloJob, RescueJob] do + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_no_performed_jobs_with_only_option_failure error = assert_raise ActiveSupport::TestCase::Assertion do assert_no_performed_jobs only: HelloJob do @@ -459,6 +796,28 @@ class PerformedJobsTest < ActiveJob::TestCase assert_match(/0 .* but 1/, error.message) end + def test_assert_no_performed_jobs_with_except_option_failure + error = assert_raise ActiveSupport::TestCase::Assertion do + assert_no_performed_jobs except: LoggingJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + end + end + + assert_match(/0 .* but 1/, error.message) + end + + def test_assert_no_performed_jobs_with_only_and_except_option_failure + error = assert_raise ArgumentError do + assert_no_performed_jobs only: HelloJob, except: HelloJob do + HelloJob.perform_later("jeremy") + LoggingJob.perform_later + end + end + + assert_match(/`:only` and `:except`/, error.message) + end + def test_assert_performed_job assert_performed_with(job: NestedJob, queue: "default") do NestedJob.perform_later diff --git a/activejob/test/jobs/retry_job.rb b/activejob/test/jobs/retry_job.rb index a12d09779b..9aa99d9a21 100644 --- a/activejob/test/jobs/retry_job.rb +++ b/activejob/test/jobs/retry_job.rb @@ -17,7 +17,7 @@ class RetryJob < ActiveJob::Base retry_on ShortWaitTenAttemptsError, wait: 1.second, attempts: 10 retry_on ExponentialWaitTenAttemptsError, wait: :exponentially_longer, attempts: 10 retry_on CustomWaitTenAttemptsError, wait: ->(executions) { executions * 2 }, attempts: 10 - retry_on(CustomCatchError) { |job, exception| JobBuffer.add("Dealt with a job that failed to retry in a custom way after #{job.arguments.second} attempts") } + retry_on(CustomCatchError) { |job, exception| JobBuffer.add("Dealt with a job that failed to retry in a custom way after #{job.arguments.second} attempts. Message: #{exception.message}") } discard_on DiscardableError def perform(raising, attempts) diff --git a/activejob/test/support/delayed_job/delayed/backend/test.rb b/activejob/test/support/delayed_job/delayed/backend/test.rb index 4721c1cc17..9280a37a5c 100644 --- a/activejob/test/support/delayed_job/delayed/backend/test.rb +++ b/activejob/test/support/delayed_job/delayed/backend/test.rb @@ -77,7 +77,7 @@ module Delayed self.locked_by = worker end - return true + true end def self.db_time_now diff --git a/activejob/test/support/integration/adapters/delayed_job.rb b/activejob/test/support/integration/adapters/delayed_job.rb index ae5de78b60..fc9bae47fa 100644 --- a/activejob/test/support/integration/adapters/delayed_job.rb +++ b/activejob/test/support/integration/adapters/delayed_job.rb @@ -18,5 +18,6 @@ module DelayedJobJobsManager def stop_workers @worker.stop + @thread.join end end diff --git a/activejob/test/support/integration/adapters/resque.rb b/activejob/test/support/integration/adapters/resque.rb index 484b476567..2ed8302277 100644 --- a/activejob/test/support/integration/adapters/resque.rb +++ b/activejob/test/support/integration/adapters/resque.rb @@ -3,11 +3,12 @@ module ResqueJobsManager def setup ActiveJob::Base.queue_adapter = :resque - Resque.redis = Redis::Namespace.new "active_jobs_int_test", redis: Redis.connect(url: "redis://:password@127.0.0.1:6379/12", thread_safe: true) + Resque.redis = Redis::Namespace.new "active_jobs_int_test", redis: Redis.new(url: "redis://127.0.0.1:6379/12", thread_safe: true) Resque.logger = Rails.logger unless can_run? puts "Cannot run integration tests for resque. To be able to run integration tests for resque you need to install and start redis.\n" - exit + status = ENV["CI"] ? false : true + exit status end end @@ -41,11 +42,8 @@ module ResqueJobsManager end def can_run? - begin - Resque.redis.client.connect - rescue - return false - end - true + Resque.redis.ping == "PONG" + rescue + false end end diff --git a/activejob/test/support/integration/adapters/sidekiq.rb b/activejob/test/support/integration/adapters/sidekiq.rb index b63d16d248..4b01a81ec5 100644 --- a/activejob/test/support/integration/adapters/sidekiq.rb +++ b/activejob/test/support/integration/adapters/sidekiq.rb @@ -5,20 +5,13 @@ require "sidekiq/api" require "sidekiq/testing" Sidekiq::Testing.disable! -Sidekiq.configure_server do |config| - config.redis = { url: "redis://:password@127.0.0.1:6379/12" } -end - -Sidekiq.configure_client do |config| - config.redis = { url: "redis://:password@127.0.0.1:6379/12" } -end - module SidekiqJobsManager def setup ActiveJob::Base.queue_adapter = :sidekiq unless can_run? puts "Cannot run integration tests for sidekiq. To be able to run integration tests for sidekiq you need to install and start redis.\n" - exit + status = ENV["CI"] ? false : true + exit status end end @@ -38,7 +31,7 @@ module SidekiqJobsManager # Sidekiq is not warning-clean :( $VERBOSE = false - $stdin.reopen("/dev/null") + $stdin.reopen(File::NULL) $stdout.sync = true $stderr.sync = true diff --git a/activejob/test/support/integration/dummy_app_template.rb b/activejob/test/support/integration/dummy_app_template.rb index ac382bd1b7..7ea78c3350 100644 --- a/activejob/test/support/integration/dummy_app_template.rb +++ b/activejob/test/support/integration/dummy_app_template.rb @@ -4,8 +4,6 @@ if ENV["AJ_ADAPTER"] == "delayed_job" generate "delayed_job:active_record", "--quiet" end -rails_command("db:migrate") - initializer "activejob.rb", <<-CODE require "#{File.expand_path("jobs_manager.rb", __dir__)}" JobsManager.current_manager.setup diff --git a/activejob/test/support/integration/helper.rb b/activejob/test/support/integration/helper.rb index a058da141f..a02d874e2e 100644 --- a/activejob/test/support/integration/helper.rb +++ b/activejob/test/support/integration/helper.rb @@ -18,6 +18,7 @@ Rails::Generators::AppGenerator.start args require "#{dummy_app_path}/config/environment.rb" ActiveRecord::Migrator.migrations_paths = [ Rails.root.join("db/migrate").to_s ] +ActiveRecord::Tasks::DatabaseTasks.migrate require "rails/test_help" Rails.backtrace_cleaner.remove_silencers! diff --git a/activejob/test/support/integration/test_case_helpers.rb b/activejob/test/support/integration/test_case_helpers.rb index 9629876a6d..f02a32a38e 100644 --- a/activejob/test/support/integration/test_case_helpers.rb +++ b/activejob/test/support/integration/test_case_helpers.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "active_support/core_ext/string/inflections" require "support/integration/jobs_manager" module TestCaseHelpers @@ -30,8 +29,7 @@ module TestCaseHelpers end def adapter_is?(*adapter_class_symbols) - adapter = ActiveJob::Base.queue_adapter.class.name.demodulize.chomp("Adapter").underscore - adapter_class_symbols.map(&:to_s).include? adapter + adapter_class_symbols.map(&:to_s).include? ActiveJob::Base.queue_adapter_name end def wait_for_jobs_to_finish_for(seconds = 60) |