discourse/spec/jobs/jobs_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

174 lines
5.1 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
RSpec.describe Jobs do
2013-02-05 13:16:51 -06:00
describe "enqueue" do
describe "run_later!" do
before { Jobs.run_later! }
2013-02-05 13:16:51 -06:00
it "enqueues a job in sidekiq" do
Sidekiq::Testing.fake! do
jobs = Jobs::ProcessPost.jobs
jobs.clear
Jobs.enqueue(:process_post, post_id: 1)
expect(jobs.length).to eq(1)
job = jobs.first
expected = {
"class" => "Jobs::ProcessPost",
"args" => [{ "post_id" => 1, "current_site_id" => "default" }],
"queue" => "default",
}
expect(job.slice("class", "args", "queue")).to eq(expected)
end
2013-02-05 13:16:51 -06:00
end
it "enqueues the job after the current transaction has committed" do
jobs = Jobs::ProcessPost.jobs
expect(jobs.length).to eq(0)
Jobs.enqueue(:process_post, post_id: 1)
expect(jobs.length).to eq(1)
ActiveRecord::Base.transaction do
Jobs.enqueue(:process_post, post_id: 1)
expect(jobs.length).to eq(1)
end
expect(jobs.length).to eq(2)
# Failed transaction
ActiveRecord::Base.transaction do
Jobs.enqueue(:process_post, post_id: 1)
raise ActiveRecord::Rollback
end
expect(jobs.length).to eq(2) # No change
end
2013-02-05 13:16:51 -06:00
it "does not pass current_site_id when 'all_sites' is present" do
Sidekiq::Testing.fake! do
jobs = Jobs::ProcessPost.jobs
jobs.clear
Jobs.enqueue(:process_post, post_id: 1, all_sites: true)
expect(jobs.length).to eq(1)
job = jobs.first
expected = {
"class" => "Jobs::ProcessPost",
"args" => [{ "post_id" => 1 }],
"queue" => "default",
}
expect(job.slice("class", "args", "queue")).to eq(expected)
end
2013-02-05 13:16:51 -06:00
end
it "doesn't execute the job" do
Sidekiq::Client.stubs(:enqueue)
Jobs::ProcessPost.any_instance.expects(:perform).never
Jobs.enqueue(:process_post, post_id: 1)
end
it "should enqueue with the correct database id when the current_site_id option is given" do
Sidekiq::Testing.fake! do
jobs = Jobs::ProcessPost.jobs
jobs.clear
Jobs.enqueue(:process_post, post_id: 1, current_site_id: "test_db")
expect(jobs.length).to eq(1)
job = jobs.first
expected = {
"class" => "Jobs::ProcessPost",
"args" => [{ "post_id" => 1, "current_site_id" => "test_db" }],
"queue" => "default",
}
expect(job.slice("class", "args", "queue")).to eq(expected)
2013-02-05 13:16:51 -06:00
end
end
end
describe "run_immediately!" do
before { Jobs.run_immediately! }
2013-02-05 13:16:51 -06:00
it "doesn't enqueue in sidekiq" do
Sidekiq::Client.expects(:enqueue).with(Jobs::ProcessPost, {}).never
Jobs.enqueue(:process_post, post_id: 1)
end
it "executes the job right away" do
Jobs::ProcessPost
.any_instance
DEV: Fix threading error when running jobs immediately in system tests (#19811) ``` class Jobs::DummyDelayedJob < Jobs::Base def execute(args = {}) end end RSpec.describe "Jobs.run_immediately!" do before { Jobs.run_immediately! } it "explodes" do current_user = Fabricate(:user) Jobs.enqueue_in(1.seconds, :dummy_delayed_job) sign_in(current_user) end end ``` The test above will fail with the following error if `ActiveRecord::Base.connection_handler.clear_active_connections!` is called before the configured Capybara server checks out a connection from the connection pool. ``` ActiveRecord::ActiveRecordError: Cannot expire connection, it is owned by a different thread: #<Thread:0x00007f437391df58@puma srv tp 001 /home/tgxworld/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/puma-6.0.2/lib/puma/thread_pool.rb:106 sleep_forever>. Current thread: #<Thread:0x00007f437d6cfc60 run>. ``` We're not exactly sure if this is an ActiveRecord bug or not but we've invested too much time into investigating this problem. Fundamentally, we also no longer understand why `ActiveRecord::Base.connection_handler.clear_active_connections!` is being called in an ensure block within `Jobs::Base#perform` which was added in ceddb6e0da92e874b3bee9543915726f1d27d60b 10 years ago. This commit moves the logic for running jobs immediately out of the `Jobs::Base#perform` method into another `Jobs::Base#perform_immediately` method such that `ActiveRecord::Base.connection_handler.clear_active_connections!` is not called. This change will only impact the test environment.
2023-01-09 23:41:25 -06:00
.expects(:perform_immediately)
.with({ "post_id" => 1, "current_site_id" => "default" })
2013-02-05 13:16:51 -06:00
Jobs.enqueue(:process_post, post_id: 1)
end
context "when current_site_id option is given and does not match the current connection" do
2013-02-05 13:16:51 -06:00
before do
Sidekiq::Client.stubs(:enqueue)
Jobs::ProcessPost.any_instance.stubs(:execute).returns(true)
end
it "should raise an exception" do
2013-02-05 13:16:51 -06:00
Jobs::ProcessPost.any_instance.expects(:execute).never
RailsMultisite::ConnectionManagement.expects(:establish_connection).never
2013-02-05 13:16:51 -06:00
expect {
Jobs.enqueue(:process_post, post_id: 1, current_site_id: "test_db")
}.to raise_error(ArgumentError)
end
end
end
end
describe "cancel_scheduled_job" do
let(:scheduled_jobs) { Sidekiq::ScheduledSet.new }
after { scheduled_jobs.clear }
it "deletes the matching job" do
Sidekiq::Testing.disable! do
scheduled_jobs.clear
expect(scheduled_jobs.size).to eq(0)
Jobs.enqueue_in(1.year, :run_heartbeat, topic_id: 123)
Jobs.enqueue_in(2.years, :run_heartbeat, topic_id: 456)
Jobs.enqueue_in(3.years, :run_heartbeat, topic_id: 123, current_site_id: "foo")
Jobs.enqueue_in(4.years, :run_heartbeat, topic_id: 123, current_site_id: "bar")
expect(scheduled_jobs.size).to eq(4)
Jobs.cancel_scheduled_job(:run_heartbeat, topic_id: 123)
expect(scheduled_jobs.size).to eq(3)
Jobs.cancel_scheduled_job(:run_heartbeat, topic_id: 123, all_sites: true)
expect(scheduled_jobs.size).to eq(1)
end
end
end
describe "enqueue_at" do
it "calls enqueue_in for you" do
freeze_time
2020-07-24 04:16:52 -05:00
expect_enqueued_with(job: :process_post, at: 3.hours.from_now) do
Jobs.enqueue_at(3.hours.from_now, :process_post, {})
end
end
it "handles datetimes that are in the past" do
freeze_time
2020-07-24 04:16:52 -05:00
expect_enqueued_with(job: :process_post, at: Time.zone.now) do
Jobs.enqueue_at(3.hours.ago, :process_post, {})
end
end
end
2013-02-05 13:16:51 -06:00
end