getsentry / getsentry/sentry-ruby
New spec suite for Active Job integrations
- Lingua principale
- Ruby
- Stelle
- 987
- Fork
- 541
- Merge medio
- 17h 40m
- PR unite (30g)
- 19
Descrizione
### Description
⚠️ This won't be done all-at-once - this issue is an anchor for all the work that must be done for the epic issue getsentry/sentry-ruby#2932. It will be growing and most likely being refined as we move forward. It will be done/closed once all the backends have been ported.
---
The existing [activejob_spec.rb]() is a monolithic file that mixes lifecycle, context, tracing, retries and cron into one describe block and only runs against `:test`. It is not a suitable foundation for a rework that has to prove identical behavior across all AJ-based integrations.
The goal is to replace the original specs with a dedicated, shared-example-driven AJ spec suite under a new tree (e.g. `sentry-rails/spec/active_job/`). Each feature area lives in its own shared-example file. Each backend ships as a thin spec file whose entire body is roughly:
```ruby
RSpec.describe "Sentry + ActiveJob on SolidQueue" do
include_context "active_job backend harness", adapter: :solid_queue
it_behaves_like "a Sentry-instrumented ActiveJob backend"
end
```
General principles and ideas:
* One top-level shared example — "a Sentry-instrumented ActiveJob backend" — composes smaller per-area shared examples. Adding a new backend is a one-line include.
* Shared examples never branch on adapter name. Per-backend quirks go through a harness helper (boot, enqueue, drain, reset) that each backend's spec file supplies via `let` or shared context.
* Backend-specific behaviors (e.g. sidekiq retry middleware, solid_queue recurring jobs) live in the respective backend-specific dirs or dedicated gems (sentry-sidekiq).
**Feature areas the shared suite must cover**
* **Harness & scaffolding.** New spec tree, shared context for adapter setup / teardown / draining, fixture jobs (normal, failing, retryable, discardable, scheduled, mailer, rescue-from, deserialization-error, nested-enqueue), transport/event helpers. No behavioral assertions yet — just the rails the rest of Phase 0 runs on.
* **Job lifecycle.** `perform_now`, `perform_later` + drain, `set(wait:)` / `set(wait_until:)` scheduled jobs, `retry_on`, `discard_on`, `rescue_from` (both suppressing and re-raising), `ActiveJob::DeserializationError` root-cause unwrapping, `ActionMailer::MailDeliveryJob` path.
* **Error capture & context.** Exception type/message/stacktrace round-trip, `extra` payload (active_job, arguments, scheduled_at, job_id, provider_job_id, locale, queue, executions), tags (job_id, provider_job_id, queue), scope cleared between jobs, `rescue_from`-suppressed errors produce no event, errors raised from `rescue_from` callbacks produce both events.
* **Consumer-side tracing.** Transaction name = job class, `source: :task`, op + origin conventions, `status: ok` / `internal_error`, event linked to transaction via same `trace_id`, messaging span data (`messaging.destination.name`, `messaging.message.id`, retry count, latency, provider job id), gated correctly by `traces_sample_rate`.
* **Producer-side tracing.** Enqueue within an active transaction produces a `queue.publish` child span; span carries the same messaging data; scheduled enqueue does the same. *(Pending until Phase 1.)*
* **Distributed tracing.** Producer trace headers round-trip through the payload; consumer transaction's `trace_id` matches producer's; consumer's `parent_span_id` points at the producer's publish span; baggage survives. Verified per backend — this is the shared suite's most important test for adapter conformance.
* **Scope & context propagation.** Hub cloned per job, user set on producer scope surfaces on consumer scope, tags propagate, no scope leak between consecutive jobs, no leak across threads/fibers.
* **Retry & discard semantics.** `active_job_report_on_retry_error` true/false, final-attempt-only reporting, discarded jobs emit no event, retry count reflected in transaction span data and tags, exhausted-retry capture.
* **Argument serialization.** Ports the existing GlobalID / nested / Range / TimeWithZone / raising-`to_global_id` coverage from the old file into a dedicated shared-examples file. Adds sensitive-value handling (`send_default_pii`) if applicable.
* **Concurrency.** Parallel job execution keeps scopes isolated; thread-local hub is not shared; trace ids do not cross-contaminate.
* **Backend wiring.** One thin spec file per adapter: `:test`, `:inline`, `:async`, `solid_queue`, `good_job`, `sidekiq`. Each just configures the adapter via the harness and includes the top-level shared example.
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.