cpoerschke commented on a change in pull request #227: URL: https://github.com/apache/solr/pull/227#discussion_r674076231
########## File path: solr/core/src/test/org/apache/solr/util/TestObjectReleaseTracker.java ########## @@ -16,46 +16,103 @@ */ package org.apache.solr.util; -import org.apache.lucene.util.TestRuleLimitSysouts.Limit; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.ObjectReleaseTracker; +import org.apache.solr.common.util.SolrNamedThreadFactory; +import org.hamcrest.MatcherAssert; import org.junit.Test; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.hamcrest.Matchers.containsString; -@Limit(bytes=150000) // raise limit as this writes to sys err public class TestObjectReleaseTracker extends SolrTestCaseJ4 { - + @Test - public void testObjectReleaseTracker() { - ObjectReleaseTracker.track(new Object()); - ObjectReleaseTracker.release(new Object()); - assertNotNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); - assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); + public void testReleaseObject() { Object obj = new Object(); ObjectReleaseTracker.track(obj); ObjectReleaseTracker.release(obj); assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); - + Object obj1 = new Object(); ObjectReleaseTracker.track(obj1); Object obj2 = new Object(); ObjectReleaseTracker.track(obj2); Object obj3 = new Object(); ObjectReleaseTracker.track(obj3); - + ObjectReleaseTracker.release(obj1); ObjectReleaseTracker.release(obj2); ObjectReleaseTracker.release(obj3); assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); - + } + + @Test + public void testUnreleased() { + Object obj1 = new Object(); + Object obj2 = new Object(); + Object obj3 = new Object(); + ObjectReleaseTracker.track(obj1); ObjectReleaseTracker.track(obj2); ObjectReleaseTracker.track(obj3); ObjectReleaseTracker.release(obj1); ObjectReleaseTracker.release(obj2); // ObjectReleaseTracker.release(obj3); + assertNotNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); } + + @Test + public void testReleaseDifferentObject() { + ObjectReleaseTracker.track(new Object()); + ObjectReleaseTracker.release(new Object()); + assertNotNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); + assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); + } + + @Test + public void testAnonymousClasses() { + ObjectReleaseTracker.track(new Object() {}); + String message = SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1); + MatcherAssert.assertThat(message, containsString("[Object]")); + } + + @Test + public void testAsyncTracking() throws InterruptedException, ExecutionException { + ExecutorService es = ExecutorUtil.newMDCAwareSingleThreadExecutor(new SolrNamedThreadFactory("TestExecutor")); + Object trackable = new Object(); + + Future<?> result = es.submit(() -> { + ObjectReleaseTracker.track(trackable); + }); + + result.get(); // make sure that track has been called + String message = SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1); + MatcherAssert.assertThat(message, containsString(getTestName())); Review comment: We could perhaps also test here that the async details are captured too. I'll add a small commit, feel free to revert or amend. ########## File path: solr/core/src/test/org/apache/solr/util/TestObjectReleaseTracker.java ########## @@ -16,46 +16,103 @@ */ package org.apache.solr.util; -import org.apache.lucene.util.TestRuleLimitSysouts.Limit; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.ObjectReleaseTracker; +import org.apache.solr.common.util.SolrNamedThreadFactory; +import org.hamcrest.MatcherAssert; import org.junit.Test; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.hamcrest.Matchers.containsString; -@Limit(bytes=150000) // raise limit as this writes to sys err public class TestObjectReleaseTracker extends SolrTestCaseJ4 { - + @Test - public void testObjectReleaseTracker() { - ObjectReleaseTracker.track(new Object()); - ObjectReleaseTracker.release(new Object()); - assertNotNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); - assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); + public void testReleaseObject() { Object obj = new Object(); ObjectReleaseTracker.track(obj); ObjectReleaseTracker.release(obj); assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); - + Object obj1 = new Object(); ObjectReleaseTracker.track(obj1); Object obj2 = new Object(); ObjectReleaseTracker.track(obj2); Object obj3 = new Object(); ObjectReleaseTracker.track(obj3); - + ObjectReleaseTracker.release(obj1); ObjectReleaseTracker.release(obj2); ObjectReleaseTracker.release(obj3); assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); - + } + + @Test + public void testUnreleased() { + Object obj1 = new Object(); + Object obj2 = new Object(); + Object obj3 = new Object(); + ObjectReleaseTracker.track(obj1); ObjectReleaseTracker.track(obj2); ObjectReleaseTracker.track(obj3); ObjectReleaseTracker.release(obj1); ObjectReleaseTracker.release(obj2); // ObjectReleaseTracker.release(obj3); + assertNotNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); assertNull(SolrTestCaseJ4.clearObjectTrackerAndCheckEmpty(1)); Review comment: Not directly related to the pull request changes here but I wonder if at https://github.com/apache/lucene-solr/blob/releases/lucene-solr/8.9.0/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java#L433 the info logging might be `if (retries > 0)` qualified i.e. the "Done waiting" is only applicable if there was a "Waiting for all" to start with. Or turning the `break` into a `return` at https://github.com/apache/lucene-solr/blob/releases/lucene-solr/8.9.0/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java#L413 would have the same effect (assuming there's no additional track call happening after the break and before the clear at line 435). ########## File path: solr/solrj/src/java/org/apache/solr/common/util/ExecutorUtil.java ########## @@ -196,7 +198,13 @@ public void execute(final Runnable command) { String ctxStr = contextString.toString().replace("/", "//"); final String submitterContextStr = ctxStr.length() <= MAX_THREAD_NAME_LEN ? ctxStr : ctxStr.substring(0, MAX_THREAD_NAME_LEN); - final Exception submitterStackTrace = enableSubmitterStackTrace ? new Exception("Submitter stack trace") : null; + final Exception submitterStackTrace; + if (enableSubmitterStackTrace) { + Exception grandParentSubmitter = submitter.get(); + submitterStackTrace = new Exception("Submitter stack trace", grandParentSubmitter); Review comment: Hmm, yes, the tests help to demonstrate what is happening. But explaining it in a comment, well, that is trickier and so yes `grandParentSubmitter` is concise and comments as well might just add confusion. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org For additional commands, e-mail: issues-h...@solr.apache.org