def prune_files(p4_prune_dir, p4_passes):
    util.check_dir(p4_prune_dir)
    for p4_file in p4_passes:
        sed_cmd = "sed -r "
        sed_cmd += "\':a; s%(.*)/\\*.*\\*/%\\1%; ta; /\\/\\*/ !b; N; ba\' "
        sed_cmd += f"{p4_file} "
        sed_cmd += " | sed -r \'/^\\s*$/d\' "
        sed_cmd += f"> {p4_prune_dir}/{p4_file.name}"
        log.debug("Removing comments and whitespace")
        log.debug("Command: %s", sed_cmd)
        util.exec_process(sed_cmd)
    return p4_prune_dir
예제 #2
0
def compile_p4_prog(p4c_bin, p4_file, p4_dump_dir):
    p4_cmd = f"{p4c_bin} "
    # p4_cmd += f"-vvvv "
    p4_cmd += f"{p4_file} "
    p4_cmd += f"-o  {p4_dump_dir}"
    log.debug("Checking compilation with command %s ", p4_cmd)
    return util.exec_process(p4_cmd)
예제 #3
0
def generate_p4_prog(p4c_bin, p4_file, config):
    arch = config["arch"]
    p4_cmd = f"{p4c_bin} "
    p4_cmd += f"--output {p4_file} "
    p4_cmd += f"--arch {arch} "
    log.debug("Generating random p4 code with command %s ", p4_cmd)
    return util.exec_process(p4_cmd), p4_file
def generate_p4_dump(p4c_bin, p4_file, p4_dmp_dir):
    p4_cmd = f"{p4c_bin} "
    p4_cmd += f"{PASSES} "
    # p4_cmd += f"-o {p4_dmp_dir} "
    p4_cmd += f"--dump {p4_dmp_dir} {p4_file} "
    log.debug("Running dumps with command %s ", p4_cmd)
    return util.exec_process(p4_cmd)
예제 #5
0
def validate_p4(p4_file, target_dir, p4c_bin, log_file):
    p4z3_cmd = "python3 check_p4_whitebox.py "
    p4z3_cmd += f"-i {p4_file} "
    p4z3_cmd += f"-o {target_dir} "
    p4z3_cmd += f"-p {p4c_bin} "
    p4z3_cmd += f"-l {log_file} "
    result = util.exec_process(p4z3_cmd)
    return result.returncode
예제 #6
0
def generate_p4_dump(p4c_bin, p4_file, config):
    p4_cmd = f"{p4c_bin} "
    p4_cmd += f"{p4_file} "
    if config["use_tofino"]:
        p4_cmd += f"1 "
    else:
        p4_cmd += f"0 "
    log.debug("Generating random p4 code with command %s ", p4_cmd)
    return util.exec_process(p4_cmd), p4_file
예제 #7
0
def run_p4_to_py(p4_file, py_file, config, option_str=""):
    cmd = f"{P4Z3_BIN} "
    cmd += f"{p4_file} "
    cmd += f"--output {py_file} "
    cmd += option_str
    if config["use_tofino"]:
        include_dir = TOFINO_DIR.joinpath(f"install/share/p4c/p4include/ ")
        cmd += f"-I {include_dir}"
    log.info("Converting p4 to z3 python with command %s ", cmd)
    return util.exec_process(cmd)
예제 #8
0
def validate_p4_blackbox(p4_file, target_dir, log_file, config):
    p4z3_cmd = "python3 check_p4_blackbox.py "
    p4z3_cmd += f"-i {p4_file} "
    p4z3_cmd += f"-o {target_dir} "
    p4z3_cmd += f"-l {log_file} "
    if config["use_tofino"]:
        p4z3_cmd += f"-t "
    if config["randomize_input"]:
        p4z3_cmd += f"-r "
    result = util.exec_process(p4z3_cmd)
    time.sleep(3)
    return result.returncode
예제 #9
0
def validate_p4_blackbox(p4_file, target_dir, log_file, config):
    p4z3_cmd = "python3 "
    p4z3_cmd += f"{FILE_DIR.joinpath('generate_p4_test.py')} "
    p4z3_cmd += f"-i {p4_file} "
    p4z3_cmd += f"-o {target_dir} "
    p4z3_cmd += f"-l {log_file} "
    p4z3_cmd += f"-a {config['arch']} "
    if config["randomize_input"]:
        p4z3_cmd += "-r "
    result = util.exec_process(p4z3_cmd, silent=True)
    time.sleep(3)
    return result.returncode
예제 #10
0
def validate_p4(p4_file, target_dir, p4c_bin, log_file):
    p4z3_cmd = "python3 "
    p4z3_cmd += f"{FILE_DIR.joinpath('validate_p4_translation.py')} "
    p4z3_cmd += f"-i {p4_file} "
    p4z3_cmd += f"-o {target_dir} "
    p4z3_cmd += f"-p {p4c_bin} "
    p4z3_cmd += f"-l {log_file} "
    # distinguish between well-defined and undefined validation errors
    p4z3_cmd += "-u "
    # also dump info which we can reuse for various purposes
    p4z3_cmd += "-d "
    result = util.exec_process(p4z3_cmd, silent=True)
    return result.returncode
예제 #11
0
def compile_p4_prog(p4c_bin, p4_file, p4_dump_dir):
    p4_cmd = f"{p4c_bin} "
    # p4_cmd += f"-vvvv "
    # the Tofino compiler is not great with warnings
    if p4c_bin != TNA_BIN:
        p4_cmd += "--Wdisable "
    p4_cmd += f"{p4_file} "
    # p4test does not have the -o flag
    if p4c_bin != P4TEST_BIN:
        out_file = p4_file.with_suffix(".out").name
        p4_cmd += f"-o  {p4_dump_dir}/{out_file}"
    log.debug("Checking compilation with command %s ", p4_cmd)
    return util.exec_process(p4_cmd, silent=True)
def diff_files(passes, pass_dir, p4_file):

    p4_name = p4_file.name.stem
    for index, p4_pass in enumerate(passes[1:]):
        pass_before = passes[index - 1]
        pass_after = passes[index]
        diff_dir = f"{pass_dir}/{p4_name}"
        util.check_dir(diff_dir)
        diff_file = f"{diff_dir}/{p4_name}_{p4_pass}.diff"
        diff_cmd = "diff -rupP "
        diff_cmd += "--label=\"before_pass\" --label=\"after_pass\" "
        diff_cmd += f"{pass_before} {pass_after}"
        diff_cmd += f"> {diff_file}"
        log.debug("Creating a diff of the file")
        log.debug("Command: %s", diff_cmd)
        util.exec_process(diff_cmd)
        if os.stat(diff_file).st_size == 0:
            os.remove(diff_file)
        else:
            after_name = f"{diff_dir}/{p4_name}_{p4_pass}{p4_file.suffix}"
            util.copy_file(pass_after, after_name)
            og_name = f"{diff_dir}/{p4_name}_original{p4_file.suffix}"
            util.copy_file(p4_file, og_name)
    return util.EXIT_SUCCESS
def run_p4_to_py(p4_file, py_file):
    cmd = f"{P4Z3_BIN} "
    cmd += f"{p4_file} "
    cmd += f"--output {py_file} "
    return util.exec_process(cmd)
예제 #14
0
def run_tofino_test(out_dir, p4_input, stf_file_name):
    # we need to change the working directory
    # tofino scripts make some assumptions where to dump files
    prog_name = p4_input.stem
    # we need to create a specific test dir in which we can run tests
    test_dir = out_dir.joinpath("test_dir")
    util.check_dir(test_dir)
    util.copy_file(stf_file_name, test_dir)
    template_name = test_dir.joinpath(f"{prog_name}.py")
    # use a test template that runs stf tests
    util.copy_file(f"{FILE_DIR}/tofino_test_template.py", template_name)

    # initialize the target install
    log.info("Building the tofino target...")
    config_cmd = f"{TOFINO_DIR}/pkgsrc/p4-build/configure "
    config_cmd += f"--with-tofino --with-p4c=bf-p4c "
    config_cmd += f"--prefix={TOFINO_DIR}/install "
    config_cmd += f"--bindir={TOFINO_DIR}/install/bin "
    config_cmd += f"P4_NAME={prog_name} "
    config_cmd += f"P4_PATH={p4_input.resolve()} "
    config_cmd += f"P4_VERSION=p4-16 "
    config_cmd += f"P4_ARCHITECTURE=tna "
    result = util.exec_process(config_cmd, cwd=out_dir)
    if result.returncode != util.EXIT_SUCCESS:
        return result, result.stdout, result.stderr
    # create the target
    make_cmd = f"make -C {out_dir} "
    result = util.exec_process(make_cmd)
    if result.returncode != util.EXIT_SUCCESS:
        return result, result.stdout, result.stderr
    # install the target in the tofino folder
    make_cmd = f"make install -C {out_dir} "
    result = util.exec_process(make_cmd)
    if result.returncode != util.EXIT_SUCCESS:
        return result, result.stdout, result.stderr
    procs = []
    test_proc = None
    # start the target in the background
    log.info("Starting the tofino model...")
    os_env = os.environ.copy()
    os_env["SDE"] = f"{TOFINO_DIR}"
    os_env["SDE_INSTALL"] = f"{TOFINO_DIR}/install"

    model_cmd = f"{TOFINO_DIR}/run_tofino_model.sh "
    model_cmd += f"-p {prog_name} "
    proc = util.start_process(model_cmd,
                              preexec_fn=os.setsid,
                              env=os_env,
                              cwd=out_dir)
    procs.append(proc)
    # start the binary for the target in the background
    log.info("Launching switchd...")
    os_env = os.environ.copy()
    os_env["SDE"] = f"{TOFINO_DIR}"
    os_env["SDE_INSTALL"] = f"{TOFINO_DIR}/install"

    switch_cmd = f"{TOFINO_DIR}/run_switchd.sh "
    switch_cmd += f"--arch tofino "
    switch_cmd += f"-p {prog_name} "
    proc = util.start_process(switch_cmd,
                              preexec_fn=os.setsid,
                              env=os_env,
                              cwd=out_dir)
    procs.append(proc)

    # wait for a bit
    time.sleep(2)
    # finally we can run the test
    log.info("Running the actual test...")
    test_cmd = f"{TOFINO_DIR}/run_p4_tests.sh "
    test_cmd += f"-t {test_dir} "
    os_env = os.environ.copy()
    os_env["SDE"] = f"{TOFINO_DIR}"
    os_env["SDE_INSTALL"] = f"{TOFINO_DIR}/install"
    os_env["PYTHONPATH"] = f"${{PYTHONPATH}}:{FILE_DIR}"
    test_proc = util.start_process(test_cmd, env=os_env, cwd=out_dir)

    def signal_handler(sig, frame):
        log.warning("run_tofino_test: Caught Interrupt, exiting...")
        cleanup(procs)
        os.kill(test_proc.pid, signal.SIGINT)
        os.kill(test_proc.pid, signal.SIGTERM)
        sys.exit(1)

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    stdout, stderr = test_proc.communicate()
    cleanup(procs)
    return test_proc, stdout, stderr