test: cover Excache.IntrospectionTest

This commit is contained in:
dualfroz committed 2026-09-10 21:26:12 +02:00
1 parent 6480adce44
commit 6f47ae847c
1 file changed
+158
+158
View File
@@ -0,0 +1,158 @@
defmodule Excache.IntrospectionTest do
use Excache.Test.ServerCase, async: false
alias Excache.Aof
alias Excache.Blocking
alias Excache.Command
alias Excache.Command.Introspection
alias Excache.Command.Introspection.Catalog
alias Excache.Command.Transaction
alias Excache.Config
alias Excache.Eviction.Runner
alias Excache.Memory
setup do
Config.reset()
Runner.resetStats()
on_exit(&Config.reset/0)
:ok
end
describe "INFO" do
test "answers with every default section in the documented order", %{conn: conn} do
assert {text, _conn} = Client.command(conn, ["INFO"])
assert sections(text) == [
"Server",
"Clients",
"Memory",
"Persistence",
"Stats",
"Replication",
"Keyspace"
]
assert String.ends_with?(text, "\r\n\r\n")
end
test "the server section reports the running system, not placeholders", %{conn: conn} do
assert {text, _conn} = Client.command(conn, ["INFO", "server"])
assert sections(text) == ["Server"]
values = fields(text)
assert values["redis_mode"] == "standalone"
assert values["excache_version"] == to_string(Application.spec(:excache, :vsn))
assert values["run_id"] =~ ~r/^[0-9a-f]{40}$/
assert values["arch_bits"] == Integer.to_string(:erlang.system_info(:wordsize) * 8)
assert values["process_id"] == to_string(:os.getpid())
assert values["elixir_version"] == System.version()
assert values["otp_release"] == to_string(:erlang.system_info(:otp_release))
assert String.to_integer(values["uptime_in_seconds"]) >= 0
end
test "used_memory matches what the memory accountant reports", %{conn: conn} do
assert {{:simple, "OK"}, conn} =
Client.command(conn, ["SET", "solo", String.duplicate("payload", 40)])
assert {text, _conn} = Client.command(conn, ["INFO", "memory"])
values = fields(text)
assert sections(text) == ["Memory"]
assert String.to_integer(values["used_memory"]) == Memory.usedMemory()
assert values["maxmemory"] == "0"
assert values["maxmemory_policy"] == "noeviction"
assert values["used_memory_human"] =~ ~r/^[0-9.]+[BKMG]$/
dataset = String.to_integer(values["used_memory_dataset"])
overhead = String.to_integer(values["used_memory_overhead"])
assert dataset + overhead == String.to_integer(values["used_memory"])
end
test "the keyspace section counts live keys, volatile keys and the mean ttl", %{conn: conn} do
assert {text, conn} = Client.command(conn, ["INFO", "keyspace"])
refute String.contains?(text, "db0")
assert {{:simple, "OK"}, conn} = Client.command(conn, ["SET", "plain", "one"])
assert {{:simple, "OK"}, conn} = Client.command(conn, ["SET", "other", "two"])
assert {{:simple, "OK"}, conn} = Client.command(conn, ["SET", "timed", "three"])
assert {1, conn} = Client.command(conn, ["EXPIRE", "timed", "120"])
assert {text, _conn} = Client.command(conn, ["INFO", "keyspace"])
assert %{"db0" => summary} = fields(text)
assert [keys, expires, avgTtl] =
Regex.run(~r/keys=(\d+),expires=(\d+),avg_ttl=(\d+)/, summary,
capture: :all_but_first
)
assert keys == "3"
assert expires == "1"
assert String.to_integer(avgTtl) > 118_000
assert String.to_integer(avgTtl) <= 120_000
end
test "the persistence section reads the real append only file", %{conn: conn} do
assert {{:simple, "OK"}, conn} = Client.command(conn, ["SET", "durable", "value"])
:ok = Aof.flush()
assert {text, _conn} = Client.command(conn, ["INFO", "persistence"])
values = fields(text)
assert values["aof_enabled"] == "1"
assert values["aof_fsync_policy"] == "everysec"
assert values["loading"] == "0"
size = String.to_integer(values["aof_current_size"])
assert size > 0
assert size == File.stat!(Aof.path()).size
end
test "the stats section counts connections and eviction refusals", %{conn: conn, port: port} do
assert {text, conn} = Client.command(conn, ["INFO", "stats"])
before = String.to_integer(fields(text)["total_connections_received"])
extra = Client.connect(port)
assert {{:simple, "PONG"}, _extra} = Client.command(extra, ["PING"])
assert {text, conn} = Client.command(conn, ["INFO", "stats"])
values = fields(text)
assert String.to_integer(values["total_connections_received"]) == before + 1
assert String.to_integer(values["total_net_input_bytes"]) > 0
assert values["evicted_keys"] == "0"
assert values["oom_rejections"] == "0"
assert {{:simple, "OK"}, conn} =
Client.command(conn, ["SET", "filler", String.duplicate("x", 128)])
assert {{:simple, "OK"}, conn} = Client.command(conn, ["CONFIG", "SET", "maxmemory", "1"])
assert {{:error, "OOM" <> _}, conn} = Client.command(conn, ["SET", "toobig", "value"])
assert {{:simple, "OK"}, conn} = Client.command(conn, ["CONFIG", "SET", "maxmemory", "0"])
assert {text, _conn} = Client.command(conn, ["INFO", "stats"])
assert String.to_integer(fields(text)["oom_rejections"]) > 0
Client.close(extra)
end
test "the replication section tells the truth about being a lone master", %{conn: conn} do
assert {text, _conn} = Client.command(conn, ["INFO", "replication"])
values = fields(text)
assert values["role"] == "master"
assert values["connected_slaves"] == "0"
assert values["master_failover_state"] == "no-failover"
assert values["repl_backlog_active"] == "0"
end
test "INFO all and INFO everything add the cpu section", %{conn: conn} do
assert {plain, conn} = Client.command(conn, ["INFO"])
refute "Cpu" in sections(plain)
assert {all, conn} = Client.command(conn, ["INFO", "all"])
assert "Cpu" in sections(all)
assert {everything, conn} = Client.command(conn, ["INFO", "everything"])
assert sections(everything) == sections(all)