Skip to content

Instantly share code, notes, and snippets.

@orestis
Created January 6, 2017 10:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orestis/ed19d0da066d3e65f919da3d76b8b224 to your computer and use it in GitHub Desktop.
Save orestis/ed19d0da066d3e65f919da3d76b8b224 to your computer and use it in GitHub Desktop.
defmodule LimiterTest do
use ExUnit.Case
def echo(a) do
a
end
def wait_echo(time, a) do
Process.sleep(time)
a
end
def callback_echo(pid, time, a) do
Process.sleep(time)
send(pid, a)
a
end
test "can start and stop" do
{:ok, pid} = GenServer.start_link(Limiter, {__MODULE__, :echo})
:ok = GenServer.stop(pid)
end
test "can call normal" do
{:ok, pid} = GenServer.start_link(Limiter, {__MODULE__, :echo})
assert :hello == GenServer.call(pid, {:normal, [:hello]})
assert [1, 2, 3] == GenServer.call(pid, {:normal, [[1, 2, 3]]})
assert :goodbye == GenServer.call(pid, {:normal, [:goodbye]})
:ok = GenServer.stop(pid)
end
test "calls are serialized" do
{:ok, pid} = GenServer.start_link(Limiter, {__MODULE__, :wait_echo})
start = System.monotonic_time(:millisecond)
assert :hello == GenServer.call(pid, {:normal, [10, :hello]})
assert [1, 2, 3] == GenServer.call(pid, {:normal, [10, [1, 2, 3]]})
assert :goodbye == GenServer.call(pid, {:normal, [10, :goodbye]})
finish = System.monotonic_time(:millisecond)
elapsed = finish - start
assert elapsed > 30
:ok = GenServer.stop(pid)
end
test "can call priority" do
{:ok, pid} = GenServer.start_link(Limiter, {__MODULE__, :echo})
assert :hello == GenServer.call(pid, {:normal, [:hello]})
assert :hurry == GenServer.call(pid, {:priority, [:hurry]})
assert :goodbye == GenServer.call(pid, {:normal, [:goodbye]})
end
test "priority takes precedence" do
{:ok, pid} = GenServer.start_link(Limiter, {__MODULE__, :callback_echo})
myself = self()
start = System.monotonic_time(:millisecond)
long_time = 60
short_time = 10
tick = 5
spawn(fn() -> assert :hello == GenServer.call(pid, {:normal, [myself, long_time, :hello]}) end)
Process.sleep(tick)
spawn(fn() -> assert :goodbye == GenServer.call(pid, {:normal, [myself, long_time, :goodbye]}) end)
Process.sleep(tick)
spawn(fn() -> assert :hurry == GenServer.call(pid, {:priority, [myself, short_time, :hurry]}) end)
Process.sleep(tick)
buffer = 15
assert_receive :hurry, short_time + buffer
assert_receive :hello, long_time + buffer
assert_receive :goodbye, short_time + long_time * 2 + buffer
finish = System.monotonic_time(:millisecond)
elapsed = finish - start
assert elapsed > long_time * 2 # if this fails, the normal tasks are not serialized
:ok = GenServer.stop(pid)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment