This is an automated email from the ASF dual-hosted git repository.
bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new e069475210 Fix autest compatibility with Fedora 43 / Python 3.14
(#12857)
e069475210 is described below
commit e0694752109acfde70eb09c499e3d8db64642ae3
Author: Bryan Call <[email protected]>
AuthorDate: Tue Feb 10 15:09:34 2026 -0800
Fix autest compatibility with Fedora 43 / Python 3.14 (#12857)
Fix autest compatibility with Python 3.14, OpenSSL 3.x, and
Fedora 43 crypto-policies. Updates deprecated Python APIs, adds
socket timeouts, skips legacy TLS tests when TLSv1.0/1.1 are
disabled by system policy, and fixes a timing flake.
---
tests/gold_tests/autest-site/conditions.test.ext | 53 ++++++++++++++++++++++
tests/gold_tests/autest-site/microserver.test.ext | 25 ++++++----
tests/gold_tests/autest-site/ports.py | 2 +-
.../polite_hook_wait/polite_hook_wait.cc | 3 +-
tests/gold_tests/tls/tls_client_versions.test.py | 1 +
.../tls/tls_client_versions_minmax.test.py | 1 +
6 files changed, 74 insertions(+), 11 deletions(-)
diff --git a/tests/gold_tests/autest-site/conditions.test.ext
b/tests/gold_tests/autest-site/conditions.test.ext
index ed2656a32c..e01fecdb85 100644
--- a/tests/gold_tests/autest-site/conditions.test.ext
+++ b/tests/gold_tests/autest-site/conditions.test.ext
@@ -16,6 +16,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os
import subprocess
import json
import re
@@ -51,6 +52,57 @@ def IsOpenSSL(self):
"SSL library is not OpenSSL")
+def HasLegacyTLSSupport(self):
+ """Check if the system supports legacy TLS protocols (TLSv1.0 and TLSv1.1).
+
+ Modern OpenSSL 3.x installations often disable these protocols entirely,
+ even if the openssl binary still accepts the -tls1 flag and lists TLSv1
ciphers.
+
+ On Fedora/RHEL systems, the crypto-policies framework may disable legacy
+ TLS at runtime even when OpenSSL is compiled with support for it. This
+ causes 'openssl ciphers -v -tls1' to still list TLSv1 ciphers, but actual
+ TLS 1.0 connections will fail with "no protocols available".
+
+ We only probe TLSv1.0 (not TLSv1.1 separately) because crypto-policies
+ always disable both legacy versions together. If TLSv1.0 is unavailable,
+ TLSv1.1 will be too.
+
+ The check connects to localhost on a closed port to avoid any external
+ network dependency. A "connection refused" error means the TLS protocol
+ was available but nothing was listening; "no protocols available" means
+ the crypto-policy blocked TLSv1.0 entirely.
+ """
+
+ def check_tls1_support():
+ try:
+ # Connect to localhost on a port nothing is listening on.
+ # This avoids external network dependency while still detecting
+ # whether the crypto-policy allows TLSv1.0.
+ result = subprocess.run(
+ ['openssl', 's_client', '-tls1', '-connect', '127.0.0.1:1'],
+ capture_output=True,
+ text=True,
+ timeout=5,
+ input='' # Don't wait for interactive input
+ )
+ output = result.stdout + result.stderr
+ # "no protocols available" means TLSv1 is disabled by crypto-policy
+ if 'no protocols available' in output:
+ return False
+ # Connection refused or other errors mean TLSv1 was attempted
+ # (the protocol is available, just no server listening)
+ return True
+ except subprocess.TimeoutExpired:
+ # Timeout on localhost shouldn't happen, but if it does,
+ # assume TLSv1 is not available (safer than false positive)
+ return False
+ except Exception:
+ # If we can't determine, assume TLSv1 is not available (safer)
+ return False
+
+ return self.Condition(check_tls1_support, "System does not support legacy
TLS protocols (TLSv1.0/TLSv1.1)")
+
+
def HasCurlVersion(self, version):
return self.EnsureVersion(["curl", "--version"], min_version=version)
@@ -118,6 +170,7 @@ ExtendCondition(HasOpenSSLVersion)
ExtendCondition(HasProxyVerifierVersion)
ExtendCondition(IsBoringSSL)
ExtendCondition(IsOpenSSL)
+ExtendCondition(HasLegacyTLSSupport)
ExtendCondition(HasATSFeature)
ExtendCondition(HasCurlVersion)
ExtendCondition(HasCurlFeature)
diff --git a/tests/gold_tests/autest-site/microserver.test.ext
b/tests/gold_tests/autest-site/microserver.test.ext
index e15547ff18..70c734f42d 100644
--- a/tests/gold_tests/autest-site/microserver.test.ext
+++ b/tests/gold_tests/autest-site/microserver.test.ext
@@ -17,6 +17,7 @@
# limitations under the License.
import json
+import os
import socket
import ssl
@@ -109,7 +110,7 @@ def addSessionFromFiles(self, session_dir):
# make headers with the key and values provided
def makeHeader(self, requestString, **kwargs):
headerStr = requestString + '\r\n'
- for k, v in kwargs.iteritems():
+ for k, v in kwargs.items():
headerStr += k + ': ' + v + '\r\n'
headerStr = headerStr + '\r\n'
return headerStr
@@ -142,14 +143,20 @@ def uServerUpAndRunning(serverHost, port, isSsl, isIPv6,
request, clientcert='',
sock.sendall(request.encode())
decoded_output = ''
- while True:
- host.WriteDebug("??")
- output = sock.recv(4096) # suggested bufsize from docs.python.org
- host.WriteDebug("!!")
- if len(output) <= 0:
- break
- else:
- decoded_output += output.decode()
+ sock.settimeout(10.0) # 10 second timeout for recv
+ try:
+ while True:
+ host.WriteDebug("??")
+ output = sock.recv(4096) # suggested bufsize from docs.python.org
+ host.WriteDebug("!!")
+ if len(output) <= 0:
+ break
+ else:
+ decoded_output += output.decode('utf-8', errors='replace')
+ except socket.timeout:
+ host.WriteDebug(['uServerUpAndRunning', 'when'], "Socket timeout
waiting for response")
+ sock.close()
+ return False
sock.close()
sock = None
diff --git a/tests/gold_tests/autest-site/ports.py
b/tests/gold_tests/autest-site/ports.py
index fc68367fc1..fb36b4088d 100644
--- a/tests/gold_tests/autest-site/ports.py
+++ b/tests/gold_tests/autest-site/ports.py
@@ -74,7 +74,7 @@ def PortOpen(port: int, address: str = None, listening_ports:
Set[int] = None) -
host.WriteDebug(
'PortOpen', f"Connection to port {port} succeeded, the port is
open, "
"and a future connection cannot use it")
- except socket.error:
+ except OSError:
host.WriteDebug(
'PortOpen', f"socket error for port {port}, port is closed, "
"and therefore a future connection can use it")
diff --git a/tests/gold_tests/pluginTest/polite_hook_wait/polite_hook_wait.cc
b/tests/gold_tests/pluginTest/polite_hook_wait/polite_hook_wait.cc
index 1e071a0dfc..3642bdbac0 100644
--- a/tests/gold_tests/pluginTest/polite_hook_wait/polite_hook_wait.cc
+++ b/tests/gold_tests/pluginTest/polite_hook_wait/polite_hook_wait.cc
@@ -202,8 +202,9 @@ Blocking_action::_thread_func(void *vba)
ba->_cont_mutex_locked.store(true, std::memory_order_release);
// This is a stand-in for some blocking call to validate the HTTP request in
some way.
+ // Use a longer delay to account for slower systems and variable scheduling
latency.
//
- std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
// Pass "validation" for first transaction, fail it for second.
//
diff --git a/tests/gold_tests/tls/tls_client_versions.test.py
b/tests/gold_tests/tls/tls_client_versions.test.py
index fcd53c265e..1f0343d9cd 100644
--- a/tests/gold_tests/tls/tls_client_versions.test.py
+++ b/tests/gold_tests/tls/tls_client_versions.test.py
@@ -24,6 +24,7 @@ Test TLS protocol offering based on SNI
# for special domain foo.com only offer TLSv1 and TLSv1_1
Test.SkipUnless(Condition.HasOpenSSLVersion("1.1.1"))
+Test.SkipUnless(Condition.HasLegacyTLSSupport())
# Define default ATS
ts = Test.MakeATSProcess("ts", enable_tls=True)
diff --git a/tests/gold_tests/tls/tls_client_versions_minmax.test.py
b/tests/gold_tests/tls/tls_client_versions_minmax.test.py
index 2ea7853580..9c63d0700d 100644
--- a/tests/gold_tests/tls/tls_client_versions_minmax.test.py
+++ b/tests/gold_tests/tls/tls_client_versions_minmax.test.py
@@ -24,6 +24,7 @@ Test TLS protocol offering based on SNI
# for special domain foo.com only offer TLSv1 and TLSv1_1
Test.SkipUnless(Condition.HasOpenSSLVersion("1.1.1"))
+Test.SkipUnless(Condition.HasLegacyTLSSupport())
# Define default ATS
ts = Test.MakeATSProcess("ts", enable_tls=True)