Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix test cases #94

Merged
merged 16 commits into from
Sep 6, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Ensure Swarm.TrackerSyncTests runs with cluster setup
  • Loading branch information
Arjan Scherpenisse committed Jul 24, 2018
commit 6e0b202a2f618d3795496cfea8ddda3325ac5455
118 changes: 93 additions & 25 deletions test/tracker_sync_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ defmodule Swarm.TrackerSyncTests do
@moduletag :capture_log

setup_all do
Application.put_env(:swarm, :node_whitelist, [~r/primary@/])
{:ok, _} = Application.ensure_all_started(:swarm)

on_exit(fn ->
Application.put_env(:swarm, :node_whitelist, [])
end)

:rand.seed(:exs64)
Application.ensure_all_started(:swarm)
{:ok, _} = MyApp.WorkerSup.start_link()
:ok
end
Expand All @@ -23,7 +29,7 @@ defmodule Swarm.TrackerSyncTests do
send_sync_request(lclock, [])

entry(name: _, pid: _, ref: _, meta: _, clock: lclock) = call_track(name, pid, meta)

# fake handle_replica_event which joins the clocks so that they are in sync
rclock = Clock.join(rclock, Clock.peek(lclock))

Expand All @@ -32,97 +38,157 @@ defmodule Swarm.TrackerSyncTests do

test ":sync should add missing registration", %{pid: pid, meta: meta, rclock: rclock} do
name = random_name()

remote_registry = [
entry(name: name, pid: pid, ref: nil, meta: meta, clock: Clock.peek(rclock))
]

send_sync_request(rclock, remote_registry)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^meta, clock: _) = Registry.get_by_name(name)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^meta, clock: _) =
Registry.get_by_name(name)
end

test ":sync with same pid and remote clock dominates should update the meta", %{name: name, pid: pid, rclock: rclock} do
test ":sync with same pid and remote clock dominates should update the meta", %{
name: name,
pid: pid,
rclock: rclock
} do
rclock = Clock.event(rclock)
remote_meta = %{new: "meta"}

remote_registry = [
entry(name: name, pid: pid, ref: nil, meta: remote_meta, clock: Clock.peek(rclock))
]

send_sync_request(rclock, remote_registry)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^remote_meta, clock: _) = Registry.get_by_name(name)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^remote_meta, clock: _) =
Registry.get_by_name(name)
end

test ":sync with same pid and local clock dominates should ignore entry", %{name: name, pid: pid, rclock: rclock} do
test ":sync with same pid and local clock dominates should ignore entry", %{
name: name,
pid: pid,
rclock: rclock
} do
Swarm.Tracker.add_meta(:new_local, "meta_local", pid)

remote_registry = [
entry(name: name, pid: pid, ref: nil, meta: %{new_remote: "remote_meta"}, clock: Clock.peek(rclock))
entry(
name: name,
pid: pid,
ref: nil,
meta: %{new_remote: "remote_meta"},
clock: Clock.peek(rclock)
)
]

send_sync_request(rclock, remote_registry)

local_meta = %{mfa: {MyApp.WorkerSup, :register, []}, new_local: "meta_local"}
assert entry(name: ^name, pid: ^pid, ref: _, meta: ^local_meta, clock: _) = Registry.get_by_name(name)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^local_meta, clock: _) =
Registry.get_by_name(name)
end

test ":sync with same pid and clock should ignore entry", %{name: name, pid: pid, meta: meta, rclock: rclock} do
test ":sync with same pid and clock should ignore entry", %{
name: name,
pid: pid,
meta: meta,
rclock: rclock
} do
remote_registry = [
entry(name: name, pid: pid, ref: nil, meta: %{remote: "meta"}, clock: Clock.peek(rclock))
]

send_sync_request(rclock, remote_registry)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^meta, clock: _) = Registry.get_by_name(name)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^meta, clock: _) =
Registry.get_by_name(name)
end

test ":sync with same pid and concurrent changes should merge data", %{name: name, pid: pid, rclock: rclock} do
test ":sync with same pid and concurrent changes should merge data", %{
name: name,
pid: pid,
rclock: rclock
} do
Swarm.Tracker.add_meta(:new_local, "meta_local", pid)

rclock = Clock.event(rclock)

remote_registry = [
entry(name: name, pid: pid, ref: nil, meta: %{new_remote: "remote_meta"}, clock: Clock.peek(rclock))
entry(
name: name,
pid: pid,
ref: nil,
meta: %{new_remote: "remote_meta"},
clock: Clock.peek(rclock)
)
]

send_sync_request(rclock, remote_registry)

merged_meta = %{
mfa: {MyApp.WorkerSup, :register, []},
new_local: "meta_local",
new_remote: "remote_meta"
}
assert entry(name: ^name, pid: ^pid, ref: _, meta: ^merged_meta, clock: _) = Registry.get_by_name(name)

assert entry(name: ^name, pid: ^pid, ref: _, meta: ^merged_meta, clock: _) =
Registry.get_by_name(name)
end

test ":sync with different pid and local clock dominates should kill remote pid", %{name: name, pid: pid, meta: meta, rclock: rclock} do
test ":sync with different pid and local clock dominates should kill remote pid", %{
name: name,
pid: pid,
meta: meta,
rclock: rclock
} do
Swarm.Tracker.remove_meta(:mfa, pid)

{:ok, remote_pid} = MyApp.WorkerSup.register()

remote_registry = [
entry(name: name, pid: remote_pid, ref: nil, meta: meta, clock: Clock.peek(rclock))
]

send_sync_request(rclock, remote_registry)

assert_process_alive?(true, pid)
assert_process_alive?(false, remote_pid)
end

test ":sync with different pid and remote clock dominates should kill local pid", %{name: name, pid: pid, meta: meta, rclock: rclock} do
test ":sync with different pid and remote clock dominates should kill local pid", %{
name: name,
pid: pid,
meta: meta,
rclock: rclock
} do
{:ok, remote_pid} = MyApp.WorkerSup.register()
rclock = Clock.event(rclock)

remote_registry = [
entry(name: name, pid: remote_pid, ref: nil, meta: meta, clock: Clock.peek(rclock))
]

send_sync_request(rclock, remote_registry)

assert_process_alive?(false, pid)
assert_process_alive?(true, remote_pid)
end

defp call_track(name, pid, meta) do
Swarm.Tracker.track(name, pid)
Enum.each meta, fn {k, v} ->

Enum.each(meta, fn {k, v} ->
Swarm.Tracker.add_meta(k, v, pid)
end
end)

Registry.get_by_name(name)
end

defp send_sync_request(clock, registry) do
defp send_sync_request(clock, registry) do
GenServer.cast(Swarm.Tracker, {:sync, self(), clock})
GenServer.cast(Swarm.Tracker, {:sync_ack, self(), clock, registry})
# get_state to wait for the sync to be completed
Expand All @@ -134,9 +200,11 @@ defmodule Swarm.TrackerSyncTests do
end

defp assert_process_alive?(alive, pid, tries \\ 10)

defp assert_process_alive?(alive, pid, 0) do
assert Process.alive?(pid) == alive
end

defp assert_process_alive?(alive, pid, tries) do
if Process.alive?(pid) == alive do
alive
Expand Down