I have a test that starts up a socket connection and subscribes and joins a topic. I then push a message to the channel which does some work and persist some data. I then use ChannelTest.close/2 on the socket which simulates the client closing the connection. I would then like to modify the manipulated data and create another socket connection to test some behaviour.
My issue is ChannelTest.close/2 causes my test to fail and returns ** (EXIT from #PID<0.558.0>) shutdown: :closed
. How can I prevent this from happening?
Here's some relevant code
defmodule PlexServer.EmpireChannelTest do
use PlexServer.ChannelCase
alias PlexServer.EmpireChannel
alias PlexServer.EmpireTemplate
alias PlexServer.EmpireInstance
setup do
...
{:ok, _, socket} =
socket("user_id", %{})
|> subscribe_and_join(EmpireChannel,
"empire:#{empire.id}",
%{"guardian_token" => jwt})
{:ok, socket: socket, empire: empire, jwt: jwt}
end
test "research infrastructure", %{socket: socket, empire: empire, jwt: jwt} do
...
ref = push socket, "command", request
assert_reply ref, :ok, _, 1000
close(socket) #fails here
...
end
end
defmodule PlexServer.UserSocket do
use Phoenix.Socket
use Guardian.Phoenix.Socket
## Channels
# channel "rooms:*", PlexServer.RoomChannel
channel "empire:*", PlexServer.EmpireChannel
channel "user:*", PlexServer.UserChannel
## Transports
transport :websocket, Phoenix.Transports.WebSocket
def connect(_params,_) do
:error
end
def id(_socket), do: nil
end
defmodule PlexServer.EmpireChannel do
use PlexServer.Web, :channel
use Guardian.Channel
alias PlexServer.EmpireInstance
alias PlexServer.EmpireServer
...
def join("empire:" <> empire_id, %{claims: _claims, resource: user}, socket) do
...
#Starts a process through a supervisor here
end
def join("empire:" <> _, _, _socket) do
{:error, data_error(:auth, "not authorized, did you pass your jwt?")}
end
# Channels can be used in a request/response fashion
# by sending replies to requests from the client
def handle_in("ping", payload, socket) do
{:reply, {:ok, payload}, socket}
end
def handle_in("show", _, socket) do
...
end
def handle_in("command", request, socket) do
...
end
def handle_in("remove", _, socket) do
...
end
def handle_in("ship_templates", _, socket) do
...
end
end
Following the answer linked in the comments I added some code:
Process.flag(:trap_exit, true)
monitor_ref = Process.monitor(socket.channel_pid)
close(socket)
Now I get a different error message: ** (exit) exited in: GenServer.call(PlexServer.EmpireSupervisor, {:terminate_child, :empire4}, :infinity)
** (EXIT) no process