Current section

Files

Jump to
exq test exq_test.exs
Raw

test/exq_test.exs

Code.require_file "test_helper.exs", __DIR__
defmodule ExqTest do
use ExUnit.Case
use Timex
import ExqTestUtil
defmodule PerformWorker do
def perform do
send :exqtest, {:worked}
end
end
defmodule PerformArgWorker do
def perform(arg) do
send :exqtest, {:worked, arg}
end
end
defmodule SleepWorker do
def perform(time, message) do
:timer.sleep(time)
send :exqtest, {message}
end
end
defmodule CustomMethodWorker do
def simple_perform do
end
end
defmodule MissingMethodWorker do
end
defmodule FailWorker do
def failure_perform do
_ = :num + 1
send :exqtest, {:worked}
end
end
setup do
TestRedis.setup
on_exit fn ->
wait
TestRedis.teardown
end
:ok
end
test "start using registered name" do
{:ok, exq_sup} = Exq.start_link([host: redis_host, port: redis_port, name: :custom_manager, namespace: "test"])
assert_exq_up(:custom_manager)
stop_process(exq_sup)
end
test "start multiple exq instances using registered name" do
{:ok, sup1} = Exq.start_link([host: redis_host, port: redis_port, name: :custom_manager1, namespace: "test"])
assert_exq_up(:custom_manager1)
{:ok, sup2} = Exq.start_link([host: redis_host, port: redis_port, name: :custom_manager2, namespace: "test"])
assert_exq_up(:custom_manager2)
stop_process(sup1)
stop_process(sup2)
end
test "enqueue and run job" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test"])
{:ok, _} = Exq.enqueue(:exq_t, "default", ExqTest.PerformWorker, [])
wait
assert_received {:worked}
stop_process(sup)
end
test "enqueue_in and run a job" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test",
scheduler_enable: true, scheduler_poll_timeout: 5])
{:ok, _} = Exq.enqueue_in(:exq_t, "default", 0, ExqTest.PerformWorker, [])
wait_long
assert_received {:worked}
stop_process(sup)
end
test "enqueue_at and run a job" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test",
scheduler_enable: true, scheduler_poll_timeout: 5])
{:ok, _} = Exq.enqueue_at(:exq_t, "default", Time.now, ExqTest.PerformWorker, [])
wait_long
assert_received {:worked}
stop_process(sup)
end
test "enqueue with separate enqueuer" do
Process.register(self, :exqtest)
{:ok, exq_sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test"])
{:ok, enq_sup} = Exq.Enqueuer.start_link([name: :exq_e, host: redis_host, port: redis_port, namespace: "test"])
{:ok, _} = Exq.Enqueuer.enqueue(:exq_e, "default", ExqTest.PerformWorker, [])
wait_long
assert_received {:worked}
stop_process(exq_sup)
stop_process(enq_sup)
end
test "run jobs on multiple queues" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test", queues: ["q1", "q2"]])
{:ok, _} = Exq.enqueue(:exq_t, "q1", ExqTest.PerformArgWorker, [1])
{:ok, _} = Exq.enqueue(:exq_t, "q2", ExqTest.PerformArgWorker, [2])
wait_long
assert_received {:worked, 1}
assert_received {:worked, 2}
stop_process(sup)
end
test "register queue and run job" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test", queues: ["q1"]])
:ok = Exq.subscribe(:exq_t, "q2", 10)
{:ok, _} = Exq.enqueue(:exq_t, "q1", ExqTest.PerformArgWorker, [1])
{:ok, _} = Exq.enqueue(:exq_t, "q2", ExqTest.PerformArgWorker, [2])
wait_long
assert_received {:worked, 1}
assert_received {:worked, 2}
stop_process(sup)
end
test "unregister queue and run job" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test", queues: ["q1","to_remove"]])
:ok = Exq.unsubscribe(:exq_t, "to_remove")
{:ok, _} = Exq.enqueue(:exq_t, "q1", ExqTest.PerformArgWorker, [1])
{:ok, _} = Exq.enqueue(:exq_t, "to_remove", ExqTest.PerformArgWorker, [2])
wait_long
assert_received {:worked, 1}
refute_received {:worked, 2}
stop_process(sup)
end
test "throttle workers per queue" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test", concurrency: 1, queues: ["q1", "q2"]])
{:ok, _} = Exq.enqueue(:exq_t, "q1",ExqTest.SleepWorker, [40, :worked])
{:ok, _} = Exq.enqueue(:exq_t, "q1",ExqTest.SleepWorker, [40, :worked2])
{:ok, _} = Exq.enqueue(:exq_t, "q1",ExqTest.SleepWorker, [100, :finished])
# q2 should be clear
{:ok, _} = Exq.enqueue(:exq_t, "q2",ExqTest.SleepWorker, [100, :q2_finished])
:timer.sleep(160)
assert_received {"worked"}
assert_received {"worked2"}
refute_received {"finished"}
assert_received {"q2_finished"}
stop_process(sup)
end
test "throttle workers different concurrency per queue" do
Process.register(self, :exqtest)
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test", queues: [{"q1", 1}, {"q2", 20}]])
{:ok, _} = Exq.enqueue(:exq_t, "q1", ExqTest.SleepWorker, [40, :worked])
{:ok, _} = Exq.enqueue(:exq_t, "q1", ExqTest.SleepWorker, [40, :worked2])
{:ok, _} = Exq.enqueue(:exq_t, "q1", ExqTest.SleepWorker, [100, :should_not_finish])
# q2 should be clear
{:ok, _} = Exq.enqueue(:exq_t, "q2", ExqTest.SleepWorker, [100, :q2_work])
{:ok, _} = Exq.enqueue(:exq_t, "q2", ExqTest.SleepWorker, [100, :q2_work])
{:ok, _} = Exq.enqueue(:exq_t, "q2", ExqTest.SleepWorker, [100, :q2_work])
{:ok, _} = Exq.enqueue(:exq_t, "q2", ExqTest.SleepWorker, [100, :q2_finished])
:timer.sleep(150)
assert_received {"worked"}
assert_received {"worked2"}
refute_received {"should_not_finish"}
assert_received {"q2_finished"}
stop_process(sup)
end
test "record processed jobs" do
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test"])
state = :sys.get_state(:exq_t)
{:ok, _} = Exq.enqueue(:exq_t, "default", "ExqTest.CustomMethodWorker/simple_perform", [])
wait
{:ok, count} = TestStats.processed_count(state.redis, "test")
assert count == "1"
{:ok, _} = Exq.enqueue(:exq_t, "default", "ExqTest.CustomMethodWorker/simple_perform", [])
wait_long
{:ok, count} = TestStats.processed_count(state.redis, "test")
assert count == "2"
stop_process(sup)
end
test "record failed jobs" do
{:ok, sup} = Exq.start_link([name: :exq_t, host: redis_host, port: redis_port, namespace: "test"])
state = :sys.get_state(:exq_t)
{:ok, _} = Exq.enqueue(:exq_t, "default", "ExqTest.MissingMethodWorker/fail", [])
wait_long
{:ok, count} = TestStats.failed_count(state.redis, "test")
assert count == "1"
{:ok, _} = Exq.enqueue(:exq_t, "default", ExqTest.MissingWorker, [])
wait_long
{:ok, count} = TestStats.failed_count(state.redis, "test")
assert count == "2"
{:ok, jid} = Exq.enqueue(:exq_t, "default", "ExqTest.FailWorker/failure_perform", [])
# if we kill Exq too fast we dont record the failure because exq is gone
wait_long
{:ok, enq_sup} = Exq.Enqueuer.Server.start_link([name: :exq_e, host: redis_host, port: redis_port, namespace: "test"])
# Find the job in the processed queue
{:ok, _, _} = Exq.Api.find_failed(:exq_e, jid)
wait_long
stop_process(sup)
stop_process(enq_sup)
end
end