blob: 8097ac709fa62cd7a9456f1dc333ee20a8338b2a [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import, division, print_function
import os
import ssl
import sys
import time
import pytest
# This import is the actual ImpalaShell class from impala_shell.py.
# We rename it to ImpalaShellClass here because we later import another
# class called ImpalaShell from tests/shell/util.py, and we don't want
# to mask it.
from impala_shell.impala_shell import ImpalaShell as ImpalaShellClass
from tests.common.custom_cluster_test_suite import CustomClusterTestSuite
from tests.common.environ import IS_REDHAT_DERIVATIVE
from tests.common.test_dimensions import create_client_protocol_dimension
from tests.common.test_vector import ImpalaTestVector
from tests.shell.util import ImpalaShell
REQUIRED_MIN_OPENSSL_VERSION = 0x10001000
# Python supports TLSv1.2 from 2.7.9 officially but on Red Hat/CentOS Python2.7.5
# with newer python-libs (eg python-libs-2.7.5-77) supports TLSv1.2 already
if IS_REDHAT_DERIVATIVE:
REQUIRED_MIN_PYTHON_VERSION_FOR_TLSV12 = (2, 7, 5)
else:
REQUIRED_MIN_PYTHON_VERSION_FOR_TLSV12 = (2, 7, 9)
_openssl_version_number = getattr(ssl, "OPENSSL_VERSION_NUMBER", None)
if _openssl_version_number is None:
SKIP_SSL_MSG = "Legacy OpenSSL module detected"
elif _openssl_version_number < REQUIRED_MIN_OPENSSL_VERSION:
SKIP_SSL_MSG = "Only have OpenSSL version %X, but test requires %X" % (
ssl.OPENSSL_VERSION_NUMBER, REQUIRED_MIN_OPENSSL_VERSION)
else:
SKIP_SSL_MSG = None
CERT_DIR = "%s/be/src/testutil" % os.environ['IMPALA_HOME']
SSL_ARGS = ("--ssl_client_ca_certificate=%s/server-cert.pem "
"--ssl_server_certificate=%s/server-cert.pem "
"--ssl_private_key=%s/server-key.pem "
"--hostname=localhost " # Required to match hostname in certificate
% (CERT_DIR, CERT_DIR, CERT_DIR))
# IMPALA-12114 was an issue that occurred when the number of idle polls exceeded a limit
# and lead to disconnection. This uses a very short poll period to make these tests
# do more polls and verify the fix for this issue.
IDLE_ARGS = " --idle_client_poll_period_s=1 -v=2"
class TestThriftSocket(CustomClusterTestSuite):
""" Check if thrift timeout errors are detected properly """
@classmethod
def setup_class(cls):
if sys.version_info < REQUIRED_MIN_PYTHON_VERSION_FOR_TLSV12:
pytest.skip("Python version does not support tls 1.2")
super(TestThriftSocket, cls).setup_class()
@pytest.mark.execute_serially
@CustomClusterTestSuite.with_args(
impalad_args=IDLE_ARGS, cluster_size=1, disable_log_buffering=True)
def test_peek_timeout_no_ssl(self):
# Iterate over test vector within test function to avoid restarting cluster.
for protocol_dim in create_client_protocol_dimension():
for vector in [ImpalaTestVector([protocol_dim])]:
shell_args = ["-Q", "idle_session_timeout=1800"]
# This uses a longer idle time to verify IMPALA-12114, see comment above.
self._run_idle_shell(vector, shell_args, 12)
self.assert_impalad_log_contains('INFO',
r'Socket read or peek timeout encountered.*THRIFT_EAGAIN \(timed out\)',
expected_count=-1)
@pytest.mark.execute_serially
@CustomClusterTestSuite.with_args(statestored_args=SSL_ARGS,
catalogd_args=SSL_ARGS,
impalad_args=(SSL_ARGS + IDLE_ARGS),
cluster_size=1,
disable_log_buffering=True)
def test_peek_timeout_ssl(self):
# Iterate over test vector within test function to avoid restarting cluster.
for protocol_dim in create_client_protocol_dimension():
for vector in [ImpalaTestVector([protocol_dim])]:
shell_args = ["-Q", "idle_session_timeout=1800", "--ssl"]
# This uses a longer idle time to verify IMPALA-12114, see comment above.
self._run_idle_shell(vector, shell_args, 12)
self.assert_impalad_log_contains('INFO',
r'Socket read or peek timeout encountered.*THRIFT_POLL \(timed out\)',
expected_count=-1)
def _run_idle_shell(self, vector, args, idle_time):
p = ImpalaShell(vector, args)
p.send_cmd("USE functional")
# Running different statements before and after idle allows for more
# precise asserts that can distinguish output from before vs after.
p.send_cmd("SHOW DATABASES")
time.sleep(idle_time)
p.send_cmd("SHOW TABLES")
result = p.get_result()
# Output from before the idle period
assert "functional_parquet" in result.stdout, result.stdout
# Output from after the idle period
assert "alltypesaggmultifilesnopart" in result.stdout, result.stdout
# Impala shell reconnects automatically, so we need to be sure that
# it didn't lose the connection.
assert ImpalaShellClass.CONNECTION_LOST_MESSAGE not in result.stderr, result.stderr