This is an automated email from the ASF dual-hosted git repository.
csringhofer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git
The following commit(s) were added to refs/heads/master by this push:
new 720b94ad9 IMPALA-13419: Improve test_http_socket_timeout
720b94ad9 is described below
commit 720b94ad992d6bbde0d3c3ec69bd52e6b2d0e63c
Author: Michael Smith <[email protected]>
AuthorDate: Mon Feb 9 15:13:07 2026 -0800
IMPALA-13419: Improve test_http_socket_timeout
Uses a debug action in ExecuteStatement to add a sleep so we can test a
longer http_socket_timeout_s setting, which makes the test more
consistent. Fixes test failures with ASAN builds.
The change in testing means the failure no longer happens during 'SET
ALL' - which was too quick to be reliable - where impala-shell would
then CloseSession after failure. It now happens during executing the
query, which can result in leaving a query behind after the connection
is closed. Moves the test to custom cluster testing because there's no
way to reliably ensure the session is closed after disconnect;
idle_session_timeout should in theory work, but impala-shell has no way
to set it and detecting closed connections takes too long.
Fixes a DCHECK failure exposed by this test where registration fails
because the session has been closed and therefore the query driver was
not finalized:
760958 impala-server.cc:1522] ...] RegisterQuery(): session has been
closed, ignoring query.
760958 query-driver.cc:46] Check failed: finalized_.Load() Finalize()
must have been called
Testing: ran test_http_socket_timeout a bunch of times with ASAN.
Change-Id: Idf31bb1752586ebc296e5e8d62c035bac7371dfb
Reviewed-on: http://gerrit.cloudera.org:8080/23955
Reviewed-by: Csaba Ringhofer <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
---
be/src/runtime/query-driver.cc | 6 ++-
be/src/runtime/query-driver.h | 3 ++
be/src/service/impala-server.cc | 8 +++-
tests/custom_cluster/test_shell_commandline.py | 41 ++++++++++++++++++++
tests/shell/test_shell_commandline.py | 52 --------------------------
5 files changed, 55 insertions(+), 55 deletions(-)
diff --git a/be/src/runtime/query-driver.cc b/be/src/runtime/query-driver.cc
index 05ec95571..b62d46330 100644
--- a/be/src/runtime/query-driver.cc
+++ b/be/src/runtime/query-driver.cc
@@ -548,7 +548,11 @@ Status
QueryDriver::Unregister(ImpalaServer::QueryDriverMap* query_driver_map) {
return Status::OK();
}
-void QueryDriver::IncludeInQueryLog(const bool include) noexcept{
+void QueryDriver::Abandon() {
+ finalized_.Store(true);
+}
+
+void QueryDriver::IncludeInQueryLog(const bool include) noexcept {
include_in_query_log_ = include;
}
diff --git a/be/src/runtime/query-driver.h b/be/src/runtime/query-driver.h
index 9ad0e3e10..f6419da0b 100644
--- a/be/src/runtime/query-driver.h
+++ b/be/src/runtime/query-driver.h
@@ -189,6 +189,9 @@ class QueryDriver {
/// Delete this query from the given QueryDriverMap.
Status Unregister(ImpalaServer::QueryDriverMap* query_driver_map)
WARN_UNUSED_RESULT;
+ /// Abandon this query. This is used in scenarios where the query was never
registered.
+ void Abandon();
+
/// True if Finalize() was called while the query was inflight.
bool finalized() const { return finalized_.Load(); }
diff --git a/be/src/service/impala-server.cc b/be/src/service/impala-server.cc
index 6ac2646cc..4bd5f0dde 100644
--- a/be/src/service/impala-server.cc
+++ b/be/src/service/impala-server.cc
@@ -1347,8 +1347,12 @@ Status ImpalaServer::Execute(TQueryCtx* query_ctx,
query_handle->query_driver()->IncludeInQueryLog(include_in_query_log);
// Unregister query if it was registered and not yet finalized.
- if (!status.ok() && registered_query &&
!query_handle->query_driver()->finalized()) {
- UnregisterQueryDiscardResult((*query_handle)->query_id(), &status);
+ if (!status.ok() && !query_handle->query_driver()->finalized()) {
+ if (registered_query) {
+ UnregisterQueryDiscardResult((*query_handle)->query_id(), &status);
+ } else {
+ query_handle->query_driver()->Abandon();
+ }
}
return status;
}
diff --git a/tests/custom_cluster/test_shell_commandline.py
b/tests/custom_cluster/test_shell_commandline.py
index 77d5d4d8b..6fd4a02b3 100644
--- a/tests/custom_cluster/test_shell_commandline.py
+++ b/tests/custom_cluster/test_shell_commandline.py
@@ -172,3 +172,44 @@ class TestImpalaShellCommandLine(CustomClusterTestSuite):
for line in log_file:
if line.find("HTTP Connection Tracing Headers") != -1:
pytest.fail("found HTTP connection tracing line line:
{0}".format(line))
+
+ @CustomClusterTestSuite.with_args(cluster_size=1)
+ def test_http_socket_timeout(self, vector):
+ """Test setting different http_socket_timeout_s values. Runs as a custom
cluster test
+ because session is not closed up after the test."""
+ assert vector.get_value('protocol') == 'hs2-http'
+ # Test short http_socket_timeout_s, expect errors. After the connection is
+ # established - which now uses connect_timeout_ms - RPCs in the
minicluster appear to
+ # respond immediately, so non-blocking mode (timeout=0) does not result in
an error.
+ # Instead, use a small timeout that allows OpenSession to succeed, then
fails on
+ # ExecuteStatement due to a 1s sleep via debug action. 100ms timeout is
used to allow
+ # SET ALL to succeed, so we fail predictably. Session and query timeouts
are used to
+ # cleanup the query started by Execute, because after the timeout the
socket is closed
+ # and impala-shell doesn't close the session.
+ debug_action = 'debug_action=EXECUTE_INTERNAL_REGISTERED:SLEEP@1000'
+ args = ['--quiet', '-B', '-Q', debug_action, '--query', 'select 0']
+ result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=0.1'],
+ expect_success=False)
+
+ # Python 2 throws socket.timeout and Python 3 throws TimeoutError.
+ error_template = "[Exception] type=<class '{0}'> in ExecuteStatement.
timed out"
+ err_py2 = error_template.format("socket.timeout")
+ err_py3 = error_template.format("TimeoutError")
+ assert err_py2 in result.stderr or err_py3 in result.stderr, result.stderr
+
+ # Test http_socket_timeout_s=-1, expect errors
+ result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=-1'],
+ expect_success=False)
+ expected_err = ("http_socket_timeout_s must be a nonnegative floating
point number"
+ " expressing seconds, or None")
+ assert expected_err in result.stderr
+
+ # Test http_socket_timeout_s>0, expect success
+ result = run_impala_shell_cmd(vector, args + ['--http_socket_timeout_s=2'])
+ assert result.stderr == ""
+ assert result.stdout == "0\n"
+
+ # Test http_socket_timeout_s=None, expect success
+ result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=None'])
+ assert result.stderr == ""
+ assert result.stdout == "0\n"
diff --git a/tests/shell/test_shell_commandline.py
b/tests/shell/test_shell_commandline.py
index a79b0260d..1f9c454b6 100644
--- a/tests/shell/test_shell_commandline.py
+++ b/tests/shell/test_shell_commandline.py
@@ -63,19 +63,6 @@ RUSSIAN_CHARS = utf8_encode_if_needed(
u"А, Б, В, Г, Д, Е, Ё, Ж, З, И, Й, К, Л, М, Н, О, П, Р,"
u"С, Т, У, Ф, Х, Ц,Ч, Ш, Щ, Ъ, Ы, Ь, Э, Ю, Я")
-"""IMPALA-12216 implemented timestamp to be printed in case of any
error/warning
- during query execution, below is an example :
-
- 2024-07-15 12:49:27 [Exception] type=<class 'socket.error'> in FetchResults.
- 2024-07-15 12:49:27 [Warning] Cancelling Query
- 2024-07-15 12:49:27 [Warning] close session RPC failed: <class
'shell_exceptions.
- QueryCancelledByShellException'>
-
- To avoid test flakiness due to timestamp, we would be ignoring timestamp in
actual
- result before asserting with expected result, (YYYY-MM-DD hh:mm:ss ) is of
length 20
-"""
-TS_LEN = 20
-
def find_query_option(key, string, strip_brackets=True):
"""
@@ -1476,45 +1463,6 @@ class TestImpalaShell(ImpalaTestSuite):
rows_from_file = [line.rstrip() for line in f]
assert rows_from_stdout == rows_from_file
- @pytest.mark.execute_serially
- def test_http_socket_timeout(self, vector):
- """Test setting different http_socket_timeout_s values."""
- if (vector.get_value('strict_hs2_protocol')
- or vector.get_value('protocol') != 'hs2-http'):
- pytest.skip("http socket timeout not supported in strict hs2 mode."
- " Only supported with hs2-http protocol.")
- # Test very short http_socket_timeout_s, expect errors. After the
connection is
- # established - which now uses connect_timeout_ms - RPCs in the
minicluster appear to
- # respond immediately, so non-blocking mode (timeout=0) does not result in
an error.
- # Instead, use a very small timeout that the RPC cannot meet.
- args = ['--quiet', '-B', '--query', 'select 0']
- result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=0.001'],
- expect_success=False)
-
- # Python 2 throws socket.timeout and Python 3 throws TimeoutError.
- error_template = "[Exception] type=<class '{0}'> in ExecuteStatement.
timed out"
- pyver_exceptions = ["socket.timeout", "TimeoutError"]
- actual_err = result.stderr.splitlines()[0]
- assert actual_err[TS_LEN:] in [error_template.format(pever_exception)
- for pever_exception in pyver_exceptions]
-
- # Test http_socket_timeout_s=-1, expect errors
- result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=-1'],
- expect_success=False)
- expected_err = ("http_socket_timeout_s must be a nonnegative floating
point number"
- " expressing seconds, or None")
- assert result.stderr.splitlines()[0] == expected_err
-
- # Test http_socket_timeout_s>0, expect success
- result = run_impala_shell_cmd(vector, args + ['--http_socket_timeout_s=2'])
- assert result.stderr == ""
- assert result.stdout == "0\n"
-
- # Test http_socket_timeout_s=None, expect success
- result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=None'])
- assert result.stderr == ""
- assert result.stdout == "0\n"
-
def test_connect_max_tries(self, vector):
"""Test setting different connect_max_tries values."""
if (vector.get_value('strict_hs2_protocol')