vtc 0.1.14

A SMPTE timeoce library for Rust
Documentation
import re
import sys
import pathlib
import subprocess
from configparser import ConfigParser

CONFIG_PATH: pathlib.Path = pathlib.Path(__file__).parent.parent.parent / "setup.cfg"

STD_OUT_LOG = pathlib.Path("./zdevelop/tests/_reports/test_stdout.txt")
STD_ERR_LOG = pathlib.Path("./zdevelop/tests/_reports/test_stderr.txt")
FULL_LOG = pathlib.Path("./zdevelop/tests/_reports/test_full.txt")
COVERAGE_LOG = pathlib.Path("./zdevelop/tests/_reports/coverage.out")
TEST_REPORT = pathlib.Path("./zdevelop/tests/_reports/test_results.html")
COVERAGE_REPORT = pathlib.Path("./zdevelop/tests/_reports/coverage/index.html")

COVERAGE_REGEX = re.compile(r"total:\s+\(statements\)\s+(\d+\.\d)%")


def load_cfg() -> ConfigParser:
    """
    loads library config file
    :return: loaded `ConfigParser` object
    """
    config = ConfigParser()
    config.read(CONFIG_PATH)
    return config


def run_test() -> None:
    config = load_cfg()
    coverage_required = config.getfloat("testing", "coverage_required") * 100
    test_package = config.get("testing", "test_package", fallback="./...")
    exclude_string = config.get("testing", "exclude", fallback="")
    exclude_list = [e for e in exclude_string.split("\n") if e]
    race_detection = config.getboolean("testing", "race_detection", fallback=True)
    multi_process = config.getboolean("testing", "multi_process", fallback=True)
    timeout = config.getint("testing", "timeout", fallback=60)

    # Get the list of packages we want to cover
    list_process = subprocess.Popen(
        ["go", "list", test_package], stdout=subprocess.PIPE, universal_newlines=True
    )

    grep_command = ["grep", "-v"]
    for this_exclude in exclude_list:
        grep_command += ["-e", this_exclude]

    sys.stdout.write(f"grep: {' '.join(grep_command)}\n")
    grep_process = subprocess.Popen(
        grep_command,
        stdin=list_process.stdout,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
    )

    assert list_process.stdout is not None
    list_process.stdout.close()
    packages_str, _ = grep_process.communicate()
    packages = packages_str.split("\n")
    if not packages:
        packages = ["./..."]

    sys.stdout.write(f"COVERAGE REQUIRED: {coverage_required}\n")

    # Set up the command
    command = [
        "go",
        "test",
        "-v",
        "-failfast",
        f"-timeout={timeout}s",
    ]

    # Add the race flag if we are using it.
    if race_detection:
        command.append("-race")

    # Add th flag to restrict the number of simultaneous tests to 1.
    if not multi_process:
        command.extend(("-p", "1"))

    # Finish building the command.
    command.extend(
        [
            "-covermode=atomic",
            f"-coverprofile={COVERAGE_LOG}",
            f"-coverpkg={','.join(packages)}",
        ]
    )

    command = command + ["./..."]

    sys.stdout.write(f"command: {' '.join(command)}\n")

    proc = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
    )
    stdout, stderr = proc.communicate()

    sys.stdout.write(stdout)
    sys.stderr.write(stderr)

    STD_OUT_LOG.write_text(stdout)
    STD_ERR_LOG.write_text(stderr)
    FULL_LOG.write_text(stdout + stderr)

    if proc.returncode != 0:
        sys.exit(proc.returncode)

    # Use the cov command to generate the total coverage
    command = [
        "go",
        "tool",
        "cover",
        "--func",
        str(COVERAGE_LOG),
    ]

    proc = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
    )
    stdout, stderr = proc.communicate()

    sys.stdout.write(stdout)
    sys.stderr.write(stderr)

    with STD_OUT_LOG.open("a") as f:
        f.write(stdout)
    with STD_ERR_LOG.open("a") as f:
        f.write(stderr)

    if proc.returncode != 0:
        sys.exit(proc.returncode)

    # Get the last coverage tally in the result
    coverage_str = [x for x in COVERAGE_REGEX.finditer(stdout)][-1].group(1)
    coverage = float(coverage_str)

    if coverage < coverage_required:
        sys.stderr.write(
            f"Coverage {coverage} is less than required {coverage_required}\n"
        )
        sys.exit(1)
    else:
        sys.stderr.write(
            f"Coverage {coverage}% passes requirement of {coverage_required}%\n"
        )


if __name__ == "__main__":
    run_test()