Skip to content

Commit 96e4c57

Browse files
committed
Integration test setup for OpenTelemetry support
1 parent e666875 commit 96e4c57

File tree

30 files changed

+1061
-48
lines changed

30 files changed

+1061
-48
lines changed

test_integrations/phoenix_app/config/config.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import Config
99

1010
config :phoenix_app,
11+
ecto_repos: [PhoenixApp.Repo],
1112
generators: [timestamp_type: :utc_datetime]
1213

1314
# Configures the endpoint
@@ -59,6 +60,11 @@ config :logger, :console,
5960

6061
config :phoenix, :json_library, if(Code.ensure_loaded?(JSON), do: JSON, else: Jason)
6162

63+
config :opentelemetry, span_processor: {Sentry.OpenTelemetry.SpanProcessor, []}
64+
65+
config :opentelemetry,
66+
sampler: {Sentry.OpenTelemetry.Sampler, [drop: ["Elixir.Oban.Stager process"]]}
67+
6268
# Import environment specific config. This must remain at the bottom
6369
# of this file so it overrides the configuration defined above.
6470
import_config "#{config_env()}.exs"

test_integrations/phoenix_app/config/dev.exs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import Config
22

3+
# Configure your database
4+
config :phoenix_app, PhoenixApp.Repo,
5+
adapter: Ecto.Adapters.SQLite3,
6+
database: "db/dev.sqlite3"
7+
38
# For development, we disable any cache and enable
49
# debugging and code reloading.
510
#
@@ -73,3 +78,19 @@ config :phoenix_live_view,
7378

7479
# Disable swoosh api client as it is only required for production adapters.
7580
config :swoosh, :api_client, false
81+
82+
dsn =
83+
if System.get_env("SENTRY_LOCAL"),
84+
do: System.get_env("SENTRY_DSN_LOCAL"),
85+
else: System.get_env("SENTRY_DSN")
86+
87+
config :sentry,
88+
dsn: dsn,
89+
environment_name: :dev,
90+
enable_source_code_context: true,
91+
send_result: :sync
92+
93+
config :phoenix_app, Oban,
94+
repo: PhoenixApp.Repo,
95+
engine: Oban.Engines.Lite,
96+
queues: [default: 10, background: 5]

test_integrations/phoenix_app/config/test.exs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import Config
22

3+
# Configure your database
4+
config :phoenix_app, PhoenixApp.Repo,
5+
adapter: Ecto.Adapters.SQLite3,
6+
pool: Ecto.Adapters.SQL.Sandbox,
7+
database: "db/test.sqlite3"
8+
39
# We don't run a server during test. If one is required,
410
# you can enable the server option below.
511
config :phoenix_app, PhoenixAppWeb.Endpoint,
@@ -24,9 +30,13 @@ config :phoenix_live_view,
2430
enable_expensive_runtime_checks: true
2531

2632
config :sentry,
27-
dsn: "http://public:secret@localhost:8080/1",
28-
environment_name: Mix.env(),
33+
dsn: nil,
34+
environment_name: :dev,
2935
enable_source_code_context: true,
30-
root_source_code_paths: [File.cwd!()],
31-
test_mode: true,
32-
send_result: :sync
36+
send_result: :sync,
37+
test_mode: true
38+
39+
config :phoenix_app, Oban,
40+
repo: PhoenixApp.Repo,
41+
engine: Oban.Engines.Lite,
42+
queues: [default: 10, background: 5]
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
defmodule PhoenixApp.Accounts do
2+
@moduledoc """
3+
The Accounts context.
4+
"""
5+
6+
import Ecto.Query, warn: false
7+
alias PhoenixApp.Repo
8+
9+
alias PhoenixApp.Accounts.User
10+
11+
@doc """
12+
Returns the list of users.
13+
14+
## Examples
15+
16+
iex> list_users()
17+
[%User{}, ...]
18+
19+
"""
20+
def list_users do
21+
Repo.all(User)
22+
end
23+
24+
@doc """
25+
Gets a single user.
26+
27+
Raises `Ecto.NoResultsError` if the User does not exist.
28+
29+
## Examples
30+
31+
iex> get_user!(123)
32+
%User{}
33+
34+
iex> get_user!(456)
35+
** (Ecto.NoResultsError)
36+
37+
"""
38+
def get_user!(id), do: Repo.get!(User, id)
39+
40+
@doc """
41+
Creates a user.
42+
43+
## Examples
44+
45+
iex> create_user(%{field: value})
46+
{:ok, %User{}}
47+
48+
iex> create_user(%{field: bad_value})
49+
{:error, %Ecto.Changeset{}}
50+
51+
"""
52+
def create_user(attrs \\ %{}) do
53+
%User{}
54+
|> User.changeset(attrs)
55+
|> Repo.insert()
56+
end
57+
58+
@doc """
59+
Updates a user.
60+
61+
## Examples
62+
63+
iex> update_user(user, %{field: new_value})
64+
{:ok, %User{}}
65+
66+
iex> update_user(user, %{field: bad_value})
67+
{:error, %Ecto.Changeset{}}
68+
69+
"""
70+
def update_user(%User{} = user, attrs) do
71+
user
72+
|> User.changeset(attrs)
73+
|> Repo.update()
74+
end
75+
76+
@doc """
77+
Deletes a user.
78+
79+
## Examples
80+
81+
iex> delete_user(user)
82+
{:ok, %User{}}
83+
84+
iex> delete_user(user)
85+
{:error, %Ecto.Changeset{}}
86+
87+
"""
88+
def delete_user(%User{} = user) do
89+
Repo.delete(user)
90+
end
91+
92+
@doc """
93+
Returns an `%Ecto.Changeset{}` for tracking user changes.
94+
95+
## Examples
96+
97+
iex> change_user(user)
98+
%Ecto.Changeset{data: %User{}}
99+
100+
"""
101+
def change_user(%User{} = user, attrs \\ %{}) do
102+
User.changeset(user, attrs)
103+
end
104+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
defmodule PhoenixApp.Accounts.User do
2+
use Ecto.Schema
3+
import Ecto.Changeset
4+
5+
schema "users" do
6+
field :name, :string
7+
field :age, :integer
8+
9+
timestamps(type: :utc_datetime)
10+
end
11+
12+
@doc false
13+
def changeset(user, attrs) do
14+
user
15+
|> cast(attrs, [:name, :age])
16+
|> validate_required([:name, :age])
17+
end
18+
end

test_integrations/phoenix_app/lib/phoenix_app/application.ex

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,28 @@ defmodule PhoenixApp.Application do
77

88
@impl true
99
def start(_type, _args) do
10+
:ok = Application.ensure_started(:inets)
11+
12+
:logger.add_handler(:my_sentry_handler, Sentry.LoggerHandler, %{
13+
config: %{metadata: [:file, :line]}
14+
})
15+
16+
# OpentelemetryBandit.setup()
17+
OpentelemetryPhoenix.setup(adapter: :bandit)
18+
OpentelemetryOban.setup()
19+
OpentelemetryEcto.setup([:phoenix_app, :repo], db_statement: :enabled)
20+
1021
children = [
1122
PhoenixAppWeb.Telemetry,
23+
PhoenixApp.Repo,
24+
{Ecto.Migrator,
25+
repos: Application.fetch_env!(:phoenix_app, :ecto_repos), skip: skip_migrations?()},
1226
{DNSCluster, query: Application.get_env(:phoenix_app, :dns_cluster_query) || :ignore},
1327
{Phoenix.PubSub, name: PhoenixApp.PubSub},
1428
# Start the Finch HTTP client for sending emails
1529
{Finch, name: PhoenixApp.Finch},
16-
# Start a worker by calling: PhoenixApp.Worker.start_link(arg)
17-
# {PhoenixApp.Worker, arg},
30+
# Start Oban
31+
{Oban, Application.fetch_env!(:phoenix_app, Oban)},
1832
# Start to serve requests, typically the last entry
1933
PhoenixAppWeb.Endpoint
2034
]
@@ -25,12 +39,15 @@ defmodule PhoenixApp.Application do
2539
Supervisor.start_link(children, opts)
2640
end
2741

28-
# TODO: Uncomment if we ever move the endpoint from test/support to the phoenix_app dir
2942
# Tell Phoenix to update the endpoint configuration
3043
# whenever the application is updated.
31-
# @impl true
32-
# def config_change(changed, _new, removed) do
33-
# PhoenixAppWeb.Endpoint.config_change(changed, removed)
34-
# :ok
35-
# end
44+
@impl true
45+
def config_change(changed, _new, removed) do
46+
PhoenixAppWeb.Endpoint.config_change(changed, removed)
47+
:ok
48+
end
49+
50+
defp skip_migrations?() do
51+
System.get_env("RELEASE_NAME") != nil
52+
end
3653
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
defmodule PhoenixApp.Repo do
2+
use Ecto.Repo,
3+
otp_app: :phoenix_app,
4+
adapter: Ecto.Adapters.SQLite3
5+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
defmodule PhoenixApp.Workers.TestWorker do
2+
use Oban.Worker
3+
4+
@impl Oban.Worker
5+
def perform(%Oban.Job{args: %{"sleep_time" => sleep_time, "should_fail" => should_fail}}) do
6+
# Simulate some work
7+
Process.sleep(sleep_time)
8+
9+
if should_fail do
10+
raise "Simulated failure in test worker"
11+
else
12+
:ok
13+
end
14+
end
15+
16+
def perform(%Oban.Job{args: %{"sleep_time" => sleep_time}}) do
17+
# Simulate some work
18+
Process.sleep(sleep_time)
19+
:ok
20+
end
21+
end
Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
11
defmodule PhoenixAppWeb.PageController do
22
use PhoenixAppWeb, :controller
33

4+
require OpenTelemetry.Tracer, as: Tracer
5+
6+
alias PhoenixApp.{Repo, User}
7+
48
def home(conn, _params) do
5-
# The home page is often custom made,
6-
# so skip the default app layout.
79
render(conn, :home, layout: false)
810
end
911

1012
def exception(_conn, _params) do
1113
raise "Test exception"
1214
end
15+
16+
def transaction(conn, _params) do
17+
Tracer.with_span "test_span" do
18+
:timer.sleep(100)
19+
end
20+
21+
render(conn, :home, layout: false)
22+
end
23+
24+
def users(conn, _params) do
25+
Repo.all(User) |> Enum.map(& &1.name)
26+
27+
render(conn, :home, layout: false)
28+
end
1329
end

test_integrations/phoenix_app/lib/phoenix_app_web/endpoint.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ defmodule PhoenixAppWeb.Endpoint do
3535
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
3636
plug Phoenix.LiveReloader
3737
plug Phoenix.CodeReloader
38-
plug Phoenix.Ecto.CheckRepoStatus, otp_app: :phoenix_app
3938
end
4039

4140
plug Phoenix.LiveDashboard.RequestLogger,

0 commit comments

Comments
 (0)