Skip to content

Commit 93a1f2d

Browse files
committed
fix: correct get_user_cache fuction and add tests
1 parent a44394d commit 93a1f2d

File tree

4 files changed

+85
-27
lines changed

4 files changed

+85
-27
lines changed

lib/supavisor/client_handler.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ defmodule Supavisor.ClientHandler do
252252
Logger.metadata(state: :exchange)
253253
sni_hostname = HandlerHelpers.try_get_sni(sock)
254254

255-
case Tenants.get_user_cache(type, user, tenant_or_alias, sni_hostname) do
255+
case Tenants.fetch_user_cache(type, user, tenant_or_alias, sni_hostname) do
256256
{:ok, info} ->
257257
db_name = db_name || info.tenant.db_database
258258

lib/supavisor/tenants.ex

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,46 +73,43 @@ defmodule Supavisor.Tenants do
7373

7474
def get_tenant(_, _), do: nil
7575

76-
@spec get_user_cache(:single | :cluster, String.t(), String.t() | nil, String.t() | nil) ::
76+
@spec fetch_user_cache(:single | :cluster, String.t(), String.t() | nil, String.t() | nil) ::
7777
{:ok, map()} | {:error, any()}
78-
def get_user_cache(type, user, external_id, sni_hostname) do
78+
def fetch_user_cache(type, user, external_id, sni_hostname) do
7979
cache_key = {:user_cache, type, user, external_id, sni_hostname}
8080

8181
case Cachex.fetch(Supavisor.Cache, cache_key, fn _key ->
82-
{:commit, {:cached, get_user(type, user, external_id, sni_hostname)},
83-
ttl: :timer.hours(24)}
82+
case fetch_user(type, user, external_id, sni_hostname) do
83+
{:ok, value} -> {:commit, {:cached, value}, ttl: :timer.hours(24)}
84+
{:error, reason} -> {:ignore, reason}
85+
end
8486
end) do
85-
{_, {:cached, value}} -> value
86-
{_, {:cached, value}, _} -> value
87+
{:ok, {:cached, value}} -> {:ok, value}
88+
{:commit, {:cached, value}, _} -> {:ok, value}
89+
{:ignore, error} -> {:error, error}
8790
end
8891
end
8992

90-
@spec get_user(atom(), String.t(), String.t() | nil, String.t() | nil) ::
93+
@spec fetch_user(atom(), String.t(), String.t() | nil, String.t() | nil) ::
9194
{:ok, map()} | {:error, any()}
92-
def get_user(_, _, nil, nil) do
95+
def fetch_user(_, _, nil, nil) do
9396
{:error, "Either external_id or sni_hostname must be provided"}
9497
end
9598

96-
def get_user(:cluster, user, external_id, sni_hostname) do
99+
def fetch_user(:cluster, user, external_id, sni_hostname) do
97100
query =
98-
from(ct in ClusterTenants,
99-
where: ct.cluster_alias == ^external_id and ct.active == true,
100-
limit: 1
101-
)
101+
from(ct in ClusterTenants, where: ct.cluster_alias == ^external_id and ct.active == true)
102102

103-
case Repo.all(query) do
104-
[%ClusterTenants{} = ct] ->
105-
get_user(:single, user, ct.tenant_external_id, sni_hostname)
106-
107-
[_ | _] ->
108-
{:error, :multiple_results}
103+
case Repo.one(query) do
104+
%ClusterTenants{} = ct ->
105+
fetch_user(:single, user, ct.tenant_external_id, sni_hostname)
109106

110107
_ ->
111108
{:error, :not_found}
112109
end
113110
end
114111

115-
def get_user(:single, user, external_id, sni_hostname) do
112+
def fetch_user(:single, user, external_id, sni_hostname) do
116113
query = build_user_query(user, external_id, sni_hostname)
117114

118115
case Repo.all(query) do

test/supavisor/tenants_test.exs

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,73 @@ defmodule Supavisor.TenantsTest do
7373
assert %Ecto.Changeset{} = Tenants.change_tenant(tenant)
7474
end
7575

76-
test "get_user/4" do
77-
_tenant = tenant_fixture()
78-
assert {:error, :not_found} = Tenants.get_user(:single, "no_user", "no_tenant", "")
76+
test "fetch_user_cache/4 returns a user from cache" do
77+
tenant =
78+
tenant_fixture(%{external_id: "user_cache_tenant", sni_hostname: "user.example.com"})
7979

80-
assert {:ok, %{tenant: _, user: _}} =
81-
Tenants.get_user(:single, "postgres", "dev_tenant", "")
80+
user = List.first(tenant.users)
81+
82+
assert {:error, "Either external_id or sni_hostname must be provided"} ==
83+
Tenants.fetch_user_cache(:single, user.db_user, nil, nil)
84+
end
85+
86+
test "fetch_user/4 returns :multiple_results when more than one user matches" do
87+
users_attrs = [
88+
%{
89+
"db_user" => "postgres",
90+
"db_password" => "postgres",
91+
"pool_size" => 3,
92+
"mode_type" => "session"
93+
},
94+
%{
95+
"db_user" => "postgres",
96+
"db_password" => "postgres",
97+
"pool_size" => 3,
98+
"mode_type" => "transaction"
99+
}
100+
]
101+
102+
_tenant = tenant_fixture(%{users: users_attrs})
103+
104+
assert {:error, :multiple_results} =
105+
Tenants.fetch_user(:single, "postgres", "dev_tenant", "")
106+
end
107+
108+
test "fetch_user/4 returns :not_found for missing user or tenant, and :ok for valid input" do
109+
tenant = tenant_fixture()
110+
user = List.first(tenant.users)
111+
112+
assert {:error, :not_found} = Tenants.fetch_user(:single, "no_user", "no_tenant", "")
113+
assert {:error, :not_found} = Tenants.fetch_user(:single, "postgres", nil, "")
114+
115+
assert {:ok, %{user: fetched_user, tenant: fetched_tenant}} =
116+
Tenants.fetch_user(:single, "postgres", "dev_tenant", "")
117+
118+
assert fetched_user.id == user.id
119+
assert fetched_tenant.id == tenant.id
120+
end
121+
122+
test "fetch_user/4 with :cluster mode returns :not_found for invalid tenant alias and :ok for valid alias" do
123+
cluster_tenant_attrs = %{
124+
type: "write",
125+
cluster_alias: "cluster_alias",
126+
tenant_external_id: "dev_tenant",
127+
active: true
128+
}
129+
130+
tenant = tenant_fixture()
131+
user = List.first(tenant.users)
132+
133+
_cluster =
134+
cluster_fixture(%{alias: "cluster_alias", cluster_tenants: [cluster_tenant_attrs]})
135+
136+
assert {:error, :not_found} == Tenants.fetch_user(:cluster, "postgres", "cluster", "")
137+
138+
assert {:ok, %{user: fetched_user, tenant: fetched_tenant}} =
139+
Tenants.fetch_user(:cluster, "postgres", "cluster_alias", "")
140+
141+
assert fetched_user.id == user.id
142+
assert fetched_tenant.id == tenant.id
82143
end
83144
end
84145

test/supavisor_web/controllers/tenant_controller_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ defmodule SupavisorWeb.TenantControllerTest do
180180
end
181181

182182
defp set_cache(external_id) do
183-
Supavisor.Tenants.get_user_cache(:single, "user", external_id, nil)
183+
Supavisor.Tenants.fetch_user_cache(:single, "user", external_id, nil)
184184
Supavisor.Tenants.get_tenant_cache(external_id, nil)
185185
end
186186

0 commit comments

Comments
 (0)