test: cover commandState and fillOverLimit
This commit is contained in:
1 parent
2e3c8efe2e
commit
3a979c096e
1 file changed
+106
@@ -157,3 +157,109 @@ defmodule Excache.WritePathTest do
|
||||
assert {1, conn} = Client.command(conn, ["LPUSH", "order:queue", "payload"])
|
||||
assert Task.await(waiter) == ["order:queue", "payload"]
|
||||
|
||||
log = flushedLog()
|
||||
|
||||
assert offsetOf(log, "LPUSH") < offsetOf(log, "LPOP")
|
||||
|
||||
conn = replayFromScratch(conn)
|
||||
|
||||
assert {0, _conn} = Client.command(conn, ["EXISTS", "order:queue"])
|
||||
end
|
||||
end
|
||||
|
||||
describe "the wake signal belongs to the command layer" do
|
||||
test "a push dispatched straight through the command router wakes a waiter", %{port: port} do
|
||||
waiter = blockingTask(port, ["BLPOP", "hook:queue", "2"])
|
||||
awaitWaiters("hook:queue", 1)
|
||||
|
||||
Command.execute(["LPUSH", "hook:queue", "direct"], commandState())
|
||||
|
||||
assert Task.await(waiter) == ["hook:queue", "direct"]
|
||||
end
|
||||
|
||||
test "a rename dispatched straight through the command router wakes a waiter", %{port: port} do
|
||||
assert {:ok, 1} = Store.rpush("hook:source", ["carried"])
|
||||
|
||||
waiter = blockingTask(port, ["BLPOP", "hook:target", "2"])
|
||||
awaitWaiters("hook:target", 1)
|
||||
|
||||
Command.execute(["RENAME", "hook:source", "hook:target"], commandState())
|
||||
|
||||
assert Task.await(waiter) == ["hook:target", "carried"]
|
||||
end
|
||||
end
|
||||
|
||||
defp commandState do
|
||||
Map.put(Excache.Command.Transaction.initial_state(), :subscriptions, MapSet.new())
|
||||
end
|
||||
|
||||
defp fillOverLimit(conn, listKey) do
|
||||
conn =
|
||||
Enum.reduce(1..30, conn, fn index, acc ->
|
||||
{{:simple, "OK"}, acc} = Client.command(acc, ["SET", "oom:key:#{index}", @payload])
|
||||
acc
|
||||
end)
|
||||
|
||||
{1, conn} = Client.command(conn, ["RPUSH", listKey, "value"])
|
||||
{flat, conn} = Client.command(conn, ["MEMORY", "STATS"])
|
||||
|
||||
allocated =
|
||||
flat
|
||||
|> Enum.chunk_every(2)
|
||||
|> Map.new(fn [name, value] -> {name, value} end)
|
||||
|> Map.fetch!("total.allocated")
|
||||
|
||||
{{:simple, "OK"}, conn} =
|
||||
Client.command(conn, ["CONFIG", "SET", "maxmemory", Integer.to_string(div(allocated, 2))])
|
||||
|
||||
conn
|
||||
end
|
||||
|
||||
defp subscribeTo(port, channel) do
|
||||
subscriber = Client.connect(port)
|
||||
{["subscribe", ^channel, 1], subscriber} = Client.command(subscriber, ["SUBSCRIBE", channel])
|
||||
subscriber
|
||||
end
|
||||
|
||||
defp blockingTask(port, args) do
|
||||
Task.async(fn ->
|
||||
client = Client.connect(port)
|
||||
{reply, _client} = Client.command(client, args)
|
||||
Client.close(client)
|
||||
reply
|
||||
end)
|
||||
end
|
||||
|
||||
defp awaitWaiters(key, count), do: awaitUntil(fn -> Blocking.waitingCount(key) == count end)
|
||||
|
||||
defp awaitUntil(check, attempts \\ 400) do
|
||||
cond do
|
||||
check.() ->
|
||||
:ok
|
||||
|
||||
attempts == 0 ->
|
||||
flunk("the expected registry state was never reached")
|
||||
|
||||
true ->
|
||||
Process.sleep(5)
|
||||
awaitUntil(check, attempts - 1)
|
||||
end
|
||||
end
|
||||
|
||||
defp offsetOf(log, needle) do
|
||||
{offset, _length} = :binary.match(log, needle)
|
||||
offset
|
||||
end
|
||||
|
||||
defp flushedLog do
|
||||
Aof.flush()
|
||||
{:ok, log} = File.read(Application.get_env(:excache, :aof_path))
|
||||
log
|
||||
end
|
||||
|
||||
defp replayFromScratch(conn) do
|
||||
Store.flushdb()
|
||||
Aof.replay(Application.get_env(:excache, :aof_path))
|
||||
conn
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user