Skip to content

Commit 89f74dc

Browse files
committed
refa(tests): simplify oban integration test
1 parent 5131722 commit 89f74dc

1 file changed

Lines changed: 64 additions & 147 deletions

File tree

test_integrations/phoenix_app/test/phoenix_app/oban_test.exs

Lines changed: 64 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
33
use Oban.Testing, repo: PhoenixApp.Repo
44

55
import ExUnit.CaptureLog
6+
import Sentry.Test.Assertions
67
import Sentry.TestHelpers
78

89
require OpenTelemetry.Tracer
910

1011
alias Sentry.Integrations.Oban.ErrorReporter
1112

1213
setup do
13-
%{bypass: bypass} = setup_bypass(traces_sample_rate: 1.0)
14-
ref = setup_bypass_envelope_collector(bypass)
15-
16-
%{bypass: bypass, ref: ref}
14+
Sentry.Test.setup_sentry(collect_envelopes: true, traces_sample_rate: 1.0)
1715
end
1816

1917
defmodule TestWorker do
@@ -47,43 +45,29 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
4745
end
4846
end
4947

50-
test "captures Oban worker execution as transaction", %{ref: ref} do
48+
test "captures Oban worker execution as transaction" do
5149
:ok = perform_job(TestWorker, %{test: "args"})
5250

53-
envelopes = collect_envelopes(ref, 1)
54-
transactions = extract_transactions(envelopes)
55-
assert length(transactions) == 1
56-
57-
[tx] = transactions
51+
tx =
52+
assert_sentry_report(:transaction,
53+
transaction: "Sentry.Integrations.Phoenix.ObanTest.TestWorker",
54+
transaction_info: %{source: :custom}
55+
)
5856

59-
assert tx["transaction"] == "Sentry.Integrations.Phoenix.ObanTest.TestWorker"
60-
assert tx["transaction_info"] == %{"source" => "custom"}
57+
trace = tx.contexts.trace
58+
assert trace.origin == "opentelemetry_oban"
59+
assert trace.op == "queue.process"
60+
assert trace.description == "Sentry.Integrations.Phoenix.ObanTest.TestWorker"
61+
assert trace.data["oban.job.job_id"]
62+
assert trace.data["messaging.destination.name"] == "default"
63+
assert trace.data["oban.job.attempt"] == 1
6164

62-
trace = tx["contexts"]["trace"]
63-
assert trace["origin"] == "opentelemetry_oban"
64-
assert trace["op"] == "queue.process"
65-
assert trace["description"] == "Sentry.Integrations.Phoenix.ObanTest.TestWorker"
66-
assert trace["data"]["oban.job.job_id"]
67-
assert trace["data"]["messaging.destination.name"] == "default"
68-
assert trace["data"]["oban.job.attempt"] == 1
69-
70-
assert tx["spans"] == []
65+
assert tx.spans == []
7166
end
7267

73-
test "captures Oban worker with trace links", %{bypass: bypass} do
68+
test "captures Oban worker with trace links", %{ref: ref} do
7469
# This test verifies that when an Oban job is inserted within an active trace,
7570
# the consumer span has links back to the producer span.
76-
test_pid = self()
77-
78-
Bypass.stub(bypass, "POST", "/api/1/envelope/", fn conn ->
79-
{:ok, body, conn} = Plug.Conn.read_body(conn)
80-
81-
for {headers, body_json} <- decode_envelope!(body) do
82-
send(test_pid, {headers["type"], body_json})
83-
end
84-
85-
Plug.Conn.send_resp(conn, 200, ~s<{"id": "340"}>)
86-
end)
8771

8872
# Insert within an active span so trace context is propagated into job metadata
8973
OpenTelemetry.Tracer.with_span "test.request" do
@@ -96,9 +80,8 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
9680
# Drain the queue to execute the job
9781
Oban.drain_queue(queue: :default)
9882

99-
# Multiple transactions are sent (test.request, DB queries, Oban consumer),
100-
# so we need to find the Oban consumer transaction specifically
101-
oban_tx = receive_oban_transaction()
83+
transactions = collect_sentry_transactions(ref, 100, timeout: 500)
84+
oban_tx = find_sentry_report!(transactions, contexts: %{trace: %{origin: "opentelemetry_oban"}})
10285

10386
trace = oban_tx["contexts"]["trace"]
10487
assert trace["op"] == "queue.process"
@@ -116,70 +99,34 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
11699
end
117100
end
118101

119-
test "captures Oban worker with child spans", %{ref: ref} do
102+
test "captures Oban worker with child spans" do
120103
:ok = perform_job(WorkerWithDatabaseQuery, %{})
121104

122-
envelopes = collect_envelopes(ref, 1)
123-
transactions = extract_transactions(envelopes)
124-
assert length(transactions) == 1
125-
126-
[tx] = transactions
127-
128-
assert tx["transaction"] ==
129-
"Sentry.Integrations.Phoenix.ObanTest.WorkerWithDatabaseQuery"
130-
131-
# Should have child spans from the database query
132-
assert length(tx["spans"]) > 0
105+
tx =
106+
assert_sentry_report(:transaction,
107+
transaction: "Sentry.Integrations.Phoenix.ObanTest.WorkerWithDatabaseQuery"
108+
)
133109

134-
# Verify at least one db span exists
135-
assert Enum.any?(tx["spans"], fn span ->
136-
span["op"] == "db"
137-
end)
138-
end
110+
assert length(tx.spans) > 0
139111

140-
defp receive_oban_transaction do
141-
receive do
142-
{"transaction", tx} ->
143-
if tx["contexts"]["trace"]["origin"] == "opentelemetry_oban" do
144-
tx
145-
else
146-
receive_oban_transaction()
147-
end
148-
after
149-
2000 -> flunk("expected an Oban consumer transaction")
150-
end
112+
assert Enum.any?(tx.spans, fn span -> span.op == "db" end)
151113
end
152114

153115
describe "should_report_error_callback config" do
154-
setup %{bypass: bypass} do
116+
setup do
155117
:telemetry.detach(ErrorReporter)
156118

157-
ref = setup_bypass_envelope_collector(bypass, type: "event")
158-
159119
on_exit(fn ->
160120
_ = :telemetry.detach(ErrorReporter)
161121
ErrorReporter.attach([])
162122
end)
163123

164-
%{ref: ref}
165-
end
124+
:ok
125+
end
166126

167-
test "skips error reporting when callback returns false", %{bypass: bypass, ref: ref} do
127+
test "skips error reporting when callback returns false" do
168128
test_pid = self()
169129

170-
# Allow transaction envelopes through but assert no error events are sent
171-
Bypass.stub(bypass, "POST", "/api/1/envelope/", fn conn ->
172-
{:ok, body, conn} = Plug.Conn.read_body(conn)
173-
items = decode_envelope!(body)
174-
175-
for {headers, _body} <- items do
176-
assert headers["type"] != "event",
177-
"Should not send error events when callback returns false"
178-
end
179-
180-
Plug.Conn.send_resp(conn, 200, ~s<{"id": "340"}>)
181-
end)
182-
183130
ErrorReporter.attach(
184131
should_report_error_callback: fn worker, job ->
185132
send(test_pid, {:callback_invoked, worker, job})
@@ -199,11 +146,10 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
199146
assert %Oban.Job{} = received_job
200147
assert received_job.args == %{"should_fail" => true}
201148

202-
envelopes = collect_envelopes(ref, 10, timeout: 500)
203-
assert extract_events(envelopes) == []
149+
assert [] == Sentry.Test.pop_sentry_reports()
204150
end
205151

206-
test "reports error when callback returns true", %{ref: ref} do
152+
test "reports error when callback returns true" do
207153
test_pid = self()
208154

209155
ErrorReporter.attach(
@@ -222,18 +168,16 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
222168

223169
assert_receive {:callback_invoked, _worker, _job}
224170

225-
envelopes = collect_envelopes(ref, 10, timeout: 500)
226-
events = extract_events(envelopes)
227-
assert [event] = events
228-
229-
assert [%{"type" => "RuntimeError", "value" => "intentional failure for testing"} | _] =
230-
event["exception"]
171+
event =
172+
find_sentry_report!(Sentry.Test.pop_sentry_reports(),
173+
tags: %{oban_worker: "Sentry.Integrations.Phoenix.ObanTest.FailingWorker"}
174+
)
231175

232-
assert event["tags"]["oban_worker"] ==
233-
"Sentry.Integrations.Phoenix.ObanTest.FailingWorker"
176+
assert [%Sentry.Interfaces.Exception{type: "RuntimeError", value: "intentional failure for testing"} | _] =
177+
event.exception
234178
end
235179

236-
test "callback receives worker module and full job struct", %{ref: ref} do
180+
test "callback receives worker module and full job struct" do
237181
test_pid = self()
238182

239183
ErrorReporter.attach(
@@ -262,27 +206,11 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
262206
assert job.max_attempts == 3
263207
assert is_integer(job.attempt)
264208
assert is_integer(job.id)
265-
266-
# Drain envelopes to avoid Bypass errors
267-
collect_envelopes(ref, 10, timeout: 500)
268209
end
269210

270-
test "callback can make decisions based on attempt number", %{bypass: bypass, ref: ref} do
211+
test "callback can make decisions based on attempt number" do
271212
test_pid = self()
272213

273-
# Allow transaction envelopes through but assert no error events are sent
274-
Bypass.stub(bypass, "POST", "/api/1/envelope/", fn conn ->
275-
{:ok, body, conn} = Plug.Conn.read_body(conn)
276-
items = decode_envelope!(body)
277-
278-
for {headers, _body} <- items do
279-
assert headers["type"] != "event",
280-
"Should not send error events when callback returns false"
281-
end
282-
283-
Plug.Conn.send_resp(conn, 200, ~s<{"id": "340"}>)
284-
end)
285-
286214
ErrorReporter.attach(
287215
should_report_error_callback: fn _worker, job ->
288216
should_report = job.attempt >= job.max_attempts
@@ -303,11 +231,10 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
303231
assert max_attempts == 3
304232
assert should_report == false
305233

306-
envelopes = collect_envelopes(ref, 10, timeout: 500)
307-
assert extract_events(envelopes) == []
234+
assert [] == Sentry.Test.pop_sentry_reports()
308235
end
309236

310-
test "handles callback errors gracefully and defaults to reporting", %{ref: ref} do
237+
test "handles callback errors gracefully and defaults to reporting" do
311238
log =
312239
capture_log(fn ->
313240
ErrorReporter.attach(
@@ -328,15 +255,16 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
328255
assert log =~ "FailingWorker"
329256
assert log =~ "callback crashed!"
330257

331-
envelopes = collect_envelopes(ref, 10, timeout: 500)
332-
events = extract_events(envelopes)
333-
assert [event] = events
258+
event =
259+
find_sentry_report!(Sentry.Test.pop_sentry_reports(),
260+
tags: %{oban_worker: "Sentry.Integrations.Phoenix.ObanTest.FailingWorker"}
261+
)
334262

335-
assert [%{"type" => "RuntimeError", "value" => "intentional failure for testing"} | _] =
336-
event["exception"]
263+
assert [%Sentry.Interfaces.Exception{type: "RuntimeError", value: "intentional failure for testing"} | _] =
264+
event.exception
337265
end
338266

339-
test "reports error when no callback is configured", %{ref: ref} do
267+
test "reports error when no callback is configured" do
340268
ErrorReporter.attach([])
341269

342270
{:ok, _job} =
@@ -346,30 +274,18 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
346274

347275
Oban.drain_queue(queue: :default)
348276

349-
envelopes = collect_envelopes(ref, 10, timeout: 500)
350-
events = extract_events(envelopes)
351-
assert [event] = events
277+
event =
278+
find_sentry_report!(Sentry.Test.pop_sentry_reports(),
279+
tags: %{oban_worker: "Sentry.Integrations.Phoenix.ObanTest.FailingWorker"}
280+
)
352281

353-
assert [%{"type" => "RuntimeError", "value" => "intentional failure for testing"} | _] =
354-
event["exception"]
282+
assert [%Sentry.Interfaces.Exception{type: "RuntimeError", value: "intentional failure for testing"} | _] =
283+
event.exception
355284
end
356285

357-
test "callback can filter based on worker type", %{bypass: bypass, ref: ref} do
286+
test "callback can filter based on worker type" do
358287
test_pid = self()
359288

360-
# Allow transaction envelopes through but assert no error events are sent
361-
Bypass.stub(bypass, "POST", "/api/1/envelope/", fn conn ->
362-
{:ok, body, conn} = Plug.Conn.read_body(conn)
363-
items = decode_envelope!(body)
364-
365-
for {headers, _body} <- items do
366-
assert headers["type"] != "event",
367-
"Should not send error events when callback returns false"
368-
end
369-
370-
Plug.Conn.send_resp(conn, 200, ~s<{"id": "340"}>)
371-
end)
372-
373289
ErrorReporter.attach(
374290
should_report_error_callback: fn worker, _job ->
375291
should_report = worker != FailingWorker
@@ -387,11 +303,10 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
387303

388304
assert_receive {:worker_check, FailingWorker, false}
389305

390-
envelopes = collect_envelopes(ref, 10, timeout: 500)
391-
assert extract_events(envelopes) == []
306+
assert [] == Sentry.Test.pop_sentry_reports()
392307
end
393308

394-
test "callback receives nil and logs warning for non-existent worker module", %{ref: ref} do
309+
test "callback receives nil and logs warning for non-existent worker module" do
395310
test_pid = self()
396311

397312
log =
@@ -432,10 +347,12 @@ defmodule Sentry.Integrations.Phoenix.ObanTest do
432347
assert worker == nil
433348
assert received_job.worker == "NonExistent.Worker.Module"
434349

435-
envelopes = collect_envelopes(ref, 1)
436-
events = extract_events(envelopes)
437-
assert [event] = events
438-
assert event["tags"]["oban_worker"] == "NonExistent.Worker.Module"
350+
event =
351+
assert_sentry_report(:event,
352+
tags: %{oban_worker: "NonExistent.Worker.Module"}
353+
)
354+
355+
assert event.tags[:oban_worker] == "NonExistent.Worker.Module"
439356
end
440357
end
441358

0 commit comments

Comments
 (0)