Packages

A distributed service registry built on top of phoenix_pubsub. Requests are dispatched to one or more services based on hashed keys.

Current section

Files

Jump to
dispatch test dispatch service_test.exs
Raw

test/dispatch/service_test.exs

defmodule Dispatch.ServiceTest do
use ExUnit.Case, async: false
alias Dispatch.{Service, Helper}
defmodule FakeService do
def start_link(opts) do
GenServer.start_link(__MODULE__, opts)
end
def init(opts) do
:ok = Service.init(opts)
{:ok, %{}}
end
def handle_call({:get, key}, _from, state) do
{:reply, {:ok, key}, state}
end
def handle_cast({:set, key, from}, state) do
send(from, {:set_request, key})
{:noreply, state}
end
end
setup do
type = "ServiceTest"
pubsub_server =
Application.get_env(:dispatch, :pubsub)
|> Keyword.get(:name, Dispatch.PubSub)
Phoenix.PubSub.subscribe(pubsub_server, type)
{:ok, _registry_pid} = Helper.setup_registry()
on_exit(fn ->
Helper.clear_type(type)
end)
{:ok, %{service_type: type}}
end
test "invoke service cast", %{service_type: type} do
{:ok, service} = FakeService.start_link(type: type)
this_node = node()
assert_receive({:join, ^service, %{node: ^this_node, state: :online}})
Service.cast(type, "my_key", {:set, "key", self()})
assert_receive({:set_request, "key"})
end
test "invoke service call", %{service_type: type} do
this_node = node()
{:ok, service} = FakeService.start_link(type: type)
assert_receive({:join, ^service, %{node: ^this_node, state: :online}})
{:ok, result} = Service.call(type, "my_key", {:get, "my_key"})
assert result == "my_key"
end
test "invoke service multi cast", %{service_type: type} do
{:ok, service1} = FakeService.start_link(type: type)
{:ok, service2} = FakeService.start_link(type: type)
{:ok, service3} = FakeService.start_link(type: type)
this_node = node()
assert_receive({:join, ^service1, %{node: ^this_node, state: :online}})
assert_receive({:join, ^service2, %{node: ^this_node, state: :online}})
assert_receive({:join, ^service3, %{node: ^this_node, state: :online}})
res = Service.multi_cast(2, type, "my_key", {:set, "key", self()})
assert(res != {:error, :service_unavailable})
assert_receive({:set_request, "key"})
assert_receive({:set_request, "key"})
end
test "invoke service multi call", %{service_type: type} do
{:ok, service1} = FakeService.start_link(type: type)
{:ok, service2} = FakeService.start_link(type: type)
{:ok, service3} = FakeService.start_link(type: type)
this_node = node()
assert_receive({:join, ^service1, %{node: ^this_node, state: :online}})
assert_receive({:join, ^service2, %{node: ^this_node, state: :online}})
assert_receive({:join, ^service3, %{node: ^this_node, state: :online}})
[{:ok, out_service1, out_res1}, {:ok, out_service2, out_res2}] =
Service.multi_call(2, type, "my_key", {:get, "my_key"})
assert(out_res1 == {:ok, "my_key"})
assert(out_res2 == {:ok, "my_key"})
assert(Enum.member?([service1, service2, service3], out_service1))
assert(Enum.member?([service1, service2, service3], out_service2))
assert(out_service1 != out_service2)
end
end