Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions test/schema_cache/adapters/redis_adapter_set_ops_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
defmodule SchemaCache.Adapters.RedisAdapterSetOpsTest do
@moduledoc false

use SchemaCache.Test.RedisCase, async: false

alias SchemaCache.Test.RedisAdapter

describe "sadd/2" do
Comment thread
BobbieBarker marked this conversation as resolved.
test "adds a member to a set" do
assert :ok = RedisAdapter.sadd("my_set", 1)

Comment thread
BobbieBarker marked this conversation as resolved.
assert {:ok, members} = RedisAdapter.smembers("my_set")
assert 1 in members
end

test "with duplicate member is idempotent" do
RedisAdapter.sadd("my_set", 1)
RedisAdapter.sadd("my_set", 1)

assert {:ok, members} = RedisAdapter.smembers("my_set")
assert members == [1]
end
end

describe "srem/2" do
test "removes a specific member" do
RedisAdapter.sadd("my_set", 1)
RedisAdapter.sadd("my_set", 2)

assert :ok = RedisAdapter.srem("my_set", 1)

assert {:ok, members} = RedisAdapter.smembers("my_set")
assert 2 in members
refute 1 in members
end

test "on non-existent member returns :ok" do
RedisAdapter.sadd("my_set", 1)

assert :ok = RedisAdapter.srem("my_set", 999)

assert {:ok, members} = RedisAdapter.smembers("my_set")
assert 1 in members
end
end

describe "smembers/1" do
test "returns {:ok, members} for populated set" do
RedisAdapter.sadd("my_set", 1)
RedisAdapter.sadd("my_set", 2)
RedisAdapter.sadd("my_set", 3)

assert {:ok, members} = RedisAdapter.smembers("my_set")
assert is_list(members)
assert length(members) == 3
assert Enum.sort(members) == [1, 2, 3]
end
Comment thread
BobbieBarker marked this conversation as resolved.

test "returns {:ok, nil} for empty/non-existent set" do
assert {:ok, nil} = RedisAdapter.smembers("nonexistent_set")
Comment thread
BobbieBarker marked this conversation as resolved.
end
end

describe "mget/1" do
test "returns values for existing keys and nil for missing keys" do
RedisAdapter.put("key_1", "value_1", [])
RedisAdapter.put("key_2", "value_2", [])

assert {:ok, results} = RedisAdapter.mget(["key_1", "missing_key", "key_2"])
assert results == ["value_1", nil, "value_2"]
end
Comment thread
BobbieBarker marked this conversation as resolved.

test "with empty list returns {:ok, []}" do
assert {:ok, []} = RedisAdapter.mget([])
Comment thread
BobbieBarker marked this conversation as resolved.
end
end
end
54 changes: 54 additions & 0 deletions test/schema_cache/adapters/redis_adapter_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
defmodule SchemaCache.Adapters.RedisAdapterTest do
@moduledoc false

use SchemaCache.Test.RedisCase, async: false

alias SchemaCache.Test.RedisAdapter

describe "get/1" do
test "returns {:ok, nil} for missing keys" do
assert {:ok, nil} = RedisAdapter.get("nonexistent")
end

test "returns {:ok, value} for existing keys" do
RedisAdapter.put("key", "value", [])
assert {:ok, "value"} = RedisAdapter.get("key")
end

test "round-trips complex Elixir terms" do
value = %{nested: [1, :atom, {"tuple"}], binary: <<0, 255>>}
RedisAdapter.put("complex", value, [])
assert {:ok, ^value} = RedisAdapter.get("complex")
end
end
Comment thread
BobbieBarker marked this conversation as resolved.

describe "put/3" do
test "stores and retrieves values" do
assert :ok = RedisAdapter.put("key", %{data: true}, [])
assert {:ok, %{data: true}} = RedisAdapter.get("key")
end

test "overwrites existing values" do
RedisAdapter.put("key", "first", [])
RedisAdapter.put("key", "second", [])
assert {:ok, "second"} = RedisAdapter.get("key")
end

test "supports TTL option" do
Comment thread
BobbieBarker marked this conversation as resolved.
assert :ok = RedisAdapter.put("ttl_key", "value", ttl: 60_000)
assert {:ok, "value"} = RedisAdapter.get("ttl_key")
end
end

describe "delete/1" do
test "removes a key" do
RedisAdapter.put("key", "value", [])
assert :ok = RedisAdapter.delete("key")
assert {:ok, nil} = RedisAdapter.get("key")
end

test "returns :ok for nonexistent keys" do
assert :ok = RedisAdapter.delete("nonexistent")
end
end
end
2 changes: 2 additions & 0 deletions test/support/redis_adapter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ defmodule SchemaCache.Test.RedisAdapter do
end

@impl true
def mget([]), do: {:ok, []}
Comment thread
BobbieBarker marked this conversation as resolved.

Comment thread
BobbieBarker marked this conversation as resolved.
def mget(keys) do
case Redix.command(redis_conn(), ["MGET" | keys]) do
{:ok, values} ->
Expand Down
52 changes: 33 additions & 19 deletions test/support/redis_case.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,47 @@ defmodule SchemaCache.Test.RedisCase do

use ExUnit.CaseTemplate

using do
quote do
alias SchemaCache.Test.User
end
end
alias SchemaCache.Adapter

@ets_tables [
:schema_cache_ets,
Comment thread
BobbieBarker marked this conversation as resolved.
:schema_cache_ets_sets,
:schema_cache_key_to_id,
:schema_cache_id_to_key
]

setup do
Comment thread
BobbieBarker marked this conversation as resolved.
redis_url = Application.get_env(:schema_cache, :redis_url, "redis://localhost:6379")
{:ok, conn} = Redix.start_link(redis_url)

# Flush Redis before each test
{:ok, "OK"} = Redix.command(conn, ["FLUSHDB"])
case Redix.start_link(redis_url) do
{:ok, conn} ->
Comment thread
BobbieBarker marked this conversation as resolved.
{:ok, "OK"} = Redix.command(conn, ["FLUSHDB"])

for table <- @ets_tables do
if :ets.whereis(table) != :undefined do
:ets.delete_all_objects(table)
Comment thread
BobbieBarker marked this conversation as resolved.
end
end

# Make connection available to the adapter
Process.put(:schema_cache_redis_conn, conn)
Process.put(:schema_cache_redis_conn, conn)

# Set the adapter to Redis for this test
Application.put_env(:schema_cache, :adapter, SchemaCache.Test.RedisAdapter)
original_adapter = :persistent_term.get(:schema_cache_adapter)
original_caps = :persistent_term.get(:schema_cache_adapter_caps)

on_exit(fn ->
# Reset adapter back to ETS
Application.put_env(:schema_cache, :adapter, SchemaCache.Adapters.ETS)
:persistent_term.put(:schema_cache_adapter, SchemaCache.Test.RedisAdapter)
Comment thread
BobbieBarker marked this conversation as resolved.
Adapter.resolve_capabilities(SchemaCache.Test.RedisAdapter)

# Stop the connection
if Process.alive?(conn), do: GenServer.stop(conn)
end)
on_exit(fn ->
:persistent_term.put(:schema_cache_adapter, original_adapter)
Comment thread
BobbieBarker marked this conversation as resolved.
:persistent_term.put(:schema_cache_adapter_caps, original_caps)

%{redis_conn: conn}
if Process.alive?(conn), do: GenServer.stop(conn)
end)

%{redis_conn: conn}

{:error, _reason} ->
:skip
end
end
end