Skip to content

Commit

Permalink
remove psql from tests
Browse files Browse the repository at this point in the history
  • Loading branch information
abc3 committed Dec 18, 2023
1 parent d95f551 commit 3b07af0
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 17 deletions.
81 changes: 64 additions & 17 deletions test/integration/proxy_test.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule Supavisor.Integration.ProxyTest do
require Logger
use Supavisor.DataCase, async: true
alias Postgrex, as: P

Expand Down Expand Up @@ -29,33 +30,39 @@ defmodule Supavisor.Integration.ProxyTest do
end

test "prepared statement", %{proxy: proxy} do
prepare_sql =
"PREPARE tenant (text) AS SELECT id, external_id FROM _supavisor.tenants WHERE external_id = $1;"

db_conf = Application.get_env(:supavisor, Repo)

url = """
postgresql://#{db_conf[:username] <> "." <> @tenant}:#{db_conf[:password]}\
@#{db_conf[:hostname]}:#{Application.get_env(:supavisor, :proxy_port_transaction)}/postgres
"""
{:ok, pid} =
Keyword.merge(db_conf, username: db_conf[:username] <> "." <> @tenant)
|> single_connection(Application.get_env(:supavisor, :proxy_port_transaction))

prepare_sql =
"PREPARE tenant (text) AS SELECT id, external_id FROM _supavisor.tenants WHERE external_id = $1;"
assert [%Postgrex.Result{command: :prepare}] =
P.SimpleConnection.call(pid, {:query, prepare_sql})

{result, _} = System.cmd("psql", [url, "-c", prepare_sql], stderr_to_stdout: true)
assert result =~ "PREPARE"
:timer.sleep(500)

{result, _} =
System.cmd("psql", [url, "-c", "EXECUTE tenant('#{@tenant}');"], stderr_to_stdout: true)
assert {_, %Postgrex.Result{command: :select}} =
Postgrex.query(proxy, "EXECUTE tenant('#{@tenant}');", [])

assert result =~ "#{@tenant}\n(1 row)"
:gen_statem.stop(pid)
end

test "the wrong password" do
Process.flag(:trap_exit, true)
db_conf = Application.get_env(:supavisor, Repo)

url =
"postgresql://#{db_conf[:username] <> "." <> @tenant}:no_pass@#{db_conf[:hostname]}:#{Application.get_env(:supavisor, :proxy_port_transaction)}/postgres"

{result, _} = System.cmd("psql", [url], stderr_to_stdout: true)
assert result =~ "error received from server in SCRAM exchange: Wrong password"
assert {:error,
{_,
{:stop,
%Postgrex.Error{
message: "error received in SCRAM server final message: \"Wrong password\""
}, _}}} = parse_uri(url) |> single_connection()
end

test "insert", %{proxy: proxy, origin: origin} do
Expand Down Expand Up @@ -172,7 +179,7 @@ defmodule Supavisor.Integration.ProxyTest do
url =
"postgresql://transaction.proxy_tenant:#{db_conf[:password]}@#{db_conf[:hostname]}:#{Application.get_env(:supavisor, :proxy_port_transaction)}/postgres"

psql_pid = spawn(fn -> System.cmd("psql", [url]) end)
{:ok, pid} = parse_uri(url) |> single_connection()

:timer.sleep(500)

Expand All @@ -185,16 +192,56 @@ defmodule Supavisor.Integration.ProxyTest do
{state, %{db_pid: db_pid}} = :sys.get_state(client_pid)

assert {:idle, nil} = {state, db_pid}
Process.exit(psql_pid, :kill)
:gen_statem.stop(pid)
end

test "limit client connections" do
Process.flag(:trap_exit, true)
db_conf = Application.get_env(:supavisor, Repo)

url =
"postgresql://max_clients.proxy_tenant:#{db_conf[:password]}@#{db_conf[:hostname]}:#{Application.get_env(:supavisor, :proxy_port_transaction)}/postgres?sslmode=disable"

{result, _} = System.cmd("psql", [url], stderr_to_stdout: true)
assert result =~ "FATAL: Max client connections reached"
assert =
{:error,
{_,
{:stop,
%Postgrex.Error{
postgres: %{
code: :internal_error,
message: "Max client connections reached",
pg_code: "XX000",
severity: "FATAL",
unknown: "FATAL"
}
}, _}}} = parse_uri(url) |> single_connection()
end

defp single_connection(db_conf, c_port \\ nil) when is_list(db_conf) do
port = c_port || db_conf[:port]

[
hostname: db_conf[:hostname],
port: port,
database: db_conf[:database],
password: db_conf[:password],
username: db_conf[:username],
pool_size: 1
]
|> SingleConnection.connect()
end

defp parse_uri(uri) do
%URI{
userinfo: userinfo,
host: host,
port: port,
path: path
} = URI.parse(uri)

[username, pass] = String.split(userinfo, ":")
database = String.replace(path, "/", "")

[hostname: host, port: port, database: database, password: pass, username: username]
end
end
34 changes: 34 additions & 0 deletions test/support/fixtures/single_connection.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule SingleConnection do
alias Postgrex, as: P
@behaviour P.SimpleConnection

def connect(conf) do
P.SimpleConnection.start_link(__MODULE__, [], conf)
end

@impl true
def init(_args) do
{:ok, %{from: nil}}
end

@impl true
def handle_call({:query, query}, from, state) do
{:query, query, %{state | from: from}}
end

def handle_result(results, state) when is_list(results) do
IO.inspect({213, results})
P.SimpleConnection.reply(state.from, results)
{:noreply, state}
end

@impl true
def handle_result(%Postgrex.Error{} = error, state) do
IO.inspect({213, error})
P.SimpleConnection.reply(state.from, error)
{:noreply, state}
end

@impl true
def notify(_, _, _), do: :ok
end

0 comments on commit 3b07af0

Please sign in to comment.