This is an automated email from the ASF dual-hosted git repository.
tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new c9da2801ba switch to OK... we're not actually testing anything with
SLOW (#2788)
c9da2801ba is described below
commit c9da2801ba0eeb33f85db2ed3effa10b1a289039
Author: Tim Allison <[email protected]>
AuthorDate: Tue Apr 28 10:45:31 2026 -0400
switch to OK... we're not actually testing anything with SLOW (#2788)
---
.../tika/pipes/core/SharedServerModeTest.java | 82 +++++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)
diff --git
a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/SharedServerModeTest.java
b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/SharedServerModeTest.java
index 0aefd6dc46..59b8b4b3a5 100644
---
a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/SharedServerModeTest.java
+++
b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/SharedServerModeTest.java
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -77,6 +78,13 @@ public class SharedServerModeTest {
"<fakeload millis=\"60000\" cpu=\"1\" mb=\"10\"/>" +
"</mock>";
+ private static final String MOCK_INFLIGHT = "<?xml version=\"1.0\"
encoding=\"UTF-8\" ?>" +
+ "<mock>" +
+ "<metadata action=\"add\" name=\"dc:creator\">In-flight
Author</metadata>" +
+ "<write element=\"p\">In-flight content</write>" +
+ "<fakeload millis=\"3000\" cpu=\"1\" mb=\"10\"/>" +
+ "</mock>";
+
@Test
public void testBasicSharedMode(@TempDir Path tmp) throws Exception {
Path inputDir = setupInputDir(tmp);
@@ -191,7 +199,7 @@ public class SharedServerModeTest {
@Test
public void testGracefulShutdown(@TempDir Path tmp) throws Exception {
Path inputDir = setupInputDir(tmp);
- Files.writeString(inputDir.resolve("test.xml"), MOCK_SLOW,
StandardCharsets.UTF_8);
+ Files.writeString(inputDir.resolve("test.xml"), MOCK_OK,
StandardCharsets.UTF_8);
Path tikaConfigPath = PluginsTestHelper.getFileSystemFetcherConfig(
"tika-config-shared-server.json", tmp, inputDir,
tmp.resolve("output"), false);
@@ -216,6 +224,78 @@ public class SharedServerModeTest {
}
}
+ /**
+ * Verifies that close() unblocks an in-flight parse and returns promptly
when
+ * the parser is shut down at a randomized point in the parse lifecycle.
+ * <p>
+ * After a warmup parse to ensure the shared server is fully started, this
picks
+ * a random sleep in [0, 4000]ms before calling close(). Given the inflight
+ * fakeload runs ~3000ms, the chosen delay can land in init, mid-parse,
near the
+ * tail of parse, or post-completion. The seed is logged and included in
every
+ * assertion message so a CI failure can be reproduced via
+ * {@code -DcloseInFlightSeed=<seed>}.
+ */
+ @Test
+ public void testCloseAtRandomPhase(@TempDir Path tmp) throws Exception {
+ long seed = Long.getLong("closeInFlightSeed", System.nanoTime());
+ java.util.Random rng = new java.util.Random(seed);
+ long sleepBeforeCloseMs = rng.nextInt(4001); // [0, 4000]
+ String repro = "[seed=" + seed + ", sleep=" + sleepBeforeCloseMs +
"ms]";
+ System.out.println("testCloseAtRandomPhase " + repro);
+
+ Path inputDir = setupInputDir(tmp);
+ Files.writeString(inputDir.resolve("warmup.xml"), MOCK_OK,
StandardCharsets.UTF_8);
+ Files.writeString(inputDir.resolve("inflight.xml"), MOCK_INFLIGHT,
StandardCharsets.UTF_8);
+
+ Path tikaConfigPath = PluginsTestHelper.getFileSystemFetcherConfig(
+ "tika-config-shared-server.json", tmp, inputDir,
tmp.resolve("output"), false);
+ TikaJsonConfig tikaJsonConfig = TikaJsonConfig.load(tikaConfigPath);
+ PipesConfig pipesConfig = PipesConfig.load(tikaJsonConfig);
+
+ PipesParser pipesParser = PipesParser.load(tikaJsonConfig,
pipesConfig, tikaConfigPath);
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ try {
+ // Warmup so the shared server is fully started; without this,
short
+ // sleeps would always land in init rather than reaching mid-parse.
+ PipesResult warmup = pipesParser.parse(new FetchEmitTuple(
+ "warmup.xml",
+ new FetchKey(FETCHER_NAME, "warmup.xml"),
+ new EmitKey(EMITTER_NAME, ""),
+ new Metadata(),
+ new ParseContext(),
+ FetchEmitTuple.ON_PARSE_EXCEPTION.SKIP));
+ assertTrue(warmup.isSuccess(), "Warmup parse must succeed " +
repro);
+
+ Future<PipesResult> future = executor.submit(() ->
pipesParser.parse(new FetchEmitTuple(
+ "inflight.xml",
+ new FetchKey(FETCHER_NAME, "inflight.xml"),
+ new EmitKey(EMITTER_NAME, ""),
+ new Metadata(),
+ new ParseContext(),
+ FetchEmitTuple.ON_PARSE_EXCEPTION.SKIP)));
+
+ if (sleepBeforeCloseMs > 0) {
+ Thread.sleep(sleepBeforeCloseMs);
+ }
+
+ long closeStart = System.currentTimeMillis();
+ pipesParser.close();
+ long closeDuration = System.currentTimeMillis() - closeStart;
+
+ assertTrue(closeDuration < 15000,
+ "close() should return promptly even with in-flight work;
took " +
+ closeDuration + "ms " + repro);
+
+ // The in-flight request must return - not deadlock waiting on a
closed socket
+ PipesResult result = future.get(15, TimeUnit.SECONDS);
+ assertNotNull(result, "In-flight parse should return a result, not
hang " + repro);
+ // Result may be SUCCESS (parse finished before close) or a
crash/init-failure
+ // status (close tore down the socket mid-flight) - both are
acceptable.
+ } finally {
+ executor.shutdownNow();
+ }
+ }
+
@Test
public void testPerClientModeStillWorks(@TempDir Path tmp) throws
Exception {
// Verify default per-client mode still works