Skip to content

Commit 8c49326

Browse files
dsmileyclaude
andauthored
SOLR-18188: Misc test fixes (#4496)
Accumulated from several commits on the misc-test-fixes branch. PrepRecoveryOp: add class-level javadoc to explain its purpose. ShowFileRequestHandlerTest, TestPrometheusResponseWriter, TestCborDataFormat: close response streams to fix resource leaks flagged by the test framework. TestDistributedTracing: add retry logic around span assertions to reduce flakiness caused by timing-sensitive telemetry delivery. SocketProxy: call setSoTimeout(1000) on the server socket so the accept loop unblocks promptly when close() is called. Without a timeout the acceptor thread blocks indefinitely in accept() and leaks, causing test hangs or "thread leaked" warnings. JettySolrRunner: move proxy.close() to before server.stop() rather than leaving it in the finally block. If qtp.join() hangs (e.g. stuck PrepRecoveryOp handlers or H2C session threads) the finally block is never reached, leaving the SocketProxy acceptor thread leaked. Closing the proxy first ensures cleanup even when server shutdown hangs. HttpJettySolrClientCompatibilityTest: switch from @ClassRule to @rule so the Jetty server lifecycle is per-test as intended. TestSolrJ: delete this file -- it contains no actual tests. ClientUtils: add Objects.requireNonNull() guard on serverRootUrl to surface null earlier with a clear error rather than a cryptic NPE downstream. AbstractFullDistribZkTestBase: wrap control-collection creation in RetryUtil.retryOnException() to tolerate transient ZooKeeper errors during setup. Also move coreClients.clear(), solrClientByCollection.clear(), and super.destroyServers() into a finally block after ExecutorUtil.shutdownAndAwaitTermination() so teardown always completes even if the executor shutdown throws. HttpPartitionTest: decrease leaderConflictResolveWait to 10sec so stale PrepRecoveryOp handlers time out within the Jetty graceful stop window Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent de1e742 commit 8c49326

12 files changed

Lines changed: 105 additions & 226 deletions

File tree

solr/core/src/java/org/apache/solr/handler/admin/PrepRecoveryOp.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@
3737
import org.slf4j.Logger;
3838
import org.slf4j.LoggerFactory;
3939

40+
/**
41+
* Long-polling request sent by a recovering replica to the shard leader. The leader holds the
42+
* request open, waiting until it observes the replica reach the expected state (typically
43+
* RECOVERING) in ZooKeeper before responding. This synchronization ensures the leader is ready to
44+
* accept updates from the replica before recovery proceeds. The wait is bounded by {@code
45+
* leaderConflictResolveWait} (default 180s).
46+
*/
4047
class PrepRecoveryOp implements CoreAdminHandler.CoreAdminOp {
4148
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
4249

solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public static void setupSysProps() {
8383
System.setProperty("solr.httpclient.retries", "0");
8484
System.setProperty("solr.retries.on.forward", "0");
8585
System.setProperty("solr.retries.to.followers", "0");
86+
// Keep short so stale PrepRecoveryOp handlers time out within the Jetty graceful stop window
87+
System.setProperty("leaderConflictResolveWait", "10000");
8688
}
8789

8890
public HttpPartitionTest() {

solr/core/src/test/org/apache/solr/handler/admin/ShowFileRequestHandlerTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ public void testIllegalContentType() throws SolrServerException, IOException {
142142
createShowFileRequest(params("file", "managed-schema", "contentType", "not/known"));
143143
request.setResponseParser(new InputStreamResponseParser("xml"));
144144
NamedList<Object> response = client.request(request);
145+
closeResponseStream(response);
145146
assertEquals(response.get("responseStatus"), 404);
146147
}
147148

@@ -152,6 +153,7 @@ public void testAbsoluteFilename() throws SolrServerException, IOException {
152153
params("file", "/etc/passwd", "contentType", "text/plain; charset=utf-8"));
153154
request.setResponseParser(new InputStreamResponseParser("xml"));
154155
NamedList<Object> response = client.request(request);
156+
closeResponseStream(response);
155157
assertEquals(response.get("responseStatus"), 404);
156158
}
157159

@@ -162,6 +164,7 @@ public void testEscapeConfDir() throws SolrServerException, IOException {
162164
params("file", "../../solr.xml", "contentType", "application/xml; charset=utf-8"));
163165
request.setResponseParser(new InputStreamResponseParser("xml"));
164166
NamedList<Object> response = client.request(request);
167+
closeResponseStream(response);
165168
assertEquals(response.get("responseStatus"), 400);
166169
}
167170

@@ -176,6 +179,7 @@ public void testPathTraversalFilename() throws SolrServerException, IOException
176179
"text/plain; charset=utf-8"));
177180
request.setResponseParser(new InputStreamResponseParser("xml"));
178181
NamedList<Object> response = client.request(request);
182+
closeResponseStream(response);
179183
assertEquals(response.get("responseStatus"), 400);
180184
}
181185

@@ -202,4 +206,11 @@ public void testGetSafeContentType() {
202206
// Non-known content types are rejected with 400 error
203207
expectThrows(SolrException.class, () -> ShowFileRequestHandler.getSafeContentType("foo/bar"));
204208
}
209+
210+
private void closeResponseStream(NamedList<Object> response) throws IOException {
211+
InputStream stream = (InputStream) response.get("stream");
212+
if (stream != null) {
213+
stream.close();
214+
}
215+
}
205216
}

solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ public void testUnsupportedMetricsFormat() throws Exception {
193193

194194
try (SolrClient adminClient = getHttpSolrClient(solrTestRule.getBaseUrl())) {
195195
NamedList<Object> res = adminClient.request(req);
196+
InputStream stream = (InputStream) res.get("stream");
197+
if (stream != null) stream.close();
196198
// Unknown wt parameter should return a 400 error
197199
assertEquals(400, res.get("responseStatus"));
198200
}

solr/core/src/test/org/apache/solr/search/TestSolrJ.java

Lines changed: 0 additions & 188 deletions
This file was deleted.

solr/core/src/test/org/apache/solr/util/TestCborDataFormat.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ private byte[] runQuery(String testCollection, CloudSolrClient client, String wt
135135
request.setResponseParser(new InputStreamResponseParser(wt));
136136
}
137137
result = client.request(request, testCollection);
138-
InputStream inputStream = (InputStream) result.get("stream");
139-
byte[] b = inputStream.readAllBytes();
138+
byte[] b;
139+
try (InputStream inputStream = (InputStream) result.get("stream")) {
140+
b = inputStream.readAllBytes();
141+
}
140142
System.out.println(wt + "_time : " + timer.getTime());
141143
System.out.println(wt + "_size : " + b.length);
142144
return b;

0 commit comments

Comments
 (0)