示例#1
0
def validate_translation(p4_file, target_dir, p4c_bin):
    log.info("\n\n" + "-" * 70)
    log.info("Analysing %s", p4_file)
    util.check_dir(target_dir)
    fail_dir = target_dir.joinpath("failed")
    # run the p4 compiler and dump all the passes for this file
    passes = gen_p4_passes(p4c_bin, target_dir, p4_file)
    passes = prune_passes(passes)
    p4_py_files = []
    # for each emitted pass, generate a python representation
    for p4_pass in passes:
        p4_path = Path(p4_pass).stem
        py_file = f"{target_dir}/{p4_path}.py"
        result = run_p4_to_py(p4_pass, py_file)
        if result.returncode != util.EXIT_SUCCESS:
            log.error("Failed to translate P4 to Python.")
            log.error("Compiler crashed!")
            util.check_dir(fail_dir)
            with open(f"{fail_dir}/error.txt", 'w+') as err_file:
                err_file.write(result.stderr.decode("utf-8"))
            util.copy_file([p4_pass, py_file], fail_dir)
            return result.returncode
        p4_py_files.append(f"{target_dir}/{p4_path}")
    if len(p4_py_files) < 2:
        log.warning("P4 file did not generate enough passes!")
        return util.EXIT_SKIPPED
    # perform the actual comparison
    result = z3check.z3_check(p4_py_files, fail_dir)
    return result
def validate_translation(p4_file,
                         target_dir,
                         p4c_bin,
                         allow_undef=False,
                         dump_info=False):
    info = INFO

    # customize the main info with the new information
    info["compiler"] = str(p4c_bin)
    info["exit_code"] = util.EXIT_SUCCESS
    info["p4z3_bin"] = str(P4Z3_BIN)
    info["out_dir"] = str(target_dir)
    info["input_file"] = str(p4_file)
    info["allow_undef"] = allow_undef
    info["validation_bin"] = f"python3 {__file__}"

    log.info("\n" + "-" * 70)
    log.info("Analysing %s", p4_file)
    start_time = datetime.now()
    util.check_dir(target_dir)
    fail_dir = target_dir.joinpath("failed")
    # run the p4 compiler and dump all the passes for this file
    passes = gen_p4_passes(p4c_bin, target_dir, p4_file)
    passes = prune_passes(passes)
    p4_py_files = []
    # for each emitted pass, generate a python representation
    for p4_pass in passes:
        p4_path = Path(p4_pass).stem
        py_file = f"{target_dir}/{p4_path}.py"
        result = run_p4_to_py(p4_pass, py_file)
        if result.returncode != util.EXIT_SUCCESS:
            log.error("Failed to translate P4 to Python.")
            log.error("Compiler crashed!")
            util.check_dir(fail_dir)
            with open(f"{fail_dir}/error.txt", 'w+') as err_file:
                err_file.write(result.stderr.decode("utf-8"))
            util.copy_file([p4_pass, py_file], fail_dir)
            return result.returncode
        p4_py_files.append(f"{target_dir}/{p4_path}")
    if len(p4_py_files) < 2:
        log.warning("P4 file did not generate enough passes!")
        return util.EXIT_SKIPPED
    # perform the actual comparison
    result, check_info = z3check.z3_check(p4_py_files, fail_dir, allow_undef)
    # merge the two info dicts
    info["exit_code"] = result
    info = {**info, **check_info}
    done_time = datetime.now()
    elapsed = done_time - start_time
    time_str = time.strftime("%H hours %M minutes %S seconds",
                             time.gmtime(elapsed.total_seconds()))
    ms = elapsed.microseconds / 1000
    log.info("Translation validation took %s %s milliseconds.", time_str, ms)
    if dump_info:
        json_name = target_dir.joinpath(f"{p4_file.stem}_info.json")
        log.info("Dumping configuration to %s.", json_name)
        with open(json_name, 'w') as json_file:
            json.dump(info, json_file, indent=2, sort_keys=True)
    return result
示例#3
0
def run_violation_test(test_folder, allow_undefined=True):
    src_p4_file = test_folder.joinpath("orig.p4")
    src_py_file = test_folder.joinpath(f"{src_p4_file.stem}.py")
    tv_check.run_p4_to_py(src_p4_file, src_py_file)
    for p4_file in list(test_folder.glob("**/[0-9]*.p4")):
        py_file = test_folder.joinpath(f"{p4_file.stem}.py")
        tv_check.run_p4_to_py(p4_file, py_file)
        result = z3_check.z3_check(
            [str(src_py_file), str(py_file)], None, allow_undefined)
        if result != util.EXIT_VIOLATION:
            return util.EXIT_FAILURE
    return util.EXIT_SUCCESS
示例#4
0
def validate_translation(p4_file, target_dir, p4c_bin, allow_undef=False):
    log.info("\n\n" + "-" * 70)
    log.info("Analysing %s", p4_file)
    start_time = datetime.now()
    util.check_dir(target_dir)
    fail_dir = target_dir.joinpath("failed")
    # run the p4 compiler and dump all the passes for this file
    passes = gen_p4_passes(p4c_bin, target_dir, p4_file)
    passes = prune_passes(passes)
    p4_py_files = []
    # for each emitted pass, generate a python representation
    for p4_pass in passes:
        p4_path = Path(p4_pass).stem
        py_file = f"{target_dir}/{p4_path}.py"
        result = run_p4_to_py(p4_pass, py_file)
        if result.returncode != util.EXIT_SUCCESS:
            log.error("Failed to translate P4 to Python.")
            log.error("Compiler crashed!")
            util.check_dir(fail_dir)
            with open(f"{fail_dir}/error.txt", 'w+') as err_file:
                err_file.write(result.stderr.decode("utf-8"))
            util.copy_file([p4_pass, py_file], fail_dir)
            return result.returncode
        p4_py_files.append(f"{target_dir}/{p4_path}")
    if len(p4_py_files) < 2:
        log.warning("P4 file did not generate enough passes!")
        return util.EXIT_SKIPPED
    # perform the actual comparison
    result = z3check.z3_check(p4_py_files, fail_dir, allow_undef)
    done_time = datetime.now()
    elapsed = done_time - start_time
    time_str = time.strftime("%H hours %M minutes %S seconds",
                             time.gmtime(elapsed.total_seconds()))
    ms = elapsed.microseconds / 1000
    log.info("Translation validation took %s %s milliseconds.", time_str, ms)
    return result