Packages
exq
0.23.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.2
Exq is a job processing library compatible with Resque / Sidekiq for the Elixir language.
Current section
Files
Jump to
Current section
Files
test/job_stat_test.exs
defmodule JobStatTest do
use ExUnit.Case
alias Exq.Redis.JobStat
alias Exq.Redis.Connection
alias Exq.Redis.JobQueue
alias Exq.Support.Process
alias Exq.Support.Job
alias Exq.Support.Time
alias Exq.Support.Node
defmodule EmptyMethodWorker do
def perform do
{:ok, "test"}
end
end
def dead_jobs_count(redis) do
{:ok, count} = Connection.q(redis, ["ZCOUNT", "test:dead", "-inf", "+inf"])
count
end
def enqueue_and_fail_job(redis) do
Connection.incr!(redis, "test:stat:failed")
{:ok, jid} = Exq.enqueue(Exq, "queue", EmptyMethodWorker, [])
{:ok, _job} = JobQueue.find_job(redis, "test", jid, "queue")
JobQueue.fail_job(redis, "test", %Exq.Support.Job{jid: jid}, "forced error")
{:ok, jid}
end
def create_process_info(host) do
process_info = %Process{
pid: inspect(self()),
host: host,
payload: %Job{},
run_at: Time.unix_seconds()
}
serialized = Exq.Support.Process.encode(process_info)
{process_info, serialized}
end
setup do
TestRedis.setup()
on_exit(fn -> TestRedis.teardown() end)
Exq.start_link()
:ok
end
test "show realtime statistics" do
{:ok, time1} = DateTime.from_unix(1_452_173_400_000, :millisecond)
{:ok, time2} = DateTime.from_unix(1_452_175_515_000, :millisecond)
JobStat.record_processed(:testredis, "test", nil, time1)
JobStat.record_processed(:testredis, "test", nil, time2)
JobStat.record_processed(:testredis, "test", nil, time1)
JobStat.record_failure(:testredis, "test", nil, nil, time1)
JobStat.record_failure(:testredis, "test", nil, nil, time2)
Exq.start_link(mode: :api, name: ExqApi)
{:ok, failures, successes} = Exq.Api.realtime_stats(ExqApi.Api)
assert List.keysort(failures, 0) == [
{"2016-01-07 13:30:00Z", "1"},
{"2016-01-07 14:05:15Z", "1"}
]
assert List.keysort(successes, 0) == [
{"2016-01-07 13:30:00Z", "2"},
{"2016-01-07 14:05:15Z", "1"}
]
end
test "show realtime statistics with no data" do
Exq.start_link(mode: :api, name: ExqApi)
{:ok, failures, successes} = Exq.Api.realtime_stats(ExqApi.Api)
assert List.keysort(failures, 0) == []
assert List.keysort(successes, 0) == []
end
test "remove queue" do
Exq.enqueue(Exq, "test_queue", EmptyMethodWorker, [])
assert Connection.smembers!(:testredis, "test:queues") == ["test_queue"]
assert Connection.llen!(:testredis, "test:queue:test_queue") == 1
JobStat.remove_queue(:testredis, "test", "test_queue")
assert Connection.smembers!(:testredis, "test:queues") == []
assert Connection.llen!(:testredis, "test:queue:test_queue") == 0
end
test "remove failed" do
{:ok, jid} = enqueue_and_fail_job(:testredis)
assert dead_jobs_count(:testredis) == 1
JobStat.remove_failed(:testredis, "test", jid)
assert dead_jobs_count(:testredis) == 0
assert Connection.get!(:testredis, "test:stat:failed") == "0"
end
test "prune dead nodes" do
namespace = "test"
JobStat.node_ping(:testredis, namespace, %Node{identity: "host123", busy: 1})
JobStat.node_ping(:testredis, namespace, %Node{identity: "host456", busy: 1})
{process_info, serialized} = create_process_info("host456")
JobStat.add_process(:testredis, namespace, process_info, serialized)
assert Enum.count(Exq.Redis.JobStat.processes(:testredis, namespace)) == 1
JobStat.prune_dead_nodes(:testredis, namespace)
assert ["host123", "host456"] == JobStat.node_ids(:testredis, namespace) |> Enum.sort()
Connection.del!(:testredis, "test:host456")
assert ["host123", "host456"] == JobStat.node_ids(:testredis, namespace) |> Enum.sort()
JobStat.prune_dead_nodes(:testredis, namespace)
assert ["host123"] == JobStat.node_ids(:testredis, namespace)
assert Enum.count(Exq.Redis.JobStat.processes(:testredis, namespace)) == 0
end
test "clear failed" do
Enum.each([1, 2, 3], fn _ -> enqueue_and_fail_job(:testredis) end)
assert dead_jobs_count(:testredis) == 3
JobStat.clear_failed(:testredis, "test")
assert dead_jobs_count(:testredis) == 0
assert Connection.get!(:testredis, "test:stat:failed") == "0"
end
test "add and remove process" do
namespace = "test"
JobStat.node_ping(:testredis, "test", %Node{identity: "host123", busy: 1})
{process_info, serialized} = create_process_info("host123")
JobStat.add_process(:testredis, namespace, process_info, serialized)
assert Enum.count(Exq.Redis.JobStat.processes(:testredis, namespace)) == 1
JobStat.remove_process(:testredis, namespace, process_info)
assert Enum.count(Exq.Redis.JobStat.processes(:testredis, namespace)) == 0
end
test "remove processes on boot" do
namespace = "test"
JobStat.node_ping(:testredis, "test", %Node{identity: "host123", busy: 1})
JobStat.node_ping(:testredis, "test", %Node{identity: "host456", busy: 1})
# add processes for multiple hosts
{local_process, serialized1} = create_process_info("host123")
JobStat.add_process(:testredis, namespace, local_process, serialized1)
{remote_process, serialized2} = create_process_info("host456")
JobStat.add_process(:testredis, namespace, remote_process, serialized2)
assert Enum.count(Exq.Redis.JobStat.processes(:testredis, namespace)) == 2
# Should cleanup only the host that is passed in
JobStat.cleanup_processes(:testredis, namespace, "host123")
processes = Exq.Redis.JobStat.processes(:testredis, namespace)
assert Enum.count(processes) == 1
assert Enum.find(processes, fn process -> process.host == "host456" end) != nil
end
end