def _setup_block(self, block: RunProgramBlock): if isinstance(block["run_cmd"], List(Str())): block["run_cmds"] = block["run_cmd"] else: block["run_cmds"] = [block["run_cmd"]] if isinstance(block["cwd"], List(Str())): if len(block["cwd"]) != len(block["run_cmd"]) and not isinstance(block["run_cmd"], str): raise ValueError("Number of passed working directories {} " "is unequal with number of passed run commands {}" .format(len(block["cwd"]), len(block["run_cmd"]))) block["cwds"] = block["cwd"] else: block["cwds"] = [block["cwd"]] * len(block["run_cmds"]) self.uses_vcs = block["revision"] != -1 self.vcs_driver = None self.tmp_dir = "" if self.uses_vcs and block.id not in self._dirs: self.vcs_driver = VCSDriver.get_suited_vcs(".") self.tmp_dir = os.path.join(Settings()["tmp_dir"], datetime.datetime.now().strftime("%s%f")) os.mkdir(self.tmp_dir) self._dirs[block.id] = os.path.join(self.tmp_dir, str(block.id)) os.mkdir(self._dirs[block.id]) self.vcs_driver.copy_revision(block["revision"], ".", self._dirs[block.id]) block["working_dir"] = self._dirs[block.id] if self.misc_settings["runner"] != "": block["runner"] = self.misc_settings["runner"] super()._setup_block(block)
def _setup_block(self, block: RunProgramBlock): if isinstance(block["run_cmd"], List(Str())): block["run_cmds"] = block["run_cmd"] else: block["run_cmds"] = [block["run_cmd"]] if isinstance(block["cwd"], List(Str())): if len(block["cwd"]) != len(block["run_cmd"]) and not isinstance( block["run_cmd"], str): raise ValueError( "Number of passed working directories {} " "is unequal with number of passed run commands {}".format( len(block["cwd"]), len(block["run_cmd"]))) block["cwds"] = block["cwd"] else: block["cwds"] = [block["cwd"]] * len(block["run_cmds"]) self.uses_vcs = block["revision"] != -1 self.vcs_driver = None self.tmp_dir = "" if self.uses_vcs and block.id not in self._dirs: self.vcs_driver = VCSDriver.get_suited_vcs(".") self.tmp_dir = os.path.join( Settings()["tmp_dir"], datetime.datetime.now().strftime("%s%f")) os.mkdir(self.tmp_dir) self._dirs[block.id] = os.path.join(self.tmp_dir, str(block.id)) os.mkdir(self._dirs[block.id]) self.vcs_driver.copy_revision(block["revision"], ".", self._dirs[block.id]) block["working_dir"] = self._dirs[block.id] if self.misc_settings["runner"] != "": block["runner"] = self.misc_settings["runner"] super()._setup_block(block)
def create_revision_completer(vcs: VCSDriver) -> WordCompleter: """ Creates a WordCompleter for revision ids. :param vcs: used vcs driver :return: WordCompleter """ valid = [] meta_dict = {} if vcs.has_uncommitted(): valid.append("HEAD") meta_dict["HEAD"] = "Uncommitted changes" for info_dict in vcs.get_info_for_all_revisions(max=50): commit_number = str(info_dict["commit_number"]) if not info_dict["is_uncommitted"]: valid.append(str(info_dict["commit_id"])) msg = info_dict["commit_message"] other_branch_str = " from branch " + info_dict["branch"] + "" if info_dict["is_from_other_branch"] else "" msg = "Commit no. {commit_number}{other_branch_str}: {msg}".format(**locals()) meta_dict[info_dict["commit_id"]] = msg return WordCompleter(valid, ignore_case=True, meta_dict=meta_dict)
def prompt_exec_driver_dict(choose_revision: bool, working_dir: str = None) -> dict: """ Prompt for the contents of run config dict for suitable for the exec run driver. :param choose_revision: can the user choose a specific vcs revision? :param working_dir: default working dir for the exec driver """ from pygments.lexers.shell import BashLexer old_cwd = os.path.realpath(".") working_dir = working_dir or prompt_dir("Working directory: ") run_dict = {} run_dict["cwd"] = working_dir os.chdir(working_dir) run_dict["run_cmd"] = prompt_bash("Command to execute the program: ", allow_empty=False) if prompt_yesno("Set some environment variables? ", default=False): env_dict = {} def set_env_var(): name = prompt("Environment variable name: ", validator=NonEmptyValidator(), completer=WordCompleter(sorted(list(env_dict.keys())), meta_dict=env_dict)) default = env_dict[name] if name in env_dict else "" env_dict[name] = prompt("New value: ", default=default) try: set_env_var() while prompt_yesno("Set another environment variable? "): set_env_var() except KeyboardInterrupt: pass run_dict["env"] = env_dict if choose_revision: vcs = VCSDriver.get_suited_vcs() if vcs.number_of_revisions() + int(vcs.has_uncommitted()) > 1: run_dict["revision"] = default_prompt("Choose a revision in the current repository: ", default="HEAD", completer=create_revision_completer(vcs), validator=RevisionValidator(vcs), display_completions_in_columns=True) if is_builtin_type(int, run_dict["revision"]): run_dict["revision"] = int(run_dict["revision"]) if prompt_yesno("Run some commands before that actually benchmarked command? ", default=False): print("The commands are entered via a multiline input. ") print("Press [Meta+Enter] or [Esc] followed by [Enter] to accept input.") print("You can click with the mouse in order to select text.") run_dict["cmd_prefix"] = prompt('', multiline=True, mouse_support=True, lexer=PygmentsLexer(BashLexer), completer=SystemCompleter()) runners = { "perf_stat": { "func": prompt_perf_stat_exec_dict, "description": PerfStatExecRunner.__description__, }, "rusage": { "func": prompt_rusage_exec_dict, "description": RusageExecRunner.__description__, }, "spec": { "func": prompt_spec_exec_dict, "description": SpecExecRunner.__description__ }, "time": { "func": prompt_time_exec_dict, "description": TimeExecRunner.__description__ } } valid = sorted(list(runners.keys())) meta_dict = {} for driver in runners: meta_dict[driver] = runners[driver]["description"] driver = prompt("Used runner: ", completer=WordCompleter(words=valid, ignore_case=True, meta_dict=meta_dict), validator=WordValidator(ignore_case=False, valid_words=valid, error_msg="Invalid runner"), display_completions_in_columns=True) run_dict["runner"] = driver run_dict[driver] = runners[driver]["func"](run_dict) os.chdir(old_cwd) return run_dict
def prompt_build_dict(with_header: bool = True, whole_config: bool = True) -> dict: """ Prompts for the contents of the build config dictionary. :param with_header: print "Create the …" header? :param whole_config: prompt for the whole build config (with attributes and run config) :return: build config dictionary """ if with_header: print("Create the build configuration for the program block") old_cwd = os.path.realpath(".") build_dict = {} build_dict["base_dir"] = prompt_dir("Base directory: ") os.chdir(build_dict["base_dir"]) build_dict["working_dir"] = prompt_dir("Working directory (relative to the base dir): ") os.chdir(build_dict["working_dir"]) working_dir_abs = os.path.realpath(".") build_dict["build_cmd"] = prompt_bash("Command to build the program: ", allow_empty=True) vcs = VCSDriver.get_suited_vcs() cur_branch = vcs.get_branch() default_description = None if cur_branch is not None: # version control system is used build_dict["branch"] = default_prompt("Used branch? ", default=cur_branch, completer=WordCompleter(vcs.get_valid_branches(), meta_dict={ cur_branch: "Current branch" }), validator=WordValidator(vcs.get_valid_branches(), ignore_case=False, error_msg="Invalid branch name"), display_completions_in_columns=True) vcs.set_branch(build_dict["branch"]) build_dict["revision"] = default_prompt("Revision in this branch: ", default="HEAD", completer=create_revision_completer(vcs), validator=RevisionValidator(vcs), display_completions_in_columns=True) if is_builtin_type(int, build_dict["revision"]): build_dict["revision"] = int(build_dict["revision"]) default_description = vcs.get_info_for_revision(build_dict["revision"])["commit_message"] rand_dict = dict() if prompt_yesno("Randomize program binaries (works with gcc and cparser built programs)? ", default=True): meta_dict = {str(get_cache_line_size()): "Current cache line size", "0": "No padding"} size_completer = WordCompleter(sorted(list(meta_dict.keys())), meta_dict=meta_dict) rand_dict["heap"] = int(default_prompt("Maximum size of the random padding of each heap allocation? ", default=get_cache_line_size(), completer=size_completer, validator=TypeValidator(NaturalNumber()))) #rand_dict["stack"] = int(default_prompt("Maximum size of the random padding of each stack frame? ", # default=get_cache_line_size(), completer=size_completer, # validator=TypeValidator(NaturalNumber()))) rand_dict["bss"] = prompt_yesno("Randomize bss segment? ", default=True) rand_dict["data"] = prompt_yesno("Randomize data segment? ", default=True) rand_dict["rodata"] = prompt_yesno("Randomize rodata segment? ", default=True) rand_dict["file_structure"] = prompt_yesno("Randomize the file structure (location of functions)? ", default=True) if prompt_yesno("Randomize the link order (works with gcc and cparser)?", default=True): rand_dict["linker"] = True if rand_dict: build_dict["randomization"] = rand_dict build_dict["number"] = int(prompt("How many times should the program be built? ", validator=TypeValidator(Int()))) os.chdir(old_cwd) if whole_config: attributes_dict = prompt_attributes_dict(default_description) run_config = prompt_run_dict(working_dir=build_dict["working_dir"], binary_number=build_dict["number"], whole_config=False, driver="exec") return { "attributes": attributes_dict, "build_config": build_dict, "run_config": run_config } return build_dict