Closed schneems closed 4 years ago
A related issue that provides a workaround, but does not fix the underlying problem https://github.com/qrush/m/issues/25:
if defined?(M)
# https://github.com/qrush/m/issues/80
require "minitest"
else
require "minitest/autorun"
end
This only happens when you run the tests with m
, not directly with minitest, correct?
Correct. I could not reproduce the behavior when I’m running the test directly via “ruby”. It only occurs when running via “m”
Sorry for the delay. I investigated this a bit further and unfortunately there isn't a lot m
can do here (that's not even worse). Basically the "issue" is that minitest/autorun sets an at_exit
trigger to run the tests, with one process we were able to go around it by running m
and then calling exit!
, which will not trigger at_exit
.
With multiple processes, all the ones that are not running m
will then trigger the at_exit
, resulting in the behavior described here. Unfortunately I'm not aware of a way to either remove the at_exit
or impede it to be set in the first place, that does not lead to a lot of potential bugs in the future.
I think that if you are doing work with forks and want to use m
, you'll have to require minitest/spec
, which does not set those triggers and depend solely on m
to run your tests`.
Thanks for taking a look. I'm not very familiar with the internals of M. Do you think it could be possible to get some sort of a workaround/fix in some combination of minitest and the m
gem? Perhaps minitest could record itself as having already set the at_exit
handler in the parent process and not re-set it later?
I was also only able to reproduce this while using the m
gem in combination with minitest/auto_test
. Do you know what the m gem is doing to trigger the behavior, or rather how I could reproduce the behavior without relying on m
(if I wanted to submit a patch to minitest)?
I'm not 100% sure, but what I think happens is that minitest/autorun
sets the at_exit
, but since it only runs the tests from within it, only one process actually gets to see it (the main test process), thus the other ones get the inner at_exit
which runs the after_run callbacks, and never trigger a re run of the tests. That's actually a pretty smart use of the at_exit
stack for minitest.
However, since m
runs the tests from outside the outer at_exit
, all the processes created in the test (the main one plus all the forks) will see that at_exit
, thus triggering a run per process.
In terms of ways around it, maybe minitest allowing for a block to be passed to autorun, to configure what happens within that at_exit
, but I don't see that happening. This works nicely for minestest, but makes the running pretty opaque to the outside, but since it's called autorun
I guess that's kind of the point.
Sorry I can't be of more help here.
Origionally reported in https://github.com/seattlerb/minitest/issues/844 it looks like the problem is with the
m
gem and not minitest. Here's a reproduction:This produces the output:
I believe this has something to do with with
fork
and minitests's "autorun" as this behavior does not reproduce when running a test that does not call fork:Simple repro
Here's a local reproduction that might show the problem better:
When I run the test with fork it runs the whole suite and then runs the focus test:
When I run the test without fork it only runs what I'm focusing: