update
This commit is contained in:
198
phoenix/deps/phoenix_pubsub/test/shared/pubsub_test.exs
Normal file
198
phoenix/deps/phoenix_pubsub/test/shared/pubsub_test.exs
Normal file
@@ -0,0 +1,198 @@
|
||||
defmodule Phoenix.PubSubTest do
|
||||
@moduledoc """
|
||||
Sets up PubSub Adapter testcases.
|
||||
|
||||
## Usage
|
||||
|
||||
To test a PubSub adapter, set the `:test_adapter` on the `:phoenix_pubsub`
|
||||
configuration and require this file, ie:
|
||||
|
||||
# your_pubsub_adapter_test.exs
|
||||
Application.put_env(:phoenix_pubsub, :test_adapter, {Phoenix.PubSub.PG2, []})
|
||||
Code.require_file "../deps/phoenix_pubsub/test/shared/pubsub_test.exs", __DIR__
|
||||
|
||||
"""
|
||||
|
||||
use ExUnit.Case, async: true
|
||||
alias Phoenix.PubSub
|
||||
|
||||
defp subscribers(config, topic) do
|
||||
Registry.lookup(config.pubsub, topic)
|
||||
end
|
||||
|
||||
defp rpc(pid, func) do
|
||||
Agent.get(pid, fn :ok -> func.() end)
|
||||
end
|
||||
|
||||
defp spawn_pid do
|
||||
{:ok, pid} = Agent.start_link(fn -> :ok end)
|
||||
pid
|
||||
end
|
||||
|
||||
defmodule CustomDispatcher do
|
||||
def dispatch(entries, from, message) do
|
||||
for {pid, metadata} <- entries do
|
||||
send(pid, {:custom, metadata, from, message})
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
setup config do
|
||||
size = config[:pool_size] || 1
|
||||
registry_size = config[:registry_size] || config[:registry_pool_size] || config[:pool_size] || 1
|
||||
{adapter, adapter_opts} = Application.get_env(:phoenix_pubsub, :test_adapter)
|
||||
adapter_opts = [adapter: adapter, name: config.test, pool_size: size, registry_size: registry_size] ++ adapter_opts
|
||||
start_supervised!({Phoenix.PubSub, adapter_opts})
|
||||
|
||||
opts = %{
|
||||
pubsub: config.test,
|
||||
topic: to_string(config.test),
|
||||
pool_size: size,
|
||||
node: Phoenix.PubSub.node_name(config.test),
|
||||
adapter_name: Module.concat(config.test, "Adapter")
|
||||
}
|
||||
|
||||
{:ok, opts}
|
||||
end
|
||||
|
||||
test "node_name/1 returns the node name", config do
|
||||
assert is_atom(config.node) or is_binary(config.node)
|
||||
end
|
||||
|
||||
for size <- [1, 8] do
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: subscribe and unsubscribe", config do
|
||||
pid = spawn_pid()
|
||||
assert subscribers(config, config.topic) |> length == 0
|
||||
assert rpc(pid, fn -> PubSub.subscribe(config.pubsub, config.topic) end)
|
||||
assert subscribers(config, config.topic) == [{pid, nil}]
|
||||
assert rpc(pid, fn -> PubSub.unsubscribe(config.pubsub, config.topic) end)
|
||||
assert subscribers(config, config.topic) |> length == 0
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: broadcast/3 and broadcast!/3 publishes message to each subscriber",
|
||||
config do
|
||||
PubSub.subscribe(config.pubsub, config.topic)
|
||||
:ok = PubSub.broadcast(config.pubsub, config.topic, :ping)
|
||||
assert_receive :ping
|
||||
:ok = PubSub.broadcast!(config.pubsub, config.topic, :ping)
|
||||
assert_receive :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: broadcast/3 does not publish message to other topic subscribers",
|
||||
config do
|
||||
PubSub.subscribe(config.pubsub, "unknown")
|
||||
|
||||
Enum.each(0..10, fn _ ->
|
||||
rpc(spawn_pid(), fn -> PubSub.subscribe(config.pubsub, config.topic) end)
|
||||
end)
|
||||
|
||||
:ok = PubSub.broadcast(config.pubsub, config.topic, :ping)
|
||||
refute_received :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: broadcast_from/4 and broadcast_from!/4 skips sender", config do
|
||||
PubSub.subscribe(config.pubsub, config.topic)
|
||||
|
||||
PubSub.broadcast_from(config.pubsub, self(), config.topic, :ping)
|
||||
refute_received :ping
|
||||
|
||||
PubSub.broadcast_from!(config.pubsub, self(), config.topic, :ping)
|
||||
refute_received :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: unsubscribe on not subscribed topic noops", config do
|
||||
assert :ok = PubSub.unsubscribe(config.pubsub, config.topic)
|
||||
assert subscribers(config, config.topic) == []
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: direct_broadcast sends to given node", config do
|
||||
PubSub.subscribe(config.pubsub, config.topic)
|
||||
|
||||
PubSub.direct_broadcast(config.node, config.pubsub, config.topic, :ping)
|
||||
assert_receive :ping
|
||||
|
||||
PubSub.direct_broadcast!(config.node, config.pubsub, config.topic, :ping)
|
||||
assert_receive :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: direct_broadcast sends to unknown node", config do
|
||||
PubSub.subscribe(config.pubsub, config.topic)
|
||||
|
||||
PubSub.direct_broadcast(:"IDONTKNOW@127.0.0.1", config.pubsub, config.topic, :ping)
|
||||
refute_received :ping
|
||||
|
||||
PubSub.direct_broadcast!(:"IDONTKNOW@127.0.0.1", config.pubsub, config.topic, :ping)
|
||||
refute_received :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: local_broadcast sends to the current node", config do
|
||||
PubSub.subscribe(config.pubsub, config.topic)
|
||||
|
||||
PubSub.local_broadcast(config.pubsub, config.topic, :ping)
|
||||
assert_receive :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: local_broadcast_from/5 skips sender", config do
|
||||
PubSub.subscribe(config.pubsub, config.topic)
|
||||
|
||||
PubSub.local_broadcast_from(config.pubsub, self(), config.topic, :ping)
|
||||
refute_received :ping
|
||||
end
|
||||
|
||||
@tag pool_size: size
|
||||
test "pool #{size}: with custom dispatching", %{topic: topic, test: test, node: node} do
|
||||
PubSub.subscribe(test, topic)
|
||||
PubSub.subscribe(test, topic, metadata: :special)
|
||||
|
||||
PubSub.broadcast(test, topic, :broadcast, CustomDispatcher)
|
||||
assert_receive {:custom, nil, :none, :broadcast}
|
||||
assert_receive {:custom, :special, :none, :broadcast}
|
||||
|
||||
PubSub.broadcast_from(test, self(), topic, :broadcast_from, CustomDispatcher)
|
||||
assert_receive {:custom, nil, pid, :broadcast_from} when pid == self()
|
||||
assert_receive {:custom, :special, pid, :broadcast_from} when pid == self()
|
||||
|
||||
PubSub.local_broadcast(test, topic, :local, CustomDispatcher)
|
||||
assert_receive {:custom, nil, :none, :local}
|
||||
assert_receive {:custom, :special, :none, :local}
|
||||
|
||||
PubSub.local_broadcast_from(test, self(), topic, :local_from, CustomDispatcher)
|
||||
assert_receive {:custom, nil, pid, :local_from} when pid == self()
|
||||
assert_receive {:custom, :special, pid, :local_from} when pid == self()
|
||||
|
||||
PubSub.direct_broadcast(node, test, topic, :direct, CustomDispatcher)
|
||||
assert_receive {:custom, nil, :none, :direct}
|
||||
assert_receive {:custom, :special, :none, :direct}
|
||||
end
|
||||
end
|
||||
|
||||
@tag pool_size: 4
|
||||
@tag registry_size: 2
|
||||
test "PubSub pool size can be configured separately from the Registry partitions",
|
||||
config do
|
||||
assert {:duplicate, 2, _} = :ets.lookup_element(config.pubsub, -2, 2)
|
||||
|
||||
assert :persistent_term.get(config.adapter_name) ==
|
||||
{config.adapter_name, :"#{config.adapter_name}_2", :"#{config.adapter_name}_3", :"#{config.adapter_name}_4"}
|
||||
end
|
||||
|
||||
@tag pool_size: 3
|
||||
test "Registry partitions are configured with the same pool size as PubSub if not specified",
|
||||
config do
|
||||
assert {:duplicate, 3, _} = :ets.lookup_element(config.pubsub, -2, 2)
|
||||
|
||||
assert :persistent_term.get(config.adapter_name) ==
|
||||
{config.adapter_name, :"#{config.adapter_name}_2", :"#{config.adapter_name}_3"}
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user