Unsolved puzzle of mnesia behavior in mix test
Updated:
Recently, I am evaluating the usage of Mnesia in Elixir.
After figuring out how to use One Elixir Code for Both Mnesia Master & Child, I moved on to data CRUD operation.
Before writing actual testing code, in order to make each test independent, I need to first complete the setup and teardown tasks between each test.
Test Callbacks
In Elixir, these callbacks can be used:
setup_all: Invoked once per module before any test is run.setup: Invoked once before each test.on_exit: Registered on demand during setup.
Tips: Multiple setup and setup_all are allowed. They are invoked in sequence. Failures in setup_all or setup will stop all remaining setup callbacks from executing while on_exit will always run.
The test script looks like this:
1 | defmodule Sample.MnesiaTest do |
- Attribute
:mnesia_tableis registered and used on each test to annotate the table name within the following test. - In
setup_all, it performs steps to bring up the whole Mnesia and shutdown. - In
setup, it destroys the tables used in each test annotated by the:mnesia_tableattribute.
I set the accumulate: true so that we can specify multiple @mnesia_table attributes and so the value of context.registered[:mnesia_table] is a list.
Tips: Attribute, similar to tag, is cleared after each test. The difference is that when a tag is given more than once, the last value wins.
Puzzle
Everything sounds smooth but I noticed one thing after running mix test, the mnesia directory still has files inside. Shouldn’t all files removed after calling delete_schema? But the result of delete_schema returns :ok when I suspected its failure and printed it.
Later, I realized that the mnesia directory contains the table name used in the application startup logic prepared last week. It’s the table and schema created during the application startup when running mix test.
Below is the observation of the puzzle:
- If
mix testis run under umbrella root, the mnesia directory is generated under root and the files cannot be removed. - However, if
mix testis run under the folder ofapp\mgrwhere the mnesia startup and setup logic exists, the mnesia directory is generated there but the files can be removed. - If I add
@moduletag :no_startto the test module, add below code to the umbrella rootmix.exs, and then runmix ut, the behavior just like runningmix testinapp\mgr.
1 | def project do |
Looks like there is something mysterious of the umbrella project causing the mnesia directory issue.
It took me hours to try to figure out why but no luck.
Before I got desperate and gave up, I found that the problem can be solved after I changed the config.exs following the suggestion in https://github.com/Nebo15/ecto_mnesia/issues/40:
from
config :mnesia, dir: 'mnesia.#{Mix.env}.#{node()}'
to
config :mnesia, dir: to_charlist Path.join(File.cwd!, 'mnesia.#{Mix.env}.#{node()}')
Although the problem can be solved, the reason is still a puzzle remained. Maybe it is the absolute and relative path handling issue of mnesia in umbrella project? Your advice or explanation is greatly appreciated.
