Skip to content

Commit 34cc7d1

Browse files
demonolockvsheparddmitry-lipetsk
authored
Remove usage of not standard nc in remote_ops.py is_port_free (#284)
* Remove usage of not standard nc in remote_ops.py is_port_free We will check the content of /proc/net/tcp instead usage of 'nc' utility. Co-authored-by: vshepard <[email protected]> Co-authored-by: d.kovalenko <[email protected]>
1 parent 5ffe75f commit 34cc7d1

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

testgres/operations/local_ops.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,8 @@ def get_process_children(self, pid):
583583

584584
def is_port_free(self, number: int) -> bool:
585585
assert type(number) == int # noqa: E721
586+
assert number >= 0
587+
assert number <= 65535 # OK?
586588

587589
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
588590
try:

testgres/operations/remote_ops.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import logging
1111
import typing
1212
import copy
13+
import re
1314

1415
from ..exceptions import ExecUtilException
1516
from ..exceptions import InvalidOperationException
@@ -680,23 +681,45 @@ def get_process_children(self, pid):
680681

681682
def is_port_free(self, number: int) -> bool:
682683
assert type(number) == int # noqa: E721
684+
assert number >= 0
685+
assert number <= 65535 # OK?
683686

684-
cmd = ["nc", "-w", "5", "-z", "-v", "localhost", str(number)]
687+
# grep -q returns 0 if a listening socket on that port is found
688+
port_hex = format(number, '04X')
685689

686-
exit_status, output, error = self.exec_command(cmd=cmd, encoding=get_default_encoding(), ignore_errors=True, verbose=True)
690+
# sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt ...
691+
# 137: 0A01A8C0:EC08 1DA2A959:01BB 01 00000000:00000000 02:00000000 00000000 ...
692+
C_REGEXP = r"^\s*[0-9]+:\s*[0-9a-fA-F]{8}:" + re.escape(port_hex) + r"\s+[0-9a-fA-F]{8}:[0-9a-fA-F]{4}\s+"
687693

688-
assert type(output) == str # noqa: E721
689-
assert type(error) == str # noqa: E721
694+
# Search /proc/net/tcp for any entry with this port
695+
# NOTE: grep requires quote string with regular expression
696+
# TODO: added a support for tcp/ip v6
697+
grep_cmd_s = "grep -q -E \"" + C_REGEXP + "\" /proc/net/tcp"
698+
699+
cmd = [
700+
"/bin/bash",
701+
"-c",
702+
grep_cmd_s,
703+
]
704+
705+
exit_status, output, error = self.exec_command(
706+
cmd=cmd,
707+
encoding=get_default_encoding(),
708+
ignore_errors=True,
709+
verbose=True
710+
)
690711

712+
# grep exit 0 -> port is busy
691713
if exit_status == 0:
692-
return __class__._is_port_free__process_0(error)
714+
return False
693715

716+
# grep exit 1 -> port is free
694717
if exit_status == 1:
695-
return __class__._is_port_free__process_1(error)
696-
697-
errMsg = "nc returns an unknown result code: {0}".format(exit_status)
718+
return True
698719

699-
RaiseError.CommandExecutionError(
720+
# any other code is an unexpected error
721+
errMsg = f"grep returned unexpected exit code: {exit_status}"
722+
raise RaiseError.CommandExecutionError(
700723
cmd=cmd,
701724
exit_code=exit_status,
702725
message=errMsg,
@@ -746,12 +769,7 @@ def _is_port_free__process_0(error: str) -> bool:
746769
@staticmethod
747770
def _is_port_free__process_1(error: str) -> bool:
748771
assert type(error) == str # noqa: E721
749-
#
750-
# Example of error text:
751-
# "nc: connect to localhost (127.0.0.1) port 1024 (tcp) failed: Connection refused\n"
752-
#
753772
# May be here is needed to check error message?
754-
#
755773
return True
756774

757775
@staticmethod

0 commit comments

Comments
 (0)