This is an automated email from the ASF dual-hosted git repository.
stigahuang 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 2535e7949 IMPALA-12216: Print timestamp for impala-shell errors
2535e7949 is described below
commit 2535e79491078a0353dbeed1a094e91366906149
Author: Saurabh Katiyal <[email protected]>
AuthorDate: Wed May 15 00:06:51 2024 +0530
IMPALA-12216: Print timestamp for impala-shell errors
This change will print timestamp of an exception or warning
occurred during execution of a query via impala-shell.
The timestamp will use timezone of the machine running impala-shell.
example:
Query submitted at: 2024-08-22 16:17:57 (Coordinator: http://host:25000)
Query state can be monitored at:
http://localhost:25000/query_plan?query_id=e04dcc55e560d1ee:11173fe800000000
^C Cancelling Query
Opened TCP connection to localhost:21050
2024-08-22 16:17:58 [Exception] type=<class 'socket.error'> in FetchResults.
[Errno 4] Interrupted system call
2024-08-22 16:17:58 [Warning] Cancelling Query
2024-08-22 16:17:58 [Warning] close session RPC failed: <class
'shell_exceptions.QueryCancelledByShellException'>
Opened TCP connection to localhost:21050
[localhost:21050] default>
Change-Id: I4abbd02aa9f61210b0333495bf191e72c22a5944
Reviewed-on: http://gerrit.cloudera.org:8080/21426
Reviewed-by: Impala Public Jenkins <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
---
shell/impala_client.py | 49 +++++++++----
shell/impala_shell.py | 24 ++++---
tests/custom_cluster/test_hs2_fault_injection.py | 91 ++++++++++++++----------
tests/custom_cluster/test_shell_jwt_auth.py | 4 +-
tests/shell/test_shell_commandline.py | 26 +++++--
tests/shell/util.py | 2 +-
6 files changed, 124 insertions(+), 72 deletions(-)
diff --git a/shell/impala_client.py b/shell/impala_client.py
index 39e8d397f..284d1923d 100755
--- a/shell/impala_client.py
+++ b/shell/impala_client.py
@@ -770,7 +770,8 @@ class ImpalaHS2Client(ImpalaClient):
resp = self._do_hs2_rpc(CloseSession, req)
self._check_hs2_rpc_status(resp.status)
except Exception as e:
- print("Warning: close session RPC failed: {0}, {1}".format(str(e),
type(e)))
+ log_exception_with_timestamp(e, "Warning",
+ "close session RPC failed: {0}".format(type(e)), stderr_flag=False)
self.session_handle = None
self._close_transport()
@@ -801,13 +802,13 @@ class ImpalaHS2Client(ImpalaClient):
if (r.exception_type == RPC_EXCEPTION_TAPPLICATION or
r.exception_type == RPC_EXCEPTION_SERVER):
raise
- print('Caught exception {0}, type={1} when listing query options. {2}'
- .format(str(r), type(r), retry_msg), file=sys.stderr)
+ log_exception_with_timestamp(r, "Exception",
+ "type={0} when listing query options. {1}".format(type(r),
retry_msg))
if raise_error:
raise
except Exception as e:
- print('Caught exception {0}, type={1} when listing query options. {2}'
- .format(str(e), type(e), retry_msg), file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception",
+ "type={0} when listing query options. {1}".format(type(e),
retry_msg))
if raise_error:
raise
finally:
@@ -1161,8 +1162,8 @@ class ImpalaHS2Client(ImpalaClient):
if isinstance(e.inner, socket.error):
e = e.inner
# issue with the connection with the impalad
- print('Caught exception {0}, type={1} in {2}. {3}'
- .format(str(e), type(e), rpc.__name__, retry_msg), file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception",
+ "type={0} in {1}. {2}".format(type(e), rpc.__name__, retry_msg))
self._print_rpc_end(rpc, None, start_time, "Error -
TTransportException")
if raise_error:
if isinstance(e, TTransportException):
@@ -1186,18 +1187,18 @@ class ImpalaHS2Client(ImpalaClient):
except ValueError:
retry_secs = None
if retry_secs:
- print('Caught exception {0}, type={1} in {2}. {3}, retry after {4}
secs'
- .format(str(h), type(h), rpc.__name__, retry_msg, retry_secs),
- file=sys.stderr)
+ log_exception_with_timestamp(h, "Exception",
+ "type={0} in {1}. {2}, retry after {3} secs"
+ .format(type(h), rpc.__name__, retry_msg, retry_secs))
else:
- print('Caught exception {0}, type={1} in {2}. {3}'
- .format(str(h), type(h), rpc.__name__, retry_msg),
file=sys.stderr)
+ log_exception_with_timestamp(h, "Exception", "type={0} in {1}. {2}"
+ .format(type(h), rpc.__name__, retry_msg))
self._print_rpc_end(rpc, None, start_time, "Error - HttpError")
if raise_error:
raise
except Exception as e:
- print('Caught exception {0}, type={1} in {2}. {3}'
- .format(str(e), type(e), rpc.__name__, retry_msg), file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception", "type={0} in {1}. {2}"
+ .format(type(e), rpc.__name__, retry_msg))
self._print_rpc_end(rpc, None, start_time, "Error")
if raise_error:
raise
@@ -1613,6 +1614,24 @@ class ImpalaBeeswaxClient(ImpalaClient):
if "QueryNotFoundException" in str(e):
raise QueryStateException('Error: Stale query handle')
# Print more details for other kinds of exceptions
- print('Caught exception {0}, type={1}'.format(str(e), type(e)),
file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception",
"type={0}".format(type(e)))
traceback.print_exc()
raise Exception("Encountered unknown exception")
+
+
+def log_exception_with_timestamp(e, type="Exception", msg="",
stderr_flag=True):
+ # method log_exception_with_timestamp prints timestamp with exception trace
+ # and accepts custom message before timestamp. stderr_flag controls print
statement
+ # to be logged in stderr, by default it is true.
+ if(stderr_flag):
+ print("%s [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime()), type,
+ msg), e, file=sys.stderr)
+ else:
+ print("%s [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime()), type,
+ msg), e)
+
+
+def log_timestamp(type="Exception", msg=""):
+ # method log_timestamp prints timestamp with custom message
+ print("%s [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
type, msg),
+ file=sys.stderr)
diff --git a/shell/impala_shell.py b/shell/impala_shell.py
index afff90ee0..b7a491d1f 100755
--- a/shell/impala_shell.py
+++ b/shell/impala_shell.py
@@ -41,7 +41,7 @@ import time
import traceback
from impala_client import ImpalaHS2Client, StrictHS2Client, \
- ImpalaBeeswaxClient, QueryOptionLevels
+ ImpalaBeeswaxClient, QueryOptionLevels, log_exception_with_timestamp,
log_timestamp
from impala_shell_config_defaults import impala_shell_defaults
from option_parser import get_option_parser, get_config_from_file
from shell_output import (DelimitedOutputFormatter, OutputStream,
PrettyOutputFormatter,
@@ -1116,8 +1116,8 @@ class ImpalaShell(cmd.Cmd, object):
if self.use_ssl and sys.version_info < (2,7,9) \
and "EOF occurred in violation of protocol" in str(e):
print("Warning: TLSv1.2 is not supported for Python < 2.7.9",
file=sys.stderr)
- print("%s: %s, %s" %
- (self.ERROR_CONNECTING_MESSAGE, type(e).__name__, e),
file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception",
+ self.ERROR_CONNECTING_MESSAGE + type(e).__name__)
# A secure connection may still be open. So we explicitly close it.
self.close_connection()
# If a connection to another impalad failed while already connected
@@ -1467,10 +1467,11 @@ class ImpalaShell(cmd.Cmd, object):
if self.show_profiles: raise e
return CmdStatus.SUCCESS
except QueryCancelledByShellException as e:
+ log_exception_with_timestamp(e, "Warning", "Query Interrupted")
return CmdStatus.SUCCESS
except RPCException as e:
# could not complete the rpc successfully
- print(e, file=sys.stderr)
+ log_exception_with_timestamp(e)
except UnicodeDecodeError as e:
# An error occoured possibly during the fetching.
# Depending of which protocol is at use it can come from different
places.
@@ -1478,8 +1479,8 @@ class ImpalaShell(cmd.Cmd, object):
# undecodable elements.
if self.last_query_handle is not None:
self.imp_client.close_query(self.last_query_handle)
- print('UnicodeDecodeError : %s \nPlease check for columns containing
binary data '
- 'to find the possible source of the error.' % (e,), file=sys.stderr)
+ log_exception_with_timestamp(e, "UnicodeDecodeError", "Please check for"
+ "columns containing binary data to find the possible source of the
error")
except QueryStateException as e:
# an exception occurred while executing the query
if self.last_query_handle is not None:
@@ -1490,25 +1491,26 @@ class ImpalaShell(cmd.Cmd, object):
# Here we use 'utf-8' to explicitly convert 'msg' to str if it's in
unicode type.
if sys.version_info.major == 2 and isinstance(msg, unicode):
msg = msg.encode('utf-8')
- print(msg, file=sys.stderr)
+ log_exception_with_timestamp(msg)
except DisconnectedException as e:
# the client has lost the connection
- print(e, file=sys.stderr)
+ log_exception_with_timestamp(e)
self.imp_client.connected = False
self.prompt = ImpalaShell.DISCONNECTED_PROMPT
except socket.error as e:
# if the socket was interrupted, reconnect the connection with the client
if e.errno == errno.EINTR:
- print(ImpalaShell.CANCELLATION_MESSAGE)
+ log_timestamp("Warning", ImpalaShell.CANCELLATION_MESSAGE)
self._reconnect_cancellation()
else:
- print("%s %s: %s" % (self.SOCKET_ERROR_MESSAGE, e.errno, e),
file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception", self.SOCKET_ERROR_MESSAGE
+ + str(e.errno))
self.prompt = self.DISCONNECTED_PROMPT
self.imp_client.connected = False
except Exception as e:
# if the exception is unknown, there was possibly an issue with the
connection
# set the shell as disconnected
- print('Unknown Exception : %s' % (e,), file=sys.stderr)
+ log_exception_with_timestamp(e, "Exception", "Unknown Exception")
# Print the stack trace for the exception.
traceback.print_exc()
self.close_connection()
diff --git a/tests/custom_cluster/test_hs2_fault_injection.py
b/tests/custom_cluster/test_hs2_fault_injection.py
index 7f326a9b9..1d393001d 100644
--- a/tests/custom_cluster/test_hs2_fault_injection.py
+++ b/tests/custom_cluster/test_hs2_fault_injection.py
@@ -27,6 +27,19 @@ from tests.common.impala_test_suite import
IMPALAD_HS2_HTTP_HOST_PORT
from tests.common.custom_cluster_test_suite import CustomClusterTestSuite
from time import sleep
+"""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
+
class FaultInjectingHttpClient(ImpalaHttpClient, object):
"""Class for injecting faults in the ImpalaHttpClient. Faults are injected
by using the
@@ -132,35 +145,34 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
def __expect_msg_retry(self, impala_rpc_name):
"""Returns expected log message for rpcs which can be retried"""
- return ("Caught exception HTTP code 502: Injected Fault, "
- "type=<class 'shell.shell_exceptions.HttpError'> in {0}. "
- "Num remaining tries: 3".format(impala_rpc_name))
+ return ("[Exception] type=<class 'shell.shell_exceptions.HttpError'> in
{0}. "
+ "Num remaining tries: 3 HTTP code 502: Injected
Fault".format(impala_rpc_name))
def __expect_msg_retry_with_extra(self, impala_rpc_name):
"""Returns expected log message for rpcs which can be retried and where
the http
message has a message body"""
- return ("Caught exception HTTP code 503: Injected Fault [EXTRA], "
- "type=<class 'shell.shell_exceptions.HttpError'> in {0}. "
- "Num remaining tries: 3".format(impala_rpc_name))
+ return ("[Exception] type=<class 'shell.shell_exceptions.HttpError'> in
{0}. "
+ "Num remaining tries: 3 HTTP code 503: Injected Fault [EXTRA]"
+ .format(impala_rpc_name))
def __expect_msg_retry_with_retry_after(self, impala_rpc_name):
"""Returns expected log message for rpcs which can be retried and the http
message has a body and a Retry-After header that can be correctly
decoded"""
- return ("Caught exception HTTP code 503: Injected Fault [EXTRA], "
- "type=<class 'shell.shell_exceptions.HttpError'> in {0}. "
- "Num remaining tries: 3, retry after 1 secs".format(impala_rpc_name))
+ return ("[Exception] type=<class 'shell.shell_exceptions.HttpError'> in
{0}. "
+ "Num remaining tries: 3, retry after 1 secs "
+ "HTTP code 503: Injected Fault [EXTRA]".format(impala_rpc_name))
def __expect_msg_retry_with_retry_after_no_extra(self, impala_rpc_name):
"""Returns expected log message for rpcs which can be retried and the http
message has a Retry-After header that can be correctly decoded"""
- return ("Caught exception HTTP code 503: Injected Fault, "
- "type=<class 'shell.shell_exceptions.HttpError'> in {0}. "
- "Num remaining tries: 3, retry after 1 secs".format(impala_rpc_name))
+ return ("[Exception] type=<class 'shell.shell_exceptions.HttpError'> in
{0}. "
+ "Num remaining tries: 3, retry after 1 secs "
+ "HTTP code 503: Injected Fault".format(impala_rpc_name))
def __expect_msg_no_retry(self, impala_rpc_name):
"""Returns expected log message for rpcs which can not be retried"""
- return ("Caught exception HTTP code 502: Injected Fault, "
- "type=<class 'shell.shell_exceptions.HttpError'> in {0}.
".format(impala_rpc_name))
+ return ("[Exception] type=<class 'shell.shell_exceptions.HttpError'> in
{0}. "
+ "HTTP code 502: Injected Fault".format(impala_rpc_name))
@pytest.mark.execute_serially
def test_connect(self, capsys):
@@ -170,8 +182,8 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
self.transport.enable_fault(502, "Injected Fault", 0.20)
self.connect()
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("OpenSession")
- assert output[2] == self.__expect_msg_retry("CloseImpalaOperation")
+ assert output[1][TS_LEN:] == self.__expect_msg_retry("OpenSession")
+ assert output[2][TS_LEN:] ==
self.__expect_msg_retry("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_connect_proxy(self, capsys):
@@ -182,8 +194,9 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
self.transport.enable_fault(503, "Injected Fault", 0.20, 'EXTRA')
self.connect()
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry_with_extra("OpenSession")
- assert output[2] ==
self.__expect_msg_retry_with_extra("CloseImpalaOperation")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_retry_with_extra("OpenSession")
+ assert output[2][TS_LEN:] == self.\
+ __expect_msg_retry_with_extra("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_connect_proxy_no_retry(self, capsys):
@@ -195,8 +208,9 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
{"header1": "value1"})
self.connect()
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry_with_extra("OpenSession")
- assert output[2] ==
self.__expect_msg_retry_with_extra("CloseImpalaOperation")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_retry_with_extra("OpenSession")
+ assert output[2][TS_LEN:] == self.\
+ __expect_msg_retry_with_extra("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_connect_proxy_bad_retry(self, capsys):
@@ -209,8 +223,9 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
"Retry-After": "junk"})
self.connect()
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry_with_extra("OpenSession")
- assert output[2] ==
self.__expect_msg_retry_with_extra("CloseImpalaOperation")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_retry_with_extra("OpenSession")
+ assert output[2][TS_LEN:] == self.\
+ __expect_msg_retry_with_extra("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_connect_proxy_retry(self, capsys):
@@ -222,8 +237,9 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
"Retry-After": "1"})
self.connect()
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry_with_retry_after("OpenSession")
- assert output[2] ==
self.__expect_msg_retry_with_retry_after("CloseImpalaOperation")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_retry_with_retry_after("OpenSession")
+ assert output[2][TS_LEN:] == self.\
+ __expect_msg_retry_with_retry_after("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_connect_proxy_retry_no_body(self, capsys):
@@ -235,8 +251,9 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
"Retry-After": "1"})
self.connect()
output = capsys.readouterr()[1].splitlines()
- assert output[1] ==
self.__expect_msg_retry_with_retry_after_no_extra("OpenSession")
- assert output[2] == self.\
+ assert output[1][TS_LEN:] == self.\
+ __expect_msg_retry_with_retry_after_no_extra("OpenSession")
+ assert output[2][TS_LEN:] == self.\
__expect_msg_retry_with_retry_after_no_extra("CloseImpalaOperation")
@pytest.mark.execute_serially
@@ -248,7 +265,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
self.transport.enable_fault(502, "Injected Fault", 0.50)
self.custom_hs2_http_client.close_connection()
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_no_retry("CloseSession")
+ assert output[1][TS_LEN:] == self.__expect_msg_no_retry("CloseSession")
@pytest.mark.execute_serially
def test_ping(self, capsys):
@@ -263,7 +280,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
page = requests.get('{0}/{1}'.format(webserver_address, 'healthz'))
assert page.status_code == requests.codes.ok
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("PingImpalaHS2Service")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_retry("PingImpalaHS2Service")
@pytest.mark.execute_serially
def test_execute_query(self, capsys):
@@ -278,7 +295,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
assert str(e) == 'HTTP code 502: Injected Fault'
assert query_handle is None
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_no_retry("ExecuteStatement")
+ assert output[1][TS_LEN:] == self.__expect_msg_no_retry("ExecuteStatement")
@pytest.mark.execute_serially
def test_fetch(self, capsys):
@@ -298,7 +315,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
assert num_rows is None
self.close_query(query_handle)
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_no_retry("FetchResults")
+ assert output[1][TS_LEN:] == self.__expect_msg_no_retry("FetchResults")
@pytest.mark.execute_serially
def test_close_dml(self, unique_database, capsys):
@@ -320,7 +337,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
assert exception is not None
assert str(exception) == 'HTTP code 502: Injected Fault'
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_no_retry("CloseImpalaOperation")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_no_retry("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_close_query(self, capsys):
@@ -332,7 +349,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
self.transport.enable_fault(502, "Injected Fault", 0.50)
self.custom_hs2_http_client.close_query(query_handle)
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("CloseImpalaOperation")
+ assert output[1][TS_LEN:] ==
self.__expect_msg_retry("CloseImpalaOperation")
@pytest.mark.execute_serially
def test_cancel_query(self, capsys):
@@ -346,7 +363,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
assert success
self.close_query(query_handle)
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("CancelOperation")
+ assert output[1][TS_LEN:] == self.__expect_msg_retry("CancelOperation")
@pytest.mark.execute_serially
def test_get_query_state(self, capsys):
@@ -360,7 +377,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
assert query_state == self.custom_hs2_http_client.FINISHED_STATE
self.close_query(query_handle)
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("GetOperationStatus")
+ assert output[1][TS_LEN:] == self.__expect_msg_retry("GetOperationStatus")
@pytest.mark.execute_serially
def test_get_runtime_profile_summary(self, capsys):
@@ -377,8 +394,8 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
summary = self.custom_hs2_http_client.get_summary(query_handle)
assert summary is not None
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("GetRuntimeProfile")
- assert output[2] == self.__expect_msg_retry("GetExecSummary")
+ assert output[1][TS_LEN:] == self.__expect_msg_retry("GetRuntimeProfile")
+ assert output[2][TS_LEN:] == self.__expect_msg_retry("GetExecSummary")
@pytest.mark.execute_serially
def test_get_warning_log(self, capsys):
@@ -394,7 +411,7 @@ class TestHS2FaultInjection(CustomClusterTestSuite):
assert warning_log == 'WARNINGS: JOIN hint not recognized: foo'
self.close_query(query_handle)
output = capsys.readouterr()[1].splitlines()
- assert output[1] == self.__expect_msg_retry("GetLog")
+ assert output[1][TS_LEN:] == self.__expect_msg_retry("GetLog")
@pytest.mark.execute_serially
def test_connection_drop(self):
diff --git a/tests/custom_cluster/test_shell_jwt_auth.py
b/tests/custom_cluster/test_shell_jwt_auth.py
index b252edff3..44f4ac7b8 100644
--- a/tests/custom_cluster/test_shell_jwt_auth.py
+++ b/tests/custom_cluster/test_shell_jwt_auth.py
@@ -128,7 +128,7 @@ class TestImpalaShellJWTAuth(CustomClusterTestSuite):
self.assert_impalad_log_contains("ERROR", expected_string,
expected_count=-1)
# Ensure the shell login failed.
- assert "Error connecting: HttpError" in result.stderr
+ assert "HttpError" in result.stderr
assert "HTTP code 401: Unauthorized" in result.stderr
assert "Not connected to Impala, could not execute queries." in
result.stderr
@@ -167,7 +167,7 @@ class TestImpalaShellJWTAuth(CustomClusterTestSuite):
self.assert_impalad_log_contains("ERROR", expected_string,
expected_count=-1)
# Ensure the shell login failed.
- assert "Error connecting: HttpError" in result.stderr
+ assert "HttpError" in result.stderr
assert "HTTP code 401: Unauthorized" in result.stderr
assert "Not connected to Impala, could not execute queries." in
result.stderr
diff --git a/tests/shell/test_shell_commandline.py
b/tests/shell/test_shell_commandline.py
index a23cbdf68..0da89ed42 100644
--- a/tests/shell/test_shell_commandline.py
+++ b/tests/shell/test_shell_commandline.py
@@ -54,6 +54,19 @@ QUERY_FILE_PATH = os.path.join(os.environ['IMPALA_HOME'],
'tests', 'shell')
RUSSIAN_CHARS = (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):
"""
@@ -1407,16 +1420,17 @@ class TestImpalaShell(ImpalaTestSuite):
# assign requested address" for both Python 2 and Python 3.
# Tolerate all three of these variants.
error_template = (
- "Caught exception [Errno {0}] {1}, type=<class '{2}'> in OpenSession. "
- "Num remaining tries: 3")
+ "[Exception] type=<class '{0}'> in OpenSession. Num remaining tries: 3 "
+ "[Errno {1}] {2}")
expected_err_py2 = \
- error_template.format(115, "Operation now in progress", "socket.error")
+ error_template.format("socket.error", 115, "Operation now in progress")
expected_err_py3 = \
- error_template.format(115, "Operation now in progress",
"BlockingIOError")
+ error_template.format("BlockingIOError", 115, "Operation now in
progress")
expected_err_docker = \
- error_template.format(99, "Cannot assign requested address", "OSError")
+ error_template.format("OSError", 99, "Cannot assign requested address")
actual_err = result.stderr.splitlines()[0]
- assert actual_err in [expected_err_py2, expected_err_py3,
expected_err_docker]
+ assert actual_err[TS_LEN:] in [expected_err_py2, expected_err_py3,
+ expected_err_docker]
# Test http_socket_timeout_s=-1, expect errors
result = run_impala_shell_cmd(vector, args +
['--http_socket_timeout_s=-1'],
diff --git a/tests/shell/util.py b/tests/shell/util.py
index 1779309c5..08f2353d6 100755
--- a/tests/shell/util.py
+++ b/tests/shell/util.py
@@ -404,5 +404,5 @@ def get_impala_shell_executable(vector):
def stderr_get_first_error_msg(stderr):
"""Seek to the begining of the first error message in stderr of
impala-shell."""
- PROMPT = "\nERROR: "
+ PROMPT = "ERROR: "
return stderr[(stderr.index(PROMPT) + len(PROMPT)):]