Skip to content

Commit f4d4ff6

Browse files
committed
test: add tests for different auth methods (scram-sha-256, password, md5)
1 parent e1a6779 commit f4d4ff6

File tree

10 files changed

+160
-70
lines changed

10 files changed

+160
-70
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ priv/native/*
4141
/.pre-commit-config.yaml
4242
*.coverdata
4343
/tmp
44+
45+
.devenv/

config/test.exs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,32 @@ config :supavisor, Supavisor.Repo,
4141
pool_size: 10,
4242
port: 6432
4343

44+
config :supavisor, :test_auth_profiles,
45+
"scram-sha-256":
46+
{[
47+
hostname: "localhost",
48+
port: 6432,
49+
database: "postgres",
50+
username: "postgres",
51+
password: "postgres"
52+
], Supavisor.Repo},
53+
md5:
54+
{[
55+
hostname: "localhost",
56+
port: 6433,
57+
database: "postgres",
58+
username: "postgres",
59+
password: "postgres"
60+
], Supavisor.MD5Repo},
61+
password:
62+
{[
63+
hostname: "localhost",
64+
port: 6434,
65+
database: "postgres",
66+
username: "postgres",
67+
password: "postgres"
68+
], Supavisor.PasswordRepo}
69+
4470
# We don't run a server during test. If one is required,
4571
# you can enable the server option below.
4672
config :supavisor, SupavisorWeb.Endpoint,

docker-compose.db.yml

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,35 @@ services:
88
- "6432:5432"
99
volumes:
1010
- ./dev/postgres:/docker-entrypoint-initdb.d/
11-
# Uncomment to set MD5 authentication method on uninitialized databases
12-
# - ./dev/postgres/md5/etc/postgresql/pg_hba.conf:/etc/postgresql/pg_hba.conf
13-
# Uncomment to set password authentication method on uninitialized databases
14-
# - ./dev/postgres/password/etc/postgresql/pg_hba.conf:/etc/postgresql/pg_hba.conf
1511
command: postgres -c config_file=/etc/postgresql/postgresql.conf -c max_prepared_transactions=2000
1612
environment:
1713
POSTGRES_HOST: /var/run/postgresql
1814
POSTGRES_PASSWORD: postgres
19-
# Uncomment to set MD5 authentication method on uninitialized databases
20-
# POSTGRES_INITDB_ARGS: --auth-host=md5
21-
# Uncomment to set password authentication method on uninitialized databases
22-
# POSTGRES_INITDB_ARGS: --auth-host=password
15+
16+
db_md5:
17+
image: supabase/postgres:14.1.0.106
18+
container_name: supavisor-db-md5
19+
ports:
20+
- "6433:5432"
21+
volumes:
22+
- ./dev/postgres:/docker-entrypoint-initdb.d/
23+
- ./dev/postgres/md5/etc/postgresql/pg_hba.conf:/etc/postgresql/pg_hba.conf
24+
command: postgres -c config_file=/etc/postgresql/postgresql.conf -c max_prepared_transactions=2000
25+
environment:
26+
POSTGRES_HOST: /var/run/postgresql
27+
POSTGRES_PASSWORD: postgres
28+
POSTGRES_INITDB_ARGS: --auth-host=md5
29+
30+
db_password:
31+
image: supabase/postgres:14.1.0.106
32+
container_name: supavisor-db-password
33+
ports:
34+
- "6434:5432"
35+
volumes:
36+
- ./dev/postgres:/docker-entrypoint-initdb.d/
37+
- ./dev/postgres/password/etc/postgresql/pg_hba.conf:/etc/postgresql/pg_hba.conf
38+
command: postgres -c config_file=/etc/postgresql/postgresql.conf -c max_prepared_transactions=2000
39+
environment:
40+
POSTGRES_HOST: /var/run/postgresql
41+
POSTGRES_PASSWORD: postgres
42+
POSTGRES_INITDB_ARGS: --auth-host=password

lib/supavisor/client_handler.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,8 @@ defmodule Supavisor.ClientHandler do
741741
tag: :password_message,
742742
payload: {:md5, client_md5}
743743
}, _} <- receive_next(socket, "Timeout while waiting for the md5 exchange"),
744-
{:ok, key} <- authenticate_exchange(method, client_md5, secrets.().secret, salt) do
744+
{:ok, key} <-
745+
authenticate_exchange(method, client_md5, secrets.().secret, salt) do
745746
{:ok, key}
746747
else
747748
{:error, message} -> {:error, message}

priv/repo/seeds_after_migration.exs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,46 @@ alias Supavisor.Tenants
22
alias Supavisor.Repo
33
import Ecto.Adapters.SQL, only: [query: 3]
44

5-
db_conf = Application.get_env(:supavisor, Repo)
5+
auth_profiles_conf = Application.get_env(:supavisor, :test_auth_profiles)
66

77
tenant_name = "dev_tenant"
88

99
if Tenants.get_tenant_by_external_id(tenant_name) do
1010
Tenants.delete_tenant_by_external_id(tenant_name)
1111
end
1212

13-
if !Tenants.get_tenant_by_external_id("is_manager") do
14-
{:ok, _} =
15-
%{
16-
db_host: db_conf[:hostname],
17-
db_port: db_conf[:port],
18-
db_database: db_conf[:database],
19-
default_parameter_status: %{},
20-
external_id: "is_manager",
21-
require_user: false,
22-
auth_query: "SELECT rolname, rolpassword FROM pg_authid WHERE rolname=$1;",
23-
users: [
24-
%{
25-
"db_user" => db_conf[:username],
26-
"db_password" => db_conf[:password],
27-
"pool_size" => 2,
28-
"mode_type" => "transaction",
29-
"is_manager" => true,
30-
"pool_checkout_timeout" => 1000
31-
}
32-
]
33-
}
34-
|> Tenants.create_tenant()
35-
end
13+
auth_profiles_conf
14+
|> Enum.each(fn {key, {db_conf, _repo}} ->
15+
if !Tenants.get_tenant_by_external_id("is_manager_#{key}") do
16+
{:ok, _} =
17+
%{
18+
db_host: db_conf[:hostname],
19+
db_port: db_conf[:port],
20+
db_database: db_conf[:database],
21+
default_parameter_status: %{},
22+
external_id: "is_manager_#{key}",
23+
require_user: false,
24+
auth_query: "SELECT rolname, rolpassword FROM pg_authid WHERE rolname=$1;",
25+
users: [
26+
%{
27+
"db_user" => db_conf[:username],
28+
"db_password" => db_conf[:password],
29+
"pool_size" => 2,
30+
"mode_type" => "transaction",
31+
"is_manager" => true,
32+
"pool_checkout_timeout" => 1000
33+
}
34+
]
35+
}
36+
|> Tenants.create_tenant()
37+
end
38+
end)
3639

3740
["proxy_tenant1", "syn_tenant", "prom_tenant", "max_pool_tenant", "metrics_tenant"]
3841
|> Enum.each(fn tenant ->
3942
if !Tenants.get_tenant_by_external_id(tenant) do
43+
{db_conf, _repo} = auth_profiles_conf[:"scram-sha-256"]
44+
4045
{:ok, _} =
4146
%{
4247
db_host: db_conf[:hostname],

test/supavisor/monitoring/tenant_test.exs

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,37 +35,39 @@ defmodule Supavisor.PromEx.Plugins.TenantTest do
3535
end
3636
end
3737

38-
describe "execute_client_connections_lifetime" do
39-
setup ctx do
40-
create_instance([__MODULE__, ctx.line])
41-
end
38+
for {key, {auth_config, repo}} <- list_authentication_configs() do
39+
describe "execute_client_connections_lifetime when authentication method is #{key}" do
40+
setup ctx do
41+
create_instance([__MODULE__, ctx.line, unquote(key)], unquote(auth_config), unquote(repo))
42+
end
4243

43-
test "emits event for active client connections", ctx do
44-
start_supervised!(
45-
{SingleConnection,
46-
hostname: "localhost",
47-
port: Application.fetch_env!(:supavisor, :proxy_port_transaction),
48-
database: ctx.db,
49-
username: ctx.user,
50-
password: "postgres"}
51-
)
52-
53-
ref = attach_handler([:supavisor, :client, :connection, :lifetime])
54-
assert :ok = Tenant.execute_client_connections_lifetime()
55-
56-
assert_receive {^ref, {[:supavisor, :client, :connection, :lifetime], measurement, meta}}
57-
58-
assert %{lifetime: lifetime} = measurement
59-
assert lifetime >= 0
60-
61-
assert meta == %{
62-
tenant: ctx.db,
63-
user: String.split(ctx.user, ".") |> List.first(),
64-
mode: :transaction,
65-
type: :single,
66-
db_name: ctx.db,
67-
search_path: nil
68-
}
44+
test "emits event for active client connections", ctx do
45+
start_supervised!(
46+
{SingleConnection,
47+
hostname: "localhost",
48+
port: Application.fetch_env!(:supavisor, :proxy_port_transaction),
49+
database: ctx.db,
50+
username: ctx.user,
51+
password: "postgres"}
52+
)
53+
54+
ref = attach_handler([:supavisor, :client, :connection, :lifetime])
55+
assert :ok = Tenant.execute_client_connections_lifetime()
56+
57+
assert_receive {^ref, {[:supavisor, :client, :connection, :lifetime], measurement, meta}}
58+
59+
assert %{lifetime: lifetime} = measurement
60+
assert lifetime >= 0
61+
62+
assert meta == %{
63+
tenant: ctx.db,
64+
user: String.split(ctx.user, ".") |> List.first(),
65+
mode: :transaction,
66+
type: :single,
67+
db_name: ctx.db,
68+
search_path: nil
69+
}
70+
end
6971
end
7072
end
7173

test/support/e2e_case.ex

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,29 @@ defmodule Supavisor.E2ECase do
2727
Ecto.Adapters.SQL.Sandbox.unboxed_run(@repo, fun)
2828
end
2929

30-
def create_instance(external_id) do
30+
def create_instance(external_id, config \\ %{port: 6432, hostname: "localhost"}, repo \\ @repo)
31+
32+
def create_instance(external_id, config, repo) when is_list(config) do
33+
create_instance(external_id, Map.new(config), repo)
34+
end
35+
36+
def create_instance(external_id, config, repo) do
3137
external_id =
3238
external_id
3339
|> List.wrap()
3440
|> Enum.map_join("_", &String.replace(to_string(&1), ~r/\W/, "_"))
3541
|> String.downcase()
3642

3743
unboxed(fn ->
38-
assert {:ok, _} = @repo.query("DROP DATABASE IF EXISTS #{external_id}")
39-
assert {:ok, _} = @repo.query("CREATE DATABASE #{external_id}")
44+
assert {:ok, _} = repo.query("DROP DATABASE IF EXISTS #{external_id}")
45+
assert {:ok, _} = repo.query("CREATE DATABASE #{external_id}")
4046
end)
4147

4248
assert {:ok, tenant} =
4349
Supavisor.Tenants.create_tenant(%{
4450
default_parameter_status: %{},
45-
db_host: "localhost",
46-
db_port: 6432,
51+
db_host: config[:hostname],
52+
db_port: config[:port],
4753
db_database: external_id,
4854
auth_query: "SELECT rolname, rolpassword FROM pg_authid WHERE rolname=$1;",
4955
external_id: external_id,
@@ -63,10 +69,22 @@ defmodule Supavisor.E2ECase do
6369
_ = Supavisor.stop({{:single, external_id}, "postgres", :transaction, external_id, nil})
6470

6571
unboxed(fn ->
66-
assert {:ok, _} = @repo.query("DROP DATABASE #{external_id}")
72+
assert {:ok, _} = repo.query("DROP DATABASE #{external_id}")
6773
end)
6874
end)
6975

70-
{:ok, %{user: "postgres.#{external_id}", db: tenant.db_database, external_id: external_id}}
76+
{:ok,
77+
%{
78+
user: "postgres.#{external_id}",
79+
db: tenant.db_database,
80+
external_id: external_id,
81+
auth_config: config
82+
}}
83+
end
84+
85+
def list_authentication_configs do
86+
:supavisor
87+
|> Application.get_env(:test_auth_profiles)
88+
|> Macro.escape()
7189
end
7290
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
defmodule Supavisor.MD5Repo do
2+
use Ecto.Repo,
3+
otp_app: :supavisor,
4+
adapter: Ecto.Adapters.Postgres
5+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
defmodule Supavisor.PasswordRepo do
2+
use Ecto.Repo,
3+
otp_app: :supavisor,
4+
adapter: Ecto.Adapters.Postgres
5+
end

test/test_helper.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
Cachex.start_link(name: Supavisor.Cache)
44

5+
auth_profiles_conf = Application.get_env(:supavisor, :test_auth_profiles)
6+
7+
Supavisor.PasswordRepo.start_link(elem(auth_profiles_conf[:password], 0))
8+
9+
Supavisor.MD5Repo.start_link(elem(auth_profiles_conf[:md5], 0))
10+
511
logs =
612
case System.get_env("TEST_LOGS", "all") do
713
level when level in ~w[all true] ->

0 commit comments

Comments
 (0)