if DependencyHelper.que_present? require "appsignal/integrations/que" describe Appsignal::Integrations::QuePlugin do describe "#_run" do let(:job_attrs) do { :job_id => 123, :queue => "dfl", :job_class => "MyQueJob", :priority => 100, :args => %w[1 birds], :run_at => fixed_time, :error_count => 0 } end let(:env) do { :class => "MyQueJob", :method => "run", :metadata => { :id => 123, :queue => "dfl", :priority => 100, :run_at => fixed_time.to_s, :attempts => 0 }, :params => %w[1 birds] } end let(:job) do Class.new(::Que::Job) do def run(*args) end end end let(:instance) { job.new(job_attrs) } let(:transaction) do Appsignal::Transaction.new( SecureRandom.uuid, Appsignal::Transaction::BACKGROUND_JOB, Appsignal::Transaction::GenericRequest.new(env) ) end before do allow(Que).to receive(:execute) start_agent expect(Appsignal.active?).to be_truthy transaction expect(Appsignal::Transaction).to receive(:create) .with( kind_of(String), Appsignal::Transaction::BACKGROUND_JOB, kind_of(Appsignal::Transaction::GenericRequest) ).and_return(transaction) allow(Appsignal::Transaction).to receive(:current).and_return(transaction) expect(transaction.ext).to receive(:finish).and_return(true) expect(transaction.ext).to receive(:complete) end subject { transaction.to_h } context "success" do it "creates a transaction for a job" do expect do instance._run end.to_not raise_exception expect(subject).to include( "action" => "MyQueJob#run", "id" => instance_of(String), "namespace" => Appsignal::Transaction::BACKGROUND_JOB ) expect(subject["error"]).to be_nil expect(subject["events"].first).to include( "allocation_count" => kind_of(Integer), "body" => "", "body_format" => Appsignal::EventFormatter::DEFAULT, "child_allocation_count" => kind_of(Integer), "child_duration" => kind_of(Float), "child_gc_duration" => kind_of(Float), "count" => 1, "gc_duration" => kind_of(Float), "start" => kind_of(Float), "duration" => kind_of(Float), "name" => "perform_job.que", "title" => "" ) expect(subject["sample_data"]).to include( "params" => %w[1 birds], "metadata" => { "attempts" => 0, "id" => 123, "priority" => 100, "queue" => "dfl", "run_at" => fixed_time.to_s } ) end end context "with exception" do let(:error) { ExampleException.new("oh no!") } it "should report exceptions and re-raise them" do allow(instance).to receive(:run).and_raise(error) expect do instance._run end.to raise_error(ExampleException) expect(subject).to include( "action" => "MyQueJob#run", "id" => instance_of(String), "namespace" => Appsignal::Transaction::BACKGROUND_JOB ) expect(subject["error"]).to include( "backtrace" => kind_of(String), "name" => error.class.name, "message" => error.message ) expect(subject["sample_data"]).to include( "params" => %w[1 birds], "metadata" => { "attempts" => 0, "id" => 123, "priority" => 100, "queue" => "dfl", "run_at" => fixed_time.to_s } ) end end context "with error" do let(:error) { ExampleStandardError.new("oh no!") } it "should report errors and not re-raise them" do allow(instance).to receive(:run).and_raise(error) expect do instance._run end.to_not raise_error expect(subject).to include( "action" => "MyQueJob#run", "id" => instance_of(String), "namespace" => Appsignal::Transaction::BACKGROUND_JOB ) expect(subject["error"]).to include( "backtrace" => kind_of(String), "name" => error.class.name, "message" => error.message ) expect(subject["sample_data"]).to include( "params" => %w[1 birds], "metadata" => { "attempts" => 0, "id" => 123, "priority" => 100, "queue" => "dfl", "run_at" => fixed_time.to_s } ) end end end end end