def run(self, path): fd, output_exec_path = tempfile.mkstemp(prefix="hs-exec") os.fdopen(fd).close() try: ghc_proc, get_stats = Process.popen_with_timing( [ self.ghc_bin, path, "-O3", "-o", output_exec_path, ], stdout=subprocess.DEVNULL) exitcode = ghc_proc.wait() assert exitcode == 0, f"ghc failed with exitcode {exitcode}" compile_stats = get_stats() exec_proc, get_stats = Process.popen_with_timing( [ output_exec_path, ], stdout=subprocess.DEVNULL) exitcode = exec_proc.wait() assert exitcode == 0, f"ghc compiled binary failed with exitcode {exitcode}" return { "ghc_real_time": compile_stats["real_time"], "ghc_max_mem": compile_stats["max_mem"], **get_stats(), } finally: os.remove(output_exec_path)
def run_vmtest(self, json_path): _, test_type = load_and_check_test_format(json_path) assert test_type != TestType.STATE, "kevm does not support the state test format" # run json to kore script proc = Process.popen_with_log([ "python", self.json_to_kore_script, json_path, self.get_schedule_kast(), self.get_mode_kast("NORMAL" if test_type == TestType.BLOCKCHAIN else "VMTESTS"), str(self.chain_id), ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) input_kore_source = proc.stdout.read() stderr = proc.stderr.read().decode() exitcode = proc.wait() if exitcode != 0: raise Exception( f"json-to-kore script {self.json_to_kore_script} returned non-zero exitcode {exitcode} and stderr:\n{stderr}" ) # run interpreter in the llvm_k_directory to get output state with tempfile.NamedTemporaryFile() as input_kore_file: # with tempfile.NamedTemporaryFile() as output_kore_file: input_kore_file.write(input_kore_source) input_kore_file.flush() proc, get_stats = Process.popen_with_timing( [ self.llvm_k_interpreter, input_kore_file.name, "-1", "/dev/null", # output_kore_file.name, ], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) # print(proc.stdout.read()) # print(proc.stderr.read()) exitcode = proc.wait() # print(open(output_kore_file.name).read()) if exitcode != 0: raise Exception( f"interpreter {self.llvm_k_interpreter} returned non-zero exitcode {exitcode}" ) return get_stats()
def run_vmtest(self, json_path): _, test_type = load_and_check_test_format(json_path) assert test_type in [ TestType.BLOCKCHAIN, TestType.VM ], "ethereum js does not support this type of test" cwd = os.getcwd() absolute_json_path = os.path.realpath(json_path) try: os.chdir(self.script_dir) proc, get_stats = Process.popen_with_timing( [ "npx", "ts-node", "index.ts" if test_type == TestType.BLOCKCHAIN else "vm.ts", absolute_json_path, ], stderr=subprocess.DEVNULL) exitcode = proc.wait() finally: os.chdir(cwd) if exitcode != 0: raise Exception( f"ethereum js script {self.script_dir}/index.ts returned non-zero exitcode {exitcode}" ) return get_stats()
def run_vmtest(self, json_path): _, test_type = load_and_check_test_format(json_path) assert test_type in [TestType.STATE, TestType.VM ], "py-evm does not support this type of test" proc, get_stats = Process.popen_with_timing([ "python3", self.script, json_path, ], stderr=subprocess.DEVNULL) exitcode = proc.wait() if exitcode != 0: raise Exception( f"py-evm script {self.script} returned non-zero exitcode {exitcode}" ) return get_stats()
def run_vmtest(self, json_path): _, test_type = load_and_check_test_format(json_path) assert test_type != TestType.BLOCKCHAIN, "openethereum does not support full blockchain tests" proc, get_stats = Process.popen_with_timing([ self.evm_binary, "stats-jsontests-vm" if test_type == TestType.VM else "state-test", json_path, ], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) exitcode = proc.wait() if exitcode != 0: raise Exception( f"openethereum evmbin {self.evm_binary} returned non-zero exitcode {exitcode}" ) return get_stats()
def kast_pgm(self, path, input_file_path): kompiled_dir, _ = self.get_kompiled_dir(path) pgm_kore_path = os.path.join(kompiled_dir, "pgm.kore") if os.path.isfile(pgm_kore_path) and not self.is_newer_than( path, pgm_kore_path): print(ANSI.COLOR_GREY + "+ kore program is up-to-date" + ANSI.RESET) return pgm_kore_path try: with open(pgm_kore_path, "wb") as output_kore_file: kast_proc, _ = Process.popen_with_timing( [ *self.gen_k_command("kast"), "--input", "program", "--output", "kore", "--directory", kompiled_dir, input_file_path, ], stdout=subprocess.PIPE, env=self.k_env) output_kore_file.write(KTestRunner.PGM_PREFIX.encode()) output_kore_file.write(kast_proc.stdout.read()) output_kore_file.write(KTestRunner.PGM_SUFFIX.encode()) output_kore_file.flush() exitcode = kast_proc.wait(timeout=self.timeout) assert exitcode == 0, f"kast failed with exitcode {exitcode}" except KeyboardInterrupt as e: os.remove(pgm_kore_path) raise e except Exception as e: os.remove(pgm_kore_path) raise e return pgm_kore_path
def eval_one_term(self, path, input_file_path): _, actual_kompiled_dir = self.get_kompiled_dir(path) pgm_kore_path = self.kast_pgm(path, input_file_path) # run interpreter interpreter_proc, get_stats = Process.popen_with_timing([ os.path.join(actual_kompiled_dir, "interpreter"), pgm_kore_path, "-1", "/dev/null", ]) exitcode = interpreter_proc.wait(timeout=self.timeout) assert exitcode == 0, f"interpreter failed with exitcode {exitcode}" # return { # "kast_real_time": kast_stats["real_time"], # "kast_max_mem": kast_stats["max_mem"], # **get_stats(), # } return get_stats()
def kompile_definition(self, path): kompiled_dir, actual_kompiled_dir = self.get_kompiled_dir(path) # if the kompiled directory is up to date, no need to re-kompile timestamp = os.path.join(actual_kompiled_dir, "timestamp") if os.path.isfile(timestamp) and not self.is_newer_than( path, timestamp): print(ANSI.COLOR_GREY + "+ kompiled directory is up-to-date" + ANSI.RESET) return proc, _ = Process.popen_with_timing([ *self.gen_k_command("kompile"), path, "-Wno", "unused-var", "-O3", "--directory", kompiled_dir, ], env=self.k_env) exitcode = proc.wait(timeout=self.timeout) assert exitcode == 0, f"kompile failed with exitcode {exitcode}"
def run(self, path): maude_proc, get_stats = Process.popen_with_timing( [self.maude_binary, path], stdout=subprocess.DEVNULL) exitcode = maude_proc.wait() assert exitcode == 0, f"maude failed with exitcode {exitcode}" return get_stats()
def run_vmtest(self, json_path): # geth evm doesn't natively support the vmtest format # (https://ethdocs.org/en/latest/contracts-and-transactions/ethereum-tests/vm_tests/) # so we are manually setting up the account info and transaction info etc. test_config, test_type = load_and_check_test_format(json_path) # a VERY coarse approximation right now # only set the code and input data assert test_type != TestType.BLOCKCHAIN, "geth does not support full blockchain tests" total_ops = 0 total_gas = 0 def process_trace(line): nonlocal total_ops nonlocal total_gas # if line.startswith(b"{\"pc\""): # total_ops += 1 # print("\r" + str(total_ops), end="") # else: # print(line) try: obj = json.loads(line) if "op" in obj: total_ops += 1 # print("\r" + str(total_ops), end="") if "gasCost" in obj: total_gas += int(obj["gasCost"], 16) except: pass if test_type == TestType.VM: with tempfile.NamedTemporaryFile() as code_file: with tempfile.NamedTemporaryFile() as data_file: # note: this is an approximation of # what the test actually describes assert len(test_config) == 1 (_, test_config), = test_config.items() code_file.write(test_config["exec"]["code"].encode()) code_file.flush() data_file.write(test_config["exec"]["data"].encode()) data_file.flush() proc, get_stats = Process.popen_with_timing( [ self.evm_binary, # "--json", # "--nomemory", # "--nostack", "--codefile", code_file.name, "--inputfile", data_file.name, "run", ], stderr=subprocess.PIPE, stdout=subprocess.DEVNULL) while True: line = proc.stderr.readline() if line == b"": break process_trace(line) exitcode = proc.wait() else: # STATE or UNKNOWN test proc, get_stats = Process.popen_with_timing( [ self.evm_binary, # "--json", # "--nomemory", # "--nostack", "statetest", json_path, ], stderr=subprocess.PIPE, stdout=subprocess.DEVNULL) while True: line = proc.stderr.readline() if line == b"": break process_trace(line) exitcode = proc.wait() if exitcode != 0: raise Exception( f"geth evm {self.evm_binary} returned non-zero exitcode {exitcode}" ) return {"total_ops": total_ops, "total_gas": total_gas, **get_stats()}