Skip to content

Commit

Permalink
Improve behavior of :test_mode/:dsn
Browse files Browse the repository at this point in the history
  • Loading branch information
whatyouhide committed Mar 12, 2024
1 parent faa5dc7 commit 7f8442e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 5 deletions.
4 changes: 4 additions & 0 deletions lib/sentry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ defmodule Sentry do
LoggerUtils.log("Cannot report event without message or exception: #{inspect(event)}")
:ignored

# If we're in test mode, let's send the event down the pipeline anyway.
Config.test_mode?() ->
Client.send_event(event, opts)

!Config.dsn() ->
:ignored

Expand Down
5 changes: 4 additions & 1 deletion lib/sentry/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ defmodule Sentry.Config do
doc: """
The DSN for your Sentry project. If this is not set, Sentry will not be enabled.
If the `SENTRY_DSN` environment variable is set, it will be used as the default value.
If `:test_mode` is `true`, the `:dsn` option is sometimes ignored; see `Sentry.Test`
for more information.
"""
],
environment_name: [
Expand Down Expand Up @@ -200,7 +202,8 @@ defmodule Sentry.Config do
doc: """
Whether to enable *test mode*. When test mode is enabled, the SDK will check whether
there is a process **collecting events** and avoid sending those events if that's the
case. This is useful for testing. See `Sentry.Test`.
case. This is useful for testing—see `Sentry.Test`. `:test_mode` works in tandem
with `:dsn`; this is described in detail in `Sentry.Test`.
"""
],
integrations: [
Expand Down
30 changes: 28 additions & 2 deletions lib/sentry/test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,32 @@ defmodule Sentry.Test do
## Usage
This module is based on **collecting** reported events and then retrieving
them to perform assertions. You can start collecting events from a process
them to perform assertions. The functionality here is only available if the
`:test_mode` configuration option is set to `true`—see
[`Sentry`'s configuration section](sentry.html#module-configuration).
You can start collecting events from a process
by calling `start_collecting_sentry_reports/0`. Then, you can use Sentry
as normal and report events (through functions such as `Sentry.capture_message/1`
or `Sentry.capture_exception/1`). Finally, you can retrieve the collected events
by calling `pop_sentry_reports/0`.
> #### Test Mode and DSN {: .info}
>
> If `:test_mode` is `true`, the `:dsn` option behaves differently. When `:dsn` is
> not set or `nil` and you're collecting events, you'll still be able to collect
> events—even if under normal circumstances a missing `:dsn` means events don't get
> reported. If `:dsn` is `nil` and you're not collecting events, the event is simply
> ignored. See the table below for a summary for this behavior.
| `:test_mode` | `:dsn` | Collecting events? | Behavior |
|--------------|--------|--------------------|--------------------------------------------------------|
| `true` | `nil` | yes | Event is collected |
| `true` | `nil` | no | Event is ignored (silently) |
| `true` | set | yes | Event is collected |
| `true` | set | no | Makes HTTP request to configured DSN (could be Bypass) |
| `false` | `nil` | irrelevant | Ignores event |
| `false` | set | irrelevant | Makes HTTP request to configured DSN (could be Bypass) |
## Examples
Let's imagine writing a test using the functions in this module. First, we need to
Expand Down Expand Up @@ -64,6 +84,7 @@ defmodule Sentry.Test do
@spec maybe_collect(Sentry.Event.t()) :: :collected | :not_collecting
def maybe_collect(%Sentry.Event{} = event) do
if Sentry.Config.test_mode?() do
dsn_set? = not is_nil(Sentry.Config.dsn())
ensure_ownership_server_started()

case NimbleOwnership.fetch_owner(@server, callers(), @key) do
Expand All @@ -81,8 +102,13 @@ defmodule Sentry.Test do
raise ArgumentError, "cannot collect Sentry reports: #{Exception.message(error)}"
end

:error ->
:error when dsn_set? ->
:not_collecting

# If the :dsn option is not set and we didn't capture the event, it's alright,
# we can just swallow it.
:error ->
:collected
end
else
:not_collecting
Expand Down
10 changes: 8 additions & 2 deletions test/sentry_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,18 @@ defmodule SentryTest do
assert logged_count == 2
end

test "does not send events if :dsn is not configured or nil" do
put_test_config(dsn: nil)
test "does not send events if :dsn is not configured or nil (if not in test mode)" do
put_test_config(dsn: nil, test_mode: false)
event = Sentry.Event.transform_exception(%RuntimeError{message: "oops"}, [])
assert :ignored = Sentry.send_event(event)
end

test "if in test mode, swallows events if the :dsn is nil" do
put_test_config(dsn: nil, test_mode: true)
event = Sentry.Event.transform_exception(%RuntimeError{message: "oops"}, [])
assert {:ok, ""} = Sentry.send_event(event)
end

describe "send_check_in/1" do
test "posts a check-in with all the explicit arguments", %{bypass: bypass} do
put_test_config(environment_name: "test", release: "1.3.2")
Expand Down

0 comments on commit 7f8442e

Please sign in to comment.