github.com/crowdsecurity/crowdsec@v1.6.1/test/bin/wait-for-port (about)

     1  #!/usr/bin/env python3
     2  
     3  import argparse
     4  import os
     5  import socket
     6  import sys
     7  import time
     8  
     9  initial_interval = 0.02
    10  max_interval = 0.5
    11  
    12  
    13  def is_fd_open(fd):
    14      try:
    15          os.fstat(fd)
    16          return True
    17      except OSError:
    18          return False
    19  
    20  
    21  # write to file descriptor 3 if it is open (during bats tests), otherwise stderr
    22  def write_error(ex):
    23      fd = 2
    24      if is_fd_open(3):
    25          fd = 3
    26      os.write(fd, str(ex).encode())
    27  
    28  
    29  def wait(host, port, timeout):
    30      t0 = time.perf_counter()
    31      current_interval = initial_interval
    32      while True:
    33          try:
    34              with socket.create_connection((host, port), timeout=timeout):
    35                  break
    36          except OSError as ex:
    37              if time.perf_counter() - t0 >= timeout:
    38                  raise TimeoutError(f'Timeout waiting for {host}:{port} after {timeout}s') from ex
    39              time.sleep(current_interval)
    40              current_interval = min(current_interval * 1.5, max_interval)
    41  
    42  
    43  def main(argv):
    44      parser = argparse.ArgumentParser(description="Check if a port is open.")
    45      parser.add_argument("port", type=int, help="Port number to check")
    46      parser.add_argument("--host", type=str, default="localhost", help="Host to check")
    47      parser.add_argument("-t", "--timeout", type=float, default=10.0, help="Timeout duration in seconds")
    48      parser.add_argument("-q", "--quiet", action="store_true", help="Enable quiet mode")
    49      args = parser.parse_args(argv)
    50  
    51      try:
    52          wait(args.host, args.port, args.timeout)
    53      except TimeoutError as ex:
    54          if not args.quiet:
    55              write_error(ex)
    56          sys.exit(1)
    57      else:
    58          sys.exit(0)
    59  
    60      sys.exit(1)
    61  
    62  
    63  if __name__ == "__main__":
    64      main(sys.argv[1:])