Run the h2ws test client in various scenarios with given input and timings. :param env: the test environment :param path: the path on the Apache server to CONNECt to :param authority: the host:port to use as :param do_input: a Callable for sending input to h2ws :param in
(env: H2TestEnv, path, authority=None, do_input=None, inbytes=None,
send_close=True, timeout=5, scenario='ws-stdin',
wait_close: float = 0.0)
| 24 | |
| 25 | |
| 26 | def ws_run(env: H2TestEnv, path, authority=None, do_input=None, inbytes=None, |
| 27 | send_close=True, timeout=5, scenario='ws-stdin', |
| 28 | wait_close: float = 0.0) -> Tuple[ExecResult, List[str], List[WsFrame]]: |
| 29 | """ Run the h2ws test client in various scenarios with given input and |
| 30 | timings. |
| 31 | :param env: the test environment |
| 32 | :param path: the path on the Apache server to CONNECt to |
| 33 | :param authority: the host:port to use as |
| 34 | :param do_input: a Callable for sending input to h2ws |
| 35 | :param inbytes: fixed bytes to send to h2ws, unless do_input is given |
| 36 | :param send_close: send a CLOSE WebSockets frame at the end |
| 37 | :param timeout: timeout for waiting on h2ws to finish |
| 38 | :param scenario: name of scenario h2ws should run in |
| 39 | :param wait_close: time to wait before closing input |
| 40 | :return: ExecResult with exit_code/stdout/stderr of run |
| 41 | """ |
| 42 | h2ws = os.path.join(env.clients_dir, 'h2ws') |
| 43 | if not os.path.exists(h2ws): |
| 44 | pytest.fail(f'test client not build: {h2ws}') |
| 45 | if authority is None: |
| 46 | authority = f'cgi.{env.http_tld}:{env.http_port}' |
| 47 | args = [ |
| 48 | h2ws, '-vv', '-c', f'localhost:{env.http_port}', |
| 49 | f'ws://{authority}{path}', |
| 50 | scenario |
| 51 | ] |
| 52 | # we write all output to files, because we manipulate input timings |
| 53 | # and would run in deadlock situations with h2ws blocking operations |
| 54 | # because its output is not consumed |
| 55 | start = datetime.now() |
| 56 | with open(f'{env.gen_dir}/h2ws.stdout', 'w') as fdout: |
| 57 | with open(f'{env.gen_dir}/h2ws.stderr', 'w') as fderr: |
| 58 | proc = subprocess.Popen(args=args, stdin=subprocess.PIPE, |
| 59 | stdout=fdout, stderr=fderr) |
| 60 | if do_input is not None: |
| 61 | do_input(proc) |
| 62 | elif inbytes is not None: |
| 63 | proc.stdin.write(inbytes) |
| 64 | proc.stdin.flush() |
| 65 | |
| 66 | if wait_close > 0: |
| 67 | time.sleep(wait_close) |
| 68 | try: |
| 69 | inbytes = WsFrame.client_close(code=1000).to_network() if send_close else None |
| 70 | proc.communicate(input=inbytes, timeout=timeout) |
| 71 | except subprocess.TimeoutExpired: |
| 72 | log.error(f'ws_run: timeout expired') |
| 73 | proc.kill() |
| 74 | proc.communicate(timeout=timeout) |
| 75 | end = datetime.now() |
| 76 | lines = open(f'{env.gen_dir}/h2ws.stdout').read().splitlines() |
| 77 | infos = [line for line in lines if re.match(r'^\[\d+] ', line)] |
| 78 | hex_content = ' '.join([line for line in lines if not re.match(r'^\[\d+] ', line)]) |
| 79 | if len(infos) > 0 and infos[0] == '[1] :status: 200': |
| 80 | frames = WsFrameReader.parse(bytearray.fromhex(hex_content)) |
| 81 | else: |
| 82 | frames = bytearray.fromhex(hex_content) |
| 83 | return ExecResult(args=args, exit_code=proc.returncode, |
no test coverage detected