Skip to content

Commit dc6c309

Browse files
committed
utilities: Replace telnetlib with socket.
telnetlib is getting removed from standard python library in python 3.13[0]. While there are 3rd party replacements, it was used only to check if a port is open. We can use built-in socket library for that. [0] https://docs.python.org/3.13/library/telnetlib.html Signed-off-by: Martin Kalcok <[email protected]>
1 parent fb477bb commit dc6c309

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

unit_tests/utilities/test_zaza_utilities_generic.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,20 +415,31 @@ def test_get_ubuntu_release(self):
415415
generic_utils.get_ubuntu_release(bad_name)
416416

417417
def test_is_port_open(self):
418+
mock_sock_instance = mock.MagicMock()
418419
self.patch(
419-
'zaza.openstack.utilities.generic.telnetlib.Telnet',
420-
new_callable=mock.MagicMock(),
421-
name='telnet'
420+
'zaza.openstack.utilities.generic.socket.socket',
421+
return_value=mock_sock_instance,
422+
name='mock_socket'
422423
)
423424

424425
_port = "80"
425426
_addr = "10.5.254.20"
426427

428+
# Test successful connection
427429
self.assertTrue(generic_utils.is_port_open(_port, _addr))
428-
self.telnet.assert_called_with(_addr, _port)
430+
self.mock_socket.assert_called_with(
431+
generic_utils.socket.AF_INET,
432+
generic_utils.socket.SOCK_STREAM
433+
)
434+
mock_sock_instance.settimeout.assert_called_with(5)
435+
mock_sock_instance.connect.assert_called_with((_addr, 80))
436+
mock_sock_instance.close.assert_called_once()
429437

430-
self.telnet.side_effect = generic_utils.socket.error
438+
# Test failed connection - socket should still be closed
439+
mock_sock_instance.reset_mock()
440+
mock_sock_instance.connect.side_effect = generic_utils.socket.error
431441
self.assertFalse(generic_utils.is_port_open(_port, _addr))
442+
mock_sock_instance.close.assert_called_once()
432443

433444
def test_get_unit_hostnames(self):
434445
self.patch(

zaza/openstack/utilities/generic.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import os
2020
import socket
2121
import subprocess
22-
import telnetlib
2322
import tempfile
2423
import yaml
2524

@@ -583,20 +582,24 @@ def get_file_contents(unit, f):
583582
"cat {}".format(f))['Stdout']
584583

585584

586-
def is_port_open(port, address):
585+
def is_port_open(port, address, timeout=5):
587586
"""Determine if TCP port is accessible.
588587
589-
Connect to the MySQL port on the VIP.
588+
Connect to a TCP port to check if it is accessible.
590589
591590
:param port: Port number
592-
:type port: str
593-
:param address: IP address
594-
:type port: str
591+
:type port: str or int
592+
:param address: IP address or hostname
593+
:type address: str
594+
:param timeout: Connection timeout in seconds
595+
:type timeout: int
595596
:returns: True if port is reachable
596597
:rtype: boolean
597598
"""
599+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
600+
sock.settimeout(timeout)
598601
try:
599-
telnetlib.Telnet(address, port)
602+
sock.connect((address, int(port)))
600603
return True
601604
except socket.error as e:
602605
if e.errno == 113:
@@ -606,6 +609,8 @@ def is_port_open(port, address):
606609
logging.error("connection refused connecting"
607610
" to {}:{}".format(address, port))
608611
return False
612+
finally:
613+
sock.close()
609614

610615

611616
def port_knock_units(units, port=22, expect_success=True):

0 commit comments

Comments
 (0)