@@ -35,7 +35,7 @@ def perform_job(job)
3535
3636 describe "enqueueing a job" do
3737 context "with an active transaction" do
38- it "records an enqueue event titled after the job" do
38+ it "records an enqueue event titled after the job" , :agent_mode do
3939 start_agent
4040 transaction = http_request_transaction
4141 set_current_transaction ( transaction )
@@ -46,15 +46,40 @@ def perform_job(job)
4646 expect ( event ) . to_not be_nil
4747 expect ( event [ "title" ] ) . to eq ( "enqueue DelayedTestJob job" )
4848 end
49+
50+ it "records the enqueue as a producer span" , :collector_mode do
51+ start_collector_agent
52+ transaction = http_request_transaction
53+ set_current_transaction ( transaction )
54+
55+ Delayed ::Job . enqueue ( DelayedTestJob . new )
56+ Appsignal ::Transaction . complete_current!
57+
58+ # Delayed Job has no envelope to carry trace context, so -- like
59+ # OpenTelemetry's own instrumentation -- nothing is injected; the
60+ # producer span is not linked to the later perform.
61+ producer = event_spans . find { |s | s . name == "enqueue DelayedTestJob job" }
62+ expect ( producer . attributes [ "appsignal.category" ] ) . to eq ( "enqueue.delayed_job" )
63+ expect ( producer . kind ) . to eq ( :producer )
64+ expect ( producer . parent_span_id ) . to eq ( root_span . span_id )
65+ end
4966 end
5067
5168 context "without an active transaction" do
52- it "is a transparent pass-through" do
69+ it "is a transparent pass-through" , :agent_mode do
5370 start_agent
5471
5572 expect { Delayed ::Job . enqueue ( DelayedTestJob . new ) }
5673 . to change { Delayed ::Backend ::Test ::Job . count } . by ( 1 )
5774 end
75+
76+ it "emits no enqueue span" , :collector_mode do
77+ start_collector_agent
78+
79+ Delayed ::Job . enqueue ( DelayedTestJob . new )
80+
81+ expect ( span_exporter . finished_spans . map ( &:name ) ) . to_not include ( "enqueue.delayed_job" )
82+ end
5883 end
5984
6085 if DependencyHelper . active_job_present?
@@ -72,7 +97,7 @@ def perform(*)
7297 end )
7398 end
7499
75- it "does not record a second enqueue event" do
100+ it "does not record a second enqueue event" , :agent_mode do
76101 start_agent
77102 transaction = http_request_transaction
78103 set_current_transaction ( transaction )
@@ -89,7 +114,7 @@ def perform(*)
89114
90115 describe "performing a job" do
91116 context "with a normal job" do
92- it "wraps it in a background_job transaction" do
117+ it "wraps it in a background_job transaction" , :agent_mode do
93118 start_agent
94119 job = Delayed ::Job . enqueue ( DelayedTestJob . new )
95120
@@ -102,6 +127,19 @@ def perform(*)
102127 expect ( transaction ) . to include_event ( :name => "perform_job.delayed_job" )
103128 expect ( transaction ) . to include_tags ( "attempts" => 0 , "priority" => 0 )
104129 end
130+
131+ it "wraps it in a consumer span" , :collector_mode do
132+ start_collector_agent
133+ job = Delayed ::Job . enqueue ( DelayedTestJob . new )
134+
135+ perform_job ( job )
136+ Appsignal ::Transaction . complete_current!
137+
138+ expect ( root_span . kind ) . to eq ( :consumer )
139+ expect ( root_span . attributes [ "appsignal.action_name" ] ) . to eq ( "DelayedTestJob#perform" )
140+ expect ( root_span . attributes [ "appsignal.namespace" ] ) . to eq ( "background" )
141+ expect ( event_spans . map ( &:name ) ) . to include ( "perform_job.delayed_job" )
142+ end
105143 end
106144
107145 context "with a job that raises" do
@@ -113,7 +151,7 @@ def perform
113151 end )
114152 end
115153
116- it "records the error on the transaction" do
154+ it "records the error on the transaction" , :agent_mode do
117155 start_agent
118156 job = Delayed ::Job . enqueue ( DelayedErrorJob . new )
119157
@@ -126,6 +164,19 @@ def perform
126164 expect ( transaction ) . to have_action ( "DelayedErrorJob#perform" )
127165 expect ( transaction ) . to have_error ( "ExampleException" , "uh oh" )
128166 end
167+
168+ it "records the error on the consumer span" , :collector_mode do
169+ start_collector_agent
170+ job = Delayed ::Job . enqueue ( DelayedErrorJob . new )
171+
172+ expect { perform_job ( job ) } . to raise_error ( ExampleException , "uh oh" )
173+ Appsignal ::Transaction . complete_current!
174+
175+ expect ( root_span . kind ) . to eq ( :consumer )
176+ event = root_span . events . find { |e | e . name == "exception" }
177+ expect ( event . attributes [ "exception.type" ] ) . to eq ( "ExampleException" )
178+ expect ( event . attributes [ "exception.message" ] ) . to eq ( "uh oh" )
179+ end
129180 end
130181
131182 context "with a custom appsignal_name" do
@@ -140,7 +191,7 @@ def appsignal_name
140191 end )
141192 end
142193
143- it "uses the custom name as the action" do
194+ it "uses the custom name as the action" , :agent_mode do
144195 start_agent
145196 job = Delayed ::Job . enqueue ( DelayedNamedJob . new )
146197
@@ -163,7 +214,7 @@ def perform(*)
163214 end )
164215 end
165216
166- it "uses the Active Job class as the action" do
217+ it "uses the Active Job class as the action" , :agent_mode do
167218 start_agent
168219
169220 keep_transactions do
0 commit comments