This is an automated email from the ASF dual-hosted git repository.

FrankChen021 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new e2a89971bd8 fix: route IngestionSmokeTest log fetch through the real 
Overlord leader (#20841)
e2a89971bd8 is described below

commit e2a89971bd8dd5887108353d217d75fca2958910
Author: rishi-rana <[email protected]>
AuthorDate: Wed Nov 4 22:26:44 2026 -0800

    fix: route IngestionSmokeTest log fetch through the real Overlord leader 
(#20841)
    
    The log poll in test_streamLogs_ofCancelledTask read
    overlord.bindings().getInstance(TaskLogStreamer.class) directly, which only
    has live task state if that specific embedded Overlord instance happens to
    be the leader. In subclasses where the leader is a separate container/pod
    (e.g. KubernetesClusterDockerTest, IngestionDockerTest,
    IngestionBackwardCompatibilityDockerTest, 
BaseKubernetesTaskRunnerDockerTest),
    the embedded "overlord" field is never leader, so its local TaskLogStreamer
    binding always returns absent and the stream stays empty for the whole poll.
    
    Fetch the log over HTTP from whichever Overlord is actually leading, found
    via cluster.callApi().onLeaderOverlord(OverlordClient::findCurrentLeader) -
    the same leader-discovery mechanism the test already uses for
    runTask/cancelTask - instead of reading local bindings directly.
    
    Fixes #20435.
    
    Assisted with AI Claude.
---
 .../embedded/indexing/IngestionSmokeTest.java      | 49 ++++++++++++----------
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git 
a/embedded-tests/src/test/java/org/apache/druid/testing/embedded/indexing/IngestionSmokeTest.java
 
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/indexing/IngestionSmokeTest.java
index dcab6cabad8..132c06c20aa 100644
--- 
a/embedded-tests/src/test/java/org/apache/druid/testing/embedded/indexing/IngestionSmokeTest.java
+++ 
b/embedded-tests/src/test/java/org/apache/druid/testing/embedded/indexing/IngestionSmokeTest.java
@@ -20,7 +20,6 @@
 package org.apache.druid.testing.embedded.indexing;
 
 import com.google.common.base.Optional;
-import org.apache.commons.io.IOUtils;
 import org.apache.druid.common.utils.IdUtils;
 import org.apache.druid.data.input.impl.CsvInputFormat;
 import org.apache.druid.data.input.impl.TimestampSpec;
@@ -46,7 +45,6 @@ import org.apache.druid.query.DruidMetrics;
 import org.apache.druid.query.http.SqlTaskStatus;
 import org.apache.druid.rpc.indexing.OverlordClient;
 import org.apache.druid.segment.metadata.Metric;
-import org.apache.druid.tasklogs.TaskLogStreamer;
 import org.apache.druid.testing.embedded.EmbeddedBroker;
 import org.apache.druid.testing.embedded.EmbeddedCoordinator;
 import org.apache.druid.testing.embedded.EmbeddedDruidCluster;
@@ -69,8 +67,10 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -434,24 +434,29 @@ public class IngestionSmokeTest extends 
EmbeddedClusterTestBase
         taskId, runDurationMillis
     );
 
-    // The Indexer serves this task's log over HTTP straight from its own 
process log file
-    // (see HttpRemoteTaskRunner#streamTaskLog), so the stream can become 
present before the
-    // expected line has actually been written to that file. Poll until the 
expected line shows
-    // up, rather than just until the stream is present, to avoid racing 
against that lag.
-    final String logs = cluster.callApi().waitForResult(
-        () -> {
-          final Optional<InputStream> streamOptional = overlord.bindings()
-                                                                 
.getInstance(TaskLogStreamer.class)
-                                                                 
.streamTaskLog(taskId, 0);
-          if (!streamOptional.isPresent()) {
-            return "";
-          }
-          try (InputStream stream = streamOptional.get()) {
-            return IOUtils.toString(stream, StandardCharsets.UTF_8);
-          }
-        },
-        logContent -> logContent.contains(expectedLogLine)
-    ).go();
+    // Fetch the log over HTTP from whichever Overlord is actually leading, 
the same way
+    // runTask/cancelTask above do. The local "overlord" field's bindings only 
have task state
+    // if that particular instance happens to be leader, which is not true in 
subclasses where
+    // the leader is a separate container/pod (e.g. 
KubernetesClusterDockerTest).
+    final URI leaderOverlordUri = 
cluster.callApi().onLeaderOverlord(OverlordClient::findCurrentLeader);
+    final URI logUri = URI.create(leaderOverlordUri + 
"/druid/indexer/v1/task/" + taskId + "/log?offset=0");
+
+    // The log can become available on the leader before the expected line has 
actually been
+    // written to it, so poll until the content shows up rather than just 
until the request
+    // succeeds.
+    final String logs;
+    try (HttpClient httpClient = HttpClient.newHttpClient()) {
+      logs = cluster.callApi().waitForResult(
+          () -> {
+            final HttpResponse<String> response = httpClient.send(
+                HttpRequest.newBuilder(logUri).GET().build(),
+                HttpResponse.BodyHandlers.ofString()
+            );
+            return response.statusCode() == 200 ? response.body() : "";
+          },
+          logContent -> logContent.contains(expectedLogLine)
+      ).go();
+    }
 
     Assertions.assertFalse(logs.isEmpty());
     Assertions.assertTrue(logs.contains(expectedLogLine), "Actual logs are: " 
+ logs);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to