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
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
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