Hi, I created some Unit test to test my GenServer
which handles Mnesia in its state, and I need to run some function before each test like delete Mnesia Data on my disk, but I get error like this in each function or GenServer call back which has Mnesia function on it self
Error:
** (exit) exited in: GenServer.call(MishkaDatabase.Cache.MnesiaToken, {:get_token_by_user_id, "61095b8c-b172-42c6-8759-b64cacaee32d"}, 5000)
** (EXIT) normal
The test I used:
def delete_old_tokens(_context) do
MnesiaToken.delete_all_tokens() # this is `handle_cast`
end
setup :delete_old_tokens
test "Get code with code" do
%{} = assert MnesiaToken.get_token_by_user_id(Ecto.UUID.generate)
end
now this is my GenServer code:
def get_token_by_user_id(user_id) do
GenServer.call(__MODULE__, {:get_token_by_user_id, user_id}, @timeout)
end
@impl true
def handle_call({:get_token_by_user_id, user_id}, _from, state) do
token_selected = Mnesia.transaction(fn ->
Mnesia.select(Token, [{{Token, :"$1", :"$2", :"$3", :"$4", :"$5", :"$6"}, [{:"==", :"$2", "#{user_id}"}], [:"$$"]}])
end)
|> case do
{:atomic, []} -> %{}
{:atomic, data} -> data
_ -> %{}
end
{:reply, token_selected, state}
end
and my def
to delete all Mnesia
data before each test
def delete_all_tokens() do
GenServer.cast(__MODULE__, {:delete_all_tokens})
end
@impl true
def handle_cast({:delete_all_tokens}, state) do
Mnesia.transaction(fn ->
Mnesia.select(Token, [{{Token, :"$1", :"$2", :"$3", :"$4", :"$5", :"$6"}, [], [:"$$"]}])
end)
|> case do
{:atomic, []} -> {:noreply, state}
{:atomic, data} ->
Enum.map(data, fn [id, _user_id, _token, _access_expires_in, _create_time, _os] ->
Mnesia.dirty_delete(Token, id)
end)
{:noreply, state}
_ -> {:noreply, state}
end
end
I think this problem is started when the GenServer
cant stay to get answer then I use big timeout, unfortunately this didn’t help me.
more problem
I cant create a loop before each test to check whether we have data on mnesia disk or not. it shows me same error like top, for example create check all the token on disk
def get_all_token() do
GenServer.call(__MODULE__, {:get_all_token})
end
def handle_call({:get_all_token}, _from, state) do
Mnesia.transaction(fn ->
Mnesia.select(Token, [{{Token, :"$1", :"$2", :"$3", :"$4", :"$5", :"$6"}, [], [:"$$"]}])
end)
|> case do
{:atomic, []} -> {:reply, %{}, state}
{:atomic, data} -> {:reply, data, state}
_ -> {:reply, %{}, state}
end
end
again we have a Mnesia checker into GenServer call back and it doesn’t want to answer us
it should be noted I don’t want to save a copy of disk mnesia on my GenServer state
Please help me to create some test for this
Thanks