############################################################################# # Some helpers to make step functions simpler. import json import logging import os import random import re import shutil import signal import subprocess import time import urllib.parse import yaml # Run a subprocess, capture its output and exit code in context. def _run(ctx, argv): p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate("") ctx["argv"] = argv ctx["stdout"] = stdout.decode("utf-8") ctx["stderr"] = stderr.decode("utf-8") ctx["exit"] = p.returncode # Check that latest call of _run ended with an specific exit code. def _run_exit(ctx, expected): if ctx["exit"] != expected: print("ctx:", ctx.as_dict()) assert_eq(ctx["exit"], expected) # Name of Rust binary, debug-build. def _binary(name): return os.path.abspath(os.path.join(srcdir, "target", "debug", name)) # Write a file with given content. def _write(filename, content): open(filename, "w").write(content) # Construct a URL that points to server running on localhost by # replacing the actual scheme and host with ones that work for test. def _url(ctx, url): port = ctx["config"]["port"] c = urllib.parse.urlparse(url) host = c[1] c = (c[0], "localhost:{}".format(port)) + c[2:] return urllib.parse.urlunparse(c), host ############################################################################# # The actual step functions. # Fail: use this for unimplemented steps. def fixme(*args, **kwargs): assert 0 # Create a file. def create_file(ctx, filename=None, content=None): logging.debug(f"Creating file {filename} with {content}") dirname = os.path.dirname(filename) os.makedirs(dirname) _write(filename, content) # Copy test certificate from source tree, where it's been created previously by # ./check. def copy_test_certificate(ctx, cert=None, key=None): logging.debug(f"Copying test.pem, test.key from srcdir to {cert} and {key}") shutil.copy(os.path.join(srcdir, "test.pem"), cert) shutil.copy(os.path.join(srcdir, "test.key"), key) # Start server using named configuration file. def start_server(ctx, filename=None): logging.debug(f"Starting ewww with config file {filename}") config = get_file(filename).decode("UTF-8") config = yaml.safe_load(config) config["port"] = random.randint(2000, 30000) logging.debug(f"Picked randomly port for ewww: {config['port']}") ctx["config"] = config config = yaml.safe_dump(config) _write(filename, config) start_daemon(ctx, "ewww", [_binary("ewww"), filename]) # Stop previously started server. def stop_server(ctx): logging.debug("Stopping ewww") stop_daemon(ctx, "ewww") # Make an HTTP request. def request(ctx, method=None, url=None): logging.debug(f"Making HTTP request to ewww: {method} {url}") url, host = _url(ctx, url) http_request(ctx, host=host, method=method, url=url)