Reputation: 796
I'm learning to test in Elixir and this problem appeared:
When I run the following test, sometimes it passes and sometimes don't, I'm thinking it is the fact that the Supervisor don't have the time to restart the GenServer:
test "Supervisor will revive the dead gensever" do
{:ok, pid} = KV.Supervisor.start_link([])
KV.RegistryClient.create KV.RegistryClient, "wallet"
[h | _] = Supervisor.which_children(pid)
{KV.RegistryClient, pid_reg, _, _} = h
send(pid_reg, :insta_kill)
assert %{active: 1} = Supervisor.count_children(pid)
end
When occurs, this is the error:
1) test Supervisor will revive the dead gensever (KV.RegistryTest)
test/kv/registry_test.exs:35
match (=) failed
code: assert %{active: 1} = Supervisor.count_children(pid)
right: %{active: 0, specs: 1, supervisors: 0, workers: 1}
stacktrace:
test/kv/registry_test.exs:41: (test)
How do I prevent this to happen? A timeout is a good approach?
Upvotes: 0
Views: 567
Reputation: 51349
The only way you can effectively test this behaviour without race conditions is by:
Making sure the old process is dead. This can be done by monitoring the process before you send the kill signal and then assert_receive {:DOWN, ^monitor_ref, _, _, _}
Query the supervisor until the active count changes to one. This can be done by executing a function once every 10ms or so
However, as others have said, this behaviour is guaranteed by Erlang/OTP. Therefore, instead of testing if a supervisor is actually restarting something, I would rather test if you are passing the proper child specification to the supervisor. So assuming the supervisor starts a processed based on KV.Registered
, I would do this:
assert %{restart: :permanent} = Supervisor.child_spec(KV.Registered)
In other words, I would test the contract with supervisors, without testing the supervisors themselves.
Upvotes: 4
Reputation: 3335
It is a timing issue. The short version is don't bother testing OTP. IT is very well tested already.
But if you have a case in the future where you need to ensure startups work correctly understanding how Supervisors start servers is useful, see this video https://www.youtube.com/watch?v=2i_XrY5CCXE
Upvotes: 2