test: cover Excache.IntrospectionTest
This commit is contained in:
1 parent
6480adce44
commit
6f47ae847c
1 file changed
+158
@@ -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)
|
||||||
|
|
||||||
Reference in new issue
Block a user