Skip to content

Commit 4dd33f6

Browse files
committed
chore(docs): update Sentry.Test docs to reflect changes
1 parent 44b74e2 commit 4dd33f6

3 files changed

Lines changed: 43 additions & 13 deletions

File tree

lib/sentry/test.ex

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,7 @@ defmodule Sentry.Test do
230230
231231
> #### Deprecated {: .warning}
232232
>
233-
> This function is deprecated and will be removed in v13.0.0.
234-
> Use `setup_sentry/1` or `start_collecting_sentry_reports/0` instead.
233+
> This function is deprecated and will be removed in v14.0.0. Use `setup_sentry/1` instead.
235234
236235
The `:owner`, `:cleanup`, and `:key` options are no longer supported and are ignored.
237236
"""
@@ -252,11 +251,11 @@ defmodule Sentry.Test do
252251
253252
> #### Deprecated {: .warning}
254253
>
255-
> This function is deprecated and will be removed in v13.0.0.
256-
> Cleanup is now handled automatically via `on_exit` callbacks.
254+
> This function is deprecated and will be removed in v14.0.0.
255+
> Cleanup is now handled automatically when the owning test process exits.
257256
"""
258257
@doc since: "10.2.0"
259-
@doc deprecated: "Cleanup is now automatic via on_exit callbacks"
258+
@doc deprecated: "Cleanup is now automatic when the owning test process exits"
260259
@spec cleanup(pid()) :: :ok
261260
def cleanup(owner_pid) when is_pid(owner_pid) do
262261
:ok

lib/sentry/test/registry.ex

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,16 @@ defmodule Sentry.Test.Registry do
163163
{:ok, %{owner_monitors: %{}}}
164164
end
165165

166+
# Serialization note: every claim funnels through this single named
167+
# GenServer and holds it across TWO blocking round-trips to the
168+
# ownership server — `ensure_scope_owner/1`'s
169+
# `NimbleOwnership.get_and_update/4` and `NimbleOwnership.allow/4`.
170+
# This is the deliberate price of atomicity (no two concurrent async
171+
# tests can both pass a check-then-write race for the same
172+
# `allowed_pid`). It is acceptable because claims happen at test
173+
# setup, not per event, and the hot config/buffer read paths
174+
# (`lookup_allow_owner/1`, `lookup_processor_for/1`) bypass this
175+
# GenServer with lock-free direct ETS reads.
166176
@impl true
167177
def handle_call({:claim_allow, owner_pid, allowed_pid, mode}, _from, state) do
168178
state = ensure_owner_monitored(state, owner_pid)
@@ -232,14 +242,25 @@ defmodule Sentry.Test.Registry do
232242
# `Sentry.Test.setup_collector/1` (e.g. a test that uses
233243
# `Sentry.Test.Config.put/1` standalone). When the owner already
234244
# owns the key, the existing metadata is preserved.
245+
#
246+
# INVARIANT: the `:sentry_test_scope` key's metadata is overloaded —
247+
# `Sentry.Test.setup_collector/1` stores the per-test collector ETS
248+
# table name (an atom) under it, while this function stores a bare
249+
# `%{}` marker for collector-less scopes. `Sentry.Test`'s
250+
# `owner_collecting?/1` distinguishes the two purely by value type
251+
# (atom = collecting, map = not). Therefore the update fun below MUST
252+
# preserve an existing value (`current -> {:ok, current}`) and MUST
253+
# NOT overwrite it with `%{}`; doing so would silently turn a
254+
# collecting scope into a non-collecting one with no type error.
235255
defp ensure_scope_owner(owner_pid) do
236256
case NimbleOwnership.get_and_update(
237257
@ownership_server,
238258
owner_pid,
239259
@scope_key,
240260
# Metadata MUST be non-nil so that NimbleOwnership treats
241261
# `owner_pid` as a key owner (its `cond` in `allow/4` checks
242-
# truthiness of the metadata). Preserve any existing value.
262+
# truthiness of the metadata). Preserve any existing value
263+
# (see the INVARIANT above — never clobber a collector atom).
243264
fn
244265
nil -> {:ok, %{}}
245266
current -> {:ok, current}

lib/sentry/test/scope/registry.ex

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ defmodule Sentry.Test.Scope.Registry do
77
#
88
# * `{:sentry_test_scope, owner_pid} -> %Scope{}` in `:persistent_term` —
99
# one entry per active test scope, owns its overrides.
10-
# * `:sentry_test_scope_allows` ETS table (named, public, set) —
11-
# reverse index `{allowed_pid, owner_pid}` mapping each
12-
# explicitly-routed pid back to the scope that claimed it.
13-
# Owned by `Sentry.Test.Registry`. Direct ETS reads on the config
10+
# * `:sentry_test_pid_routing` ETS table (named, public, set) —
11+
# single merged routing table owned by `Sentry.Test.Registry`.
12+
# Rows are 3-tuples
13+
# `{allowed_pid, owner_pid_or_nil, processor_name_or_nil}`: the
14+
# owner field is the reverse index mapping each explicitly-routed
15+
# pid back to the scope that claimed it (read here via
16+
# `lookup_allow_owner/1`); the processor field routes buffered
17+
# events (logs, metrics) from that pid to a per-test
18+
# `Sentry.TelemetryProcessor`. Direct ETS reads on the config
1419
# read path; conflict-checked writes serialize through that
15-
# GenServer for atomic check-and-insert.
20+
# GenServer for atomic check-and-insert. Owner exit is handled by
21+
# that GenServer's `:DOWN` monitor (routing-row prune +
22+
# `handle_owner_down/1`), not `ExUnit.Callbacks.on_exit/1`.
1623
# * `@counter_key -> :counters.t()` — atomic counter for cheap
1724
# "any active scopes?" short-circuits, so config reads in
1825
# production cost essentially nothing.
@@ -29,8 +36,11 @@ defmodule Sentry.Test.Scope.Registry do
2936
# GenServers started via `start_supervised/1`).
3037
# 3. by_allow — walk `[pid | ancestors]`; reverse-allow lookup
3138
# for each candidate (the pid was explicitly
32-
# routed onto a scope via `allow/2` or
33-
# auto-allowed in `Config.put/1`).
39+
# routed onto a scope via
40+
# `Sentry.Test.allow_sentry_reports/2` /
41+
# `Sentry.Test.Config.allow/2`, or auto-allowed in
42+
# `Sentry.Test.Config.put/1` — all of which claim
43+
# through `Sentry.Test.Registry.claim_allow/3`).
3444
#
3545
# Globally-supervised processes (`:logger`, `:logger_sup`,
3646
# `Sentry.Supervisor`) have no caller/ancestor link to any test and

0 commit comments

Comments
 (0)