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:])