[barbican] Retry on tls connection timeout
The GET request could get lost or stuck on the way to
loadbalancer->backend, so let's retry it.
Closes-Bug: PRODX-16055
Change-Id: Iab75cc251daba755dd248cda6b7b8c534283fc5d
(cherry picked from commit 01954d37942b7220243e914cecded8ac16d1a1c0)
(cherry picked from commit aa656cabf94e8a7679c06ad2e365b4e18caebf4d)
(cherry picked from commit 43441afb3719ae03d60e7f653009fb336c427254)
diff --git a/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py b/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py
index 85fcef0..14468c8 100644
--- a/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py
+++ b/octavia_tempest_plugin/tests/barbican_scenario/v2/test_tls_barbican.py
@@ -22,6 +22,7 @@
import httpx
from OpenSSL.crypto import X509
from OpenSSL import SSL
+import tenacity
from oslo_log import log as logging
from oslo_utils import uuidutils
@@ -350,9 +351,12 @@
# Make sure the certificate is the one we generated
self.assertEqual(expected_cn, received_cn, message=msg)
else:
- LOG.error('Certificate with CN: %s failed validation with '
- 'OpenSSL verify errno %s',
- x509.get_subject().commonName, errno)
+ LOG.error(
+ "Certificate with CN: %s failed validation with"
+ " OpenSSL verify errno %s",
+ x509.get_subject().commonName,
+ errno
+ )
return False
return True
@@ -488,9 +492,12 @@
# Make sure the certificate is the one we generated
self.assertEqual(expected_cn, received_cn, message=msg)
else:
- LOG.error('Certificate with CN: %s failed validation with '
- 'OpenSSL verify errno %s',
- x509.get_subject().commonName, errno)
+ LOG.error(
+ "Certificate with CN: %s failed validation with"
+ " OpenSSL verify errno %s",
+ x509.get_subject().commonName,
+ errno
+ )
return False
return True
@@ -661,9 +668,12 @@
# Make sure the certificate is the one we generated
self.assertEqual(expected_cn, received_cn, message=msg)
else:
- LOG.error('Certificate with CN: %s failed validation with '
- 'OpenSSL verify errno %s',
- x509.get_subject().commonName, errno)
+ LOG.error(
+ "Certificate with CN: %s failed validation with"
+ " OpenSSL verify errno %s",
+ x509.get_subject().commonName,
+ errno
+ )
return False
return True
@@ -1245,8 +1255,18 @@
self.assertEqual(expected_proto, selected_proto)
- def _test_http_versions_tls_traffic(self, http_version, alpn_protos,
- hsts: bool = False):
+ def _test_http_versions_tls_traffic(self, http_version, alpn_protos):
+ @tenacity.retry(
+ retry=tenacity.retry_if_exception_type(httpx.ConnectTimeout),
+ wait=tenacity.wait_incrementing(
+ const.RETRY_INITIAL_DELAY, const.RETRY_BACKOFF, const.RETRY_MAX
+ ),
+ stop=tenacity.stop_after_attempt(const.RETRY_ATTEMPTS),
+ reraise=True,
+ )
+ def _get(client, url):
+ return client.get(url)
+
if not self.mem_listener_client.is_version_supported(
self.api_version, '2.20'):
raise self.skipException('ALPN protocols are only available on '
@@ -1261,12 +1281,6 @@
const.DEFAULT_TLS_CONTAINER_REF: self.server_secret_ref,
const.ALPN_PROTOCOLS: alpn_protos,
}
- if self.mem_listener_client.is_version_supported(
- self.api_version, '2.27'):
- listener_kwargs[const.HSTS_MAX_AGE] = 100 if hsts else None
- listener_kwargs[const.HSTS_INCLUDE_SUBDOMAINS] = hsts
- listener_kwargs[const.HSTS_PRELOAD] = hsts
-
listener = self.mem_listener_client.create_listener(**listener_kwargs)
self.listener_id = listener[const.ID]
self.addCleanup(
@@ -1279,26 +1293,25 @@
const.ACTIVE,
CONF.load_balancer.build_interval,
CONF.load_balancer.build_timeout)
+ # NOTE(pas-ha): depending on what other tempest plugins are installed
+ # the eventlet might've been imported by that time, and, since
+ # dnspython 2.2.0, importing eventlet or any part of it effectively
+ # instantiates a dummy httpx.Client instance, thus pinning the ssl
+ # implementation in httpx to the eventlet's one.
+ # This leads to error in the Client() call below, as the ssl lib in
+ # this module is different from ssl lib in httpx._config,
+ # which fails isinstance check for ssl.SSLContext.
+ # Use the ssl module that is actually used by httpx to instantiate
+ # the SSL context to be used with httpx.
+ ssl = httpx._config.ssl
context = ssl.create_default_context(cadata=self.ca_cert.public_bytes(
serialization.Encoding.PEM).decode('utf-8'))
context.check_hostname = False
url = 'https://%s:%s' % (self.lb_vip_address, 443)
- client_kwargs = {
- 'verify': context
- }
- if http_version == 'HTTP/2':
- client_kwargs['http1'] = False
- client_kwargs['http2'] = True
- client = httpx.Client(**client_kwargs)
- r = client.get(url)
+ client = httpx.Client(http2=(http_version == 'HTTP/2'), verify=context)
+ r = _get(client, url)
self.assertEqual(http_version, r.http_version)
- if hsts:
- self.assertIn('strict-transport-security', r.headers)
- self.assertEqual('max-age=100; includeSubDomains; preload;',
- r.headers['strict-transport-security'])
- else:
- self.assertNotIn('strict-transport-security', r.headers)
@decorators.idempotent_id('9965828d-24af-4fa0-91ae-21c6bc47ab4c')
def test_http_2_tls_traffic(self):
@@ -1309,15 +1322,6 @@
self._test_http_versions_tls_traffic(
'HTTP/1.1', ['http/1.1', 'http/1.0'])
- @decorators.idempotent_id('7436c6b7-44be-4544-a40b-31d2b7b2ad0b')
- def test_http_1_1_tls_hsts_traffic(self):
- if not self.mem_listener_client.is_version_supported(
- self.api_version, '2.27'):
- raise self.skipException('HSTS is only available on '
- 'Octavia API version 2.27 or newer.')
- self._test_http_versions_tls_traffic(
- 'HTTP/1.1', ['http/1.1', 'http/1.0'], hsts=True)
-
@decorators.idempotent_id('ee0faf71-d11e-4323-8673-e5e15779749b')
def test_pool_reencryption(self):
if not self.mem_listener_client.is_version_supported(