Skip to content

Instantly share code, notes, and snippets.

@beardedeagle
Created July 11, 2018 20:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save beardedeagle/dc72f25fb561780f902d5dbf354a582d to your computer and use it in GitHub Desktop.
Save beardedeagle/dc72f25fb561780f902d5dbf354a582d to your computer and use it in GitHub Desktop.
Distributed testing
defmodule Vanguard.Support.ClusterCase do
@moduledoc false
def spawn(nodes \\ Application.get_env(:libcluster, :topologies)[:vanguard][:config][:hosts]) do
# Turn node into a distributed node with the given long name
:net_kernel.start([:"primary@127.0.0.1"])
# Allow spawned nodes to fetch all code from this node
:erl_boot_server.start([])
allow_boot(to_charlist("127.0.0.1"))
_discard =
nodes
|> Enum.map(&Task.async(fn -> spawn_node(&1, nodes) end))
|> Enum.map(&Task.await(&1, 30_000))
Mnesiam.init_mnesia([:"primary@127.0.0.1"], :test)
:mnesia.wait_for_tables(
[OwnerStore, HandlerStore, CheckStore, StatusStore, ProcStore],
:infinity
)
Application.ensure_all_started(:vanguard)
nodes
|> Enum.map(
&Task.async(fn ->
rpc(&1, Application, :ensure_all_started, [:vanguard, :permanent])
rpc(&1, :mnesia, :wait_for_tables, [
[OwnerStore, HandlerStore, CheckStore, StatusStore, ProcStore],
:infinity
])
end)
)
|> Enum.map(&Task.await(&1, 30_000))
end
def spawn_node(node_host, nodes) do
{:ok, node} = :slave.start(to_charlist("127.0.0.1"), node_name(node_host), inet_loader_args())
add_code_paths(node)
transfer_configuration(node)
connect_node(nodes)
{:ok, node}
end
def stop do
nodes = Node.list(:connected)
nodes
|> Enum.map(&Task.async(fn -> stop_node(&1) end))
|> Enum.map(&Task.await(&1, 30_000))
end
def stop_node(node) do
:ok = :slave.stop(node)
end
defp connect_node(nodes) do
Enum.each(nodes, fn node ->
for n <- nodes, n != node, do: rpc(node, :net_kernel, :connect_node, [n])
end)
end
defp rpc(node, module, function, args) do
:rpc.call(node, module, function, args)
end
defp inet_loader_args do
'-loader inet -hosts 127.0.0.1 -connect_all false -setcookie #{:erlang.get_cookie()}'
end
defp allow_boot(host) do
{:ok, ipv4} = :inet.parse_ipv4_address(host)
:erl_boot_server.add_slave(ipv4)
end
defp add_code_paths(node) do
rpc(node, :code, :add_paths, [:code.get_path()])
end
defp transfer_configuration(node) do
for {app_name, _, _} <- Application.loaded_applications() do
for {key, val} <- Application.get_all_env(app_name) do
rpc(node, Application, :put_env, [app_name, key, val, [persistent: true]])
end
end
end
defp node_name(node_host) do
node_host
|> to_string
|> String.split("@")
|> Enum.at(0)
|> String.to_atom()
end
end
Vanguard.Support.ClusterCase.spawn()
ExUnit.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment