-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Do not stop MockLogAppender instances #12134
Conversation
When JUnit tests run concurrently they are mostly isolated but they do share static state. Tests generally don't rely on static state, with the notable exception of when they manipulate the logger to test the logging behavior of the code under test. This leads to problems if say test 1 stops a test log appender, then test 2 causes a logging message which attempts to append to that logging appender. The logging system will generate an error which leads to spurious failures in test 2. I previously attempted to avoid these problems by ensuring that test log appenders are removed before they are stopped. However, that doesn't completely eliminate race conditions as the list of appenders maintained by the logging system is essentially a copy-on-write array list. That means test 2 can get a reference of the appender list, then test 1 can remove and stop an appended, but test 2 still has a reference to a version of the list that contained the now stopped appender. I have now come to the conclusion that the easiest way to fix this problem (without mucking with the implementation details or concurrency properties of the logging system itself) is to not stop the test appenders. They maintain no external state so they can be safely removed without being stopped and they will just be garbage collected and everyone will be happy. Signed-off-by: Andrew Ross <[email protected]>
Compatibility status:Checks if related components are compatible with change 0f8047d Incompatible componentsIncompatible components: [https://github.com/opensearch-project/cross-cluster-replication.git, https://github.com/opensearch-project/performance-analyzer.git, https://github.com/opensearch-project/performance-analyzer-rca.git] Skipped componentsCompatible componentsCompatible components: [https://github.com/opensearch-project/asynchronous-search.git, https://github.com/opensearch-project/security-analytics.git, https://github.com/opensearch-project/observability.git, https://github.com/opensearch-project/reporting.git, https://github.com/opensearch-project/opensearch-oci-object-storage.git, https://github.com/opensearch-project/job-scheduler.git, https://github.com/opensearch-project/custom-codecs.git, https://github.com/opensearch-project/sql.git, https://github.com/opensearch-project/common-utils.git, https://github.com/opensearch-project/notifications.git, https://github.com/opensearch-project/security.git, https://github.com/opensearch-project/ml-commons.git, https://github.com/opensearch-project/anomaly-detection.git, https://github.com/opensearch-project/index-management.git, https://github.com/opensearch-project/neural-search.git, https://github.com/opensearch-project/geospatial.git, https://github.com/opensearch-project/alerting.git, https://github.com/opensearch-project/k-nn.git] |
❕ Gradle check result for 0f8047d: UNSTABLE
Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #12134 +/- ##
============================================
- Coverage 71.40% 71.30% -0.10%
+ Complexity 59505 59431 -74
============================================
Files 4925 4925
Lines 279540 279540
Branches 40646 40646
============================================
- Hits 199594 199328 -266
- Misses 63314 63610 +296
+ Partials 16632 16602 -30 ☔ View full report in Codecov by Sentry. |
Thanks @andrross for persisting to get this one fixed
So this is my understanding of how we do that:
The static state between tests should not be shared between JVMs but it is possible that we don't clean up properly after some test suites so this problem emerges. |
@reta You're right. I didn't realize all test concurrency happened via forked JVMs, but some experimentation definitely shows that to be true. I'll dig into this some more, but another way this could be happening even within the context of a single test is that |
When JUnit tests run concurrently they are mostly isolated but they do share static state. Tests generally don't rely on static state, with the notable exception of when they manipulate the logger to test the logging behavior of the code under test. This leads to problems if say test 1 stops a test log appender, then test 2 causes a logging message which attempts to append to that logging appender. The logging system will generate an error which leads to spurious failures in test 2. I previously attempted to avoid these problems by ensuring that test log appenders are removed before they are stopped. However, that doesn't completely eliminate race conditions as the list of appenders maintained by the logging system is essentially a copy-on-write array list. That means test 2 can get a reference of the appender list, then test 1 can remove and stop an appended, but test 2 still has a reference to a version of the list that contained the now stopped appender. I have now come to the conclusion that the easiest way to fix this problem (without mucking with the implementation details or concurrency properties of the logging system itself) is to not stop the test appenders. They maintain no external state so they can be safely removed without being stopped and they will just be garbage collected and everyone will be happy.
Related Issues
Resolves #10799
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.