Question

I'm currently issuing a problem with running tests with rspec. All the test files (*_spec.rb) may run successfully. In same rare cases an error -- Errno::EACCES may appear and one of the tests may fail. E.g:
All the test in the file *_spec.rb run:

  1. Successfully.
  2. Successfully.
  3. One the test had failed.
  4. Successfully.
  5. One the test had failed (not the same as in #3).
  6. etc.

The exception raises from the lines like:

  1. FileUtils.mv
  2. FileUtils.mkdir_p
  3. FileUtils.rm_r

All of those list work with files or directories and are used many times in tests. I.e.:
create folder(with subfolders, with files, etc.), rename folder, test something, delete.. and so on.

It looks like the problem is hidden somewhere in "timing"(if something is not done yet and another action tries to access that something). That mind comes from:

begin
  FileUtils.mv(a, b) # if an `Errno:EACCESS` was raised here
rescue               #
  FileUtils.mv(a, b) # it wouldn't be raised now
end

The question is:
How can it be fixed? (i mean Errno:EACCESS which is reproduced rarely and some tests)


  • Adding sleep after every operation with files is not acceptable nevertheless it will help.
  • ruby's methods (FileUtils.(mv|rm_r|mkdir_p)) may be modified to retry once on Errno::EACCES but is this the best solution?

P.S.
Sorry for my English and feel free to ask any question as i've tried to explain as brief as i could. Thanks in advanced, at least for you've read this to the end;

Was it helpful?

Solution

Look for the root cause, don't succumb to workarounds you mentioned.

First make sure you're using before and after for setting up and tearing down file fixtures. If you code your setup and teardown procedures in the spec itself you run a risk of it not running when the test fails.

Second, make sure your setup & teardown procedures create different files and directories for each test. If all you're doing is reading it's ok to use shared fixtures, but for all other things (moving, creation, appending, deletion) use a fresh file/directory. The best thing to do is to use freshly generated temporary files and directories. It will make your tests independent, even allowing to run them in parallel.

Third, check what other processes may use files created/used by your tests. I don't know your setup, and it all depends on that, but possible things are web servers, browsers (e.g. via selenium), mail servers, etc. Simply check what other processes are you running as a part of your build.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top