spec/lib/appsignal/hooks/delayed_job_spec.rb in appsignal-2.2.1 vs spec/lib/appsignal/hooks/delayed_job_spec.rb in appsignal-2.3.0.beta.1

- old
+ new

@@ -23,10 +23,14 @@ subject { described_class.new.dependencies_present? } it { is_expected.to be_truthy } end + it "adds the plugin" do + expect(::Delayed::Worker.plugins).to include Appsignal::Hooks::DelayedJobPlugin + end + # We haven't found a way to test the hooks, we'll have to do that manually describe ".invoke_with_instrumentation" do let(:plugin) { Appsignal::Hooks::DelayedJobPlugin } let(:time) { Time.parse("01-01-2001 10:01:00UTC") } @@ -36,121 +40,262 @@ :name => "TestClass#perform", :priority => 1, :attempts => 1, :queue => "default", :created_at => time - 60_000, - :payload_object => double(:args => ["argument"]) + :payload_object => double(:args => args) } end + let(:args) { ["argument"] } let(:job) { double(job_data) } let(:invoked_block) { proc {} } - let(:error) { StandardError.new } context "with a normal call" do - it "should wrap in a transaction with the correct params" do - expect(Appsignal).to receive(:monitor_transaction).with( - "perform_job.delayed_job", + let(:default_params) do + { :class => "TestClass", :method => "perform", :metadata => { :priority => 1, :attempts => 1, :queue => "default", :id => "123" }, - :params => ["argument"], :queue_start => time - 60_000 - ) - + } + end + after do Timecop.freeze(time) do plugin.invoke_with_instrumentation(job, invoked_block) end end + it "wraps it in a transaction with the correct params" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge(:params => ["argument"]) + ) + end + + context "with more complex params" do + let(:args) do + { + :foo => "Foo", + :bar => "Bar" + } + end + + it "adds the more complex arguments" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => { + :foo => "Foo", + :bar => "Bar" + } + ) + ) + end + + context "with parameter filtering" do + before do + Appsignal.config = project_fixture_config("production") + Appsignal.config[:filter_parameters] = ["foo"] + end + + it "filters selected arguments" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => { + :foo => "[FILTERED]", + :bar => "Bar" + } + ) + ) + end + end + end + context "with custom name call" do let(:job_data) do { :payload_object => double( :appsignal_name => "CustomClass#perform", - :args => ["argument"] + :args => args ), :id => "123", :name => "TestClass#perform", :priority => 1, :attempts => 1, :queue => "default", :created_at => time - 60_000 } end - it "should wrap in a transaction with the correct params" do - expect(Appsignal).to receive(:monitor_transaction).with( - "perform_job.delayed_job", + let(:default_params) do + { :class => "CustomClass", :method => "perform", :metadata => { :priority => 1, :attempts => 1, :queue => "default", :id => "123" }, - :params => ["argument"], :queue_start => time - 60_000 + } + end + + it "wraps it in a transaction with the correct params" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => ["argument"] + ) ) + end - Timecop.freeze(time) do - plugin.invoke_with_instrumentation(job, invoked_block) + context "with more complex params" do + let(:args) do + { + :foo => "Foo", + :bar => "Bar" + } end + + it "adds the more complex arguments" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => { + :foo => "Foo", + :bar => "Bar" + } + ) + ) + end + + context "with parameter filtering" do + before do + Appsignal.config = project_fixture_config("production") + Appsignal.config[:filter_parameters] = ["foo"] + end + + it "filters selected arguments" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => { + :foo => "[FILTERED]", + :bar => "Bar" + } + ) + ) + end + end end end if active_job_present? require "active_job" context "when wrapped by ActiveJob" do - before do - job_data[:args] = ["argument"] - end let(:job) { ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(job_data) } - - it "should wrap in a transaction with the correct params" do - expect(Appsignal).to receive(:monitor_transaction).with( - "perform_job.delayed_job", + let(:default_params) do + { :class => "TestClass", :method => "perform", :metadata => { :priority => 1, :attempts => 1, :queue => "default", :id => "123" }, - :params => ["argument"], :queue_start => time - 60_000 + } + end + before { job_data[:args] = args } + + it "wraps it in a transaction with the correct params" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge(:params => ["argument"]) ) + end - Timecop.freeze(time) do - plugin.invoke_with_instrumentation(job, invoked_block) + context "with more complex params" do + let(:args) do + { + :foo => "Foo", + :bar => "Bar" + } end + + it "adds the more complex arguments" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => { + :foo => "Foo", + :bar => "Bar" + } + ) + ) + end + + context "with parameter filtering" do + before do + Appsignal.config = project_fixture_config("production") + Appsignal.config[:filter_parameters] = ["foo"] + end + + it "filters selected arguments" do + expect(Appsignal).to receive(:monitor_transaction).with( + "perform_job.delayed_job", + default_params.merge( + :params => { + :foo => "[FILTERED]", + :bar => "Bar" + } + ) + ) + end + end end end end end context "with an erroring call" do - it "should add the error to the transaction" do - expect_any_instance_of(Appsignal::Transaction).to receive(:set_error).with(error) - expect(Appsignal::Transaction).to receive(:complete_current!) + let(:error) { VerySpecificError } + let(:transaction) do + Appsignal::Transaction.new( + SecureRandom.uuid, + Appsignal::Transaction::BACKGROUND_JOB, + Appsignal::Transaction::GenericRequest.new({}) + ) + end + before do + expect(invoked_block).to receive(:call).and_raise(error) - allow(invoked_block).to receive(:call).and_raise(error) + allow(Appsignal::Transaction).to receive(:current).and_return(transaction) + expect(Appsignal::Transaction).to receive(:create) + .with( + kind_of(String), + Appsignal::Transaction::BACKGROUND_JOB, + kind_of(Appsignal::Transaction::GenericRequest) + ).and_return(transaction) + end + it "adds the error to the transaction" do + expect(transaction).to receive(:set_error).with(error) + expect(transaction).to receive(:complete) + expect do plugin.invoke_with_instrumentation(job, invoked_block) - end.to raise_error(StandardError) + end.to raise_error(error) end end - end - - it "should add the plugin" do - expect(::Delayed::Worker.plugins).to include Appsignal::Hooks::DelayedJobPlugin end end context "without delayed job" do describe "#dependencies_present?" do