-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrency issues in junit-interface module #399
Comments
Thank you for doing this detailed investigation! Big 👍 on both recommendations. The |
jenshalm
added a commit
to jenshalm/munit
that referenced
this issue
Aug 9, 2021
These are unfixably broken for parallel execution which is the default in sbt. Addresses point 1) in scalameta#399, see that ticket for more details.
jenshalm
added a commit
to jenshalm/munit
that referenced
this issue
Aug 9, 2021
These types map 1:1 to suites/TaskDefs, which means that the complexity of some of the data structures can be avoided. Addresses point 2) in scalameta#399, see that ticket for more details.
jenshalm
added a commit
to jenshalm/munit
that referenced
this issue
Aug 10, 2021
These types map 1:1 to suites/TaskDefs, which means that the complexity of some of the data structures can be avoided. Addresses point 2) in scalameta#399, see that ticket for more details.
jenshalm
added a commit
to jenshalm/munit
that referenced
this issue
Aug 10, 2021
These are unfixably broken for parallel execution which is the default in sbt. Addresses point 1) in scalameta#399, see that ticket for more details.
jenshalm
added a commit
to jenshalm/munit
that referenced
this issue
Aug 10, 2021
These types map 1:1 to suites/TaskDefs, which means that the complexity of some of the data structures can be avoided. Addresses point 2) in scalameta#399, see that ticket for more details.
jenshalm
added a commit
to jenshalm/munit
that referenced
this issue
Aug 10, 2021
These types map 1:1 to suites/TaskDefs, which means that the complexity of some of the data structures can be avoided. Addresses point 2) in scalameta#399, see that ticket for more details.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I believe some of the issues are also a concern in the original project the code was forked from,
however, I'll only describe them from the munit perspective.
TLDR - my recommendations:
Remove support for
--no-stderr
and-q
(quiet) flags.They are very broken with parallel execution, which is the default in sbt, and cannot be made to work properly either.
Simplify
EventDispatcher
andRichLogger
by removing their support for multi-suite and multi-thread usage,which is not needed by the munit implementation and which would have race conditions if those features were needed.
In more detail:
Regarding 1)
The
--no-stderr
and-q
flags are currently not documented and also only supported for the JVM version of munit,but a user might stumble across them in the code and try them out which would lead to a pretty bad surprise.
These options redirect
System.out
andSystem.err
respectively, and they do this on a per-suite basis.This leads to unexpected behaviour in the default, parallel run mode, as the suites start to step on each other's toes.
In most cases this will leave
System.out
still pointing to aByteArrayOutputStream
even after all tests completed, permanently silencing munit until sbt is restarted.Even reverting the munit configuration change and using
reload
in the sbt console would not fix the issue.sbt has to be restarted to get back to normal, making this a really bad trap for users.
The issue is easy to reproduce.
-q
flag withTest / testOptions += Tests.Argument(TestFrameworks.MUnit, "-q")
.parallelExecution
at its default (true
)test
ortestOnly
with at least a handful of suites.Outcome:
System.out
internally).Given that those features are 1) undocumented, 2) not supported for JS or Native and 3) essentially unfixable,
I think it is best to remove them.
Regarding 2)
This is not a user issue, but more a maintainer's issue, so somewhat less critical.
I think the implementations of
EventDispatcher
andRichLogger
are confusing as they suggest a use casethat does not exist.
In practice both are pinned to a single suite and a single thread (see
JUnitTask.execute
).munit does not support nested suites or running the tests of a single suite in parallel.
The concurrent maps, keyed by suite, unnecessarily complicate the code, and give a false sense of security,
as their implementation for concurrent use is not even correct.
(The use of the
Stack
class inRichLogger
has a race condition). There is also a (minimal) performance overhead.A somewhat more defensive change would be to only remove the multi-suite support, but keep these classes thread-safe.
The current observation that usage is pinned to a thread might theoretically be undermined by future changes in
JUnitCore
orMUnitRunner
(e.g. when the latter would stop using a parasiticExecutionContext
).And removing multi-suite support alone already achieves most of the desired simplification.
Both of these suggestions are very simple changes, and I could quickly do them in the coming days,
but I wanted to see whether there are any concerns or objections before I do a PR.
The text was updated successfully, but these errors were encountered: