diff options
Diffstat (limited to 'railties/test/application/queue_test.rb')
-rw-r--r-- | railties/test/application/queue_test.rb | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/railties/test/application/queue_test.rb b/railties/test/application/queue_test.rb new file mode 100644 index 0000000000..e67c6cc371 --- /dev/null +++ b/railties/test/application/queue_test.rb @@ -0,0 +1,190 @@ +require 'isolation/abstract_unit' + +module ApplicationTests + class QueueTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + build_app + boot_rails + end + + def teardown + teardown_app + end + + def app_const + @app_const ||= Class.new(Rails::Application) + end + + test "the queue is a TestQueue in test mode" do + app("test") + assert_kind_of ActiveSupport::TestQueue, Rails.application.queue[:default] + assert_kind_of ActiveSupport::TestQueue, Rails.queue[:default] + end + + test "the queue is a SynchronousQueue in development mode" do + app("development") + assert_kind_of ActiveSupport::SynchronousQueue, Rails.application.queue[:default] + assert_kind_of ActiveSupport::SynchronousQueue, Rails.queue[:default] + end + + class ThreadTrackingJob + def initialize + @origin = Thread.current.object_id + end + + def run + @target = Thread.current.object_id + end + + def ran_in_different_thread? + @origin != @target + end + + def ran? + @target + end + end + + test "in development mode, an enqueued job will be processed in the same thread" do + app("development") + + job = ThreadTrackingJob.new + Rails.queue.push job + sleep 0.1 + + assert job.ran?, "Expected job to be run" + refute job.ran_in_different_thread?, "Expected job to run in the same thread" + end + + test "in test mode, explicitly draining the queue will process it in the same thread" do + app("test") + + Rails.queue.push ThreadTrackingJob.new + job = Rails.queue.jobs.last + Rails.queue.drain + + assert job.ran?, "Expected job to be run" + refute job.ran_in_different_thread?, "Expected job to run in the same thread" + end + + class IdentifiableJob + def initialize(id) + @id = id + end + + def ==(other) + other.same_id?(@id) + end + + def same_id?(other_id) + other_id == @id + end + + def run + end + end + + test "in test mode, the queue can be observed" do + app("test") + + jobs = (1..10).map do |id| + IdentifiableJob.new(id) + end + + jobs.each do |job| + Rails.queue.push job + end + + assert_equal jobs, Rails.queue.jobs + end + + test "in test mode, adding an unmarshallable job will raise an exception" do + app("test") + anonymous_class_instance = Struct.new(:run).new + assert_raises TypeError do + Rails.queue.push anonymous_class_instance + end + end + + test "attempting to marshal a queue will raise an exception" do + app("test") + assert_raises TypeError do + Marshal.dump Rails.queue + end + end + + test "attempting to add a reference to itself to the queue will raise an exception" do + app("test") + job = {reference: Rails.queue} + assert_raises TypeError do + Rails.queue.push job + end + end + + def setup_custom_queue + add_to_env_config "production", <<-RUBY + require "my_queue" + config.queue = MyQueue + RUBY + + app_file "lib/my_queue.rb", <<-RUBY + class MyQueue + def push(job) + job.run + end + end + RUBY + + app("production") + end + + test "a custom queue implementation can be provided" do + setup_custom_queue + + assert_kind_of MyQueue, Rails.queue[:default] + + job = Struct.new(:id, :ran) do + def run + self.ran = true + end + end + + job1 = job.new(1) + Rails.queue.push job1 + + assert_equal true, job1.ran + end + + test "a custom consumer implementation can be provided" do + add_to_env_config "production", <<-RUBY + require "my_queue_consumer" + config.queue = ActiveSupport::Queue + config.queue_consumer = MyQueueConsumer + RUBY + + app_file "lib/my_queue_consumer.rb", <<-RUBY + class MyQueueConsumer < ActiveSupport::ThreadedQueueConsumer + attr_reader :started + + def start + @started = true + self + end + end + RUBY + + app("production") + + assert_kind_of MyQueueConsumer, Rails.application.queue_consumer + assert Rails.application.queue_consumer.started + end + + test "default consumer is not used with custom queue implementation" do + setup_custom_queue + + assert_nil Rails.application.queue_consumer + end + end +end |