We are trying to run each test in a completely clean dets environment, and each test is responsible for its own setup. We're running into issues where we can not completely remove the directory between tests.
How can we reset dets
? Did we incorrectly assume blowing away the entire directory and restarting the application was sufficient setup? Is it better to remove all records between runs?
Assume:
async: true
is not set for any tests.dets
is required- The majority of answered code should (if at all possible) be in elixir, not erlang.
Example code:
setup do
#clean up anything that wasn't already clean (failed teardown, etc)
TestSetup.teardown_dets(:myappatom, "dets")
on_exit fn ->
TestSetup.teardown_dets(:myappatom, "dets")
Application.ensure_all_started(:myappatom)
Process.sleep(300)
end
end
And the guts of the teardown function...
def teardown_dets(application_atom, directory) when is_bitstring(directory) do
teardown_dets(application_atom, [directory])
end
def teardown_dets(application_atom, directories)
when is_atom(application_atom) and is_list(directories)
do
#stop the applications completely
Application.stop(application_atom)
#blow away all dets while the application is stopped
try do
directories
|> Enum.map(&File.rm_rf(&1))
rescue
error in File.Error -> IO.puts("First file removal failure. Re-attempting. Initial error information #{error.message}")
after
Process.sleep(3000) #wait for whatever it was to get out of the way
directories
|> Enum.map(&File.rm_rf!(&1))
end
end
Example errors when running mix test
are stdout showing:
dets: file "dets/event_listener_stream_positions_test" not properly closed, repairing ...
but not as an error, just regular output to console.
And then an actual failure in the test:
** (File.Error) could not remove files and directories recursively from "dets": file already exists
:file.delete(...)
and it works fine. If the directory is reused for dets during new runs anyway, you could just try deleting the files to find which one is causing the issue. – Casiedelete_all_objects(...)
? it's supposed to be constant-time – Wergildasync: true
is not set for any tests", I don't think that would be a problem. – Rosariotest "something", %{test: test} do
-- it might be an extreme strategy in this case, but it can be an effective way to isolate a test's side effects. – Cockcrow