def setup_logging() -> None: """ Sets up the logging module to have a verbose option and formats the Console handler and File handler """ logging.addLevelName(VERBOSE, "VERBOSE") logging.Logger.verbose = logger_verbose logging.verbose = logging_verbose logging.VERBOSE = VERBOSE # define console handler console_handler = ConsoleHandler(sys.stderr) if hasattr(console_handler, "_column_color"): # noinspection PyProtectedMember # pylint: disable=protected-access console_handler._column_color['%(message)s'][logging.VERBOSE] = ('cyan', None, False) console_formatter = logging.Formatter("[%(asctime)s] %(levelname)s : %(message)s", "%H:%M:%S") console_handler.setFormatter(console_formatter) console_handler.setLevel(logging.VERBOSE) # define file handler if not os.path.exists(os.path.dirname(get_global_conf().getdir("install", "log_file"))): os.makedirs(os.path.dirname(get_global_conf().getdir("install", "log_file"))) file_handler = logging.FileHandler(get_global_conf().getdir("install", "log_file")) # add handlers logging.getLogger().addHandler(console_handler) logging.getLogger().addHandler(file_handler) logging.getLogger().setLevel(get_global_conf().getint("install", "log_level"))
def install(force: bool) -> None: """ Install all the necessary above programs and modules :param force: force installation if package is already installed :raise subprocess.CalledProcessError on error """ logging.info("Installing required programs and modules") packages_to_install = set(get_global_conf().getlist("install", "dependencies")) if get_global_conf().getboolean("install", "module_handling"): packages_to_install.add("python3-pip") # pylint: disable=no-member compiler = get_global_conf().get("install", "compiler") compiler_conf = get_compiler_conf(*compiler.split(".")) for section in compiler_conf.sections(): if section in ["env", "install"]: continue packages_to_install.update(compiler_conf[section].getlist("depend", fallback=[])) packages_to_install.update(get_programs_dependencies()) packages_to_install.update(compiler_conf.getlist("install", "depend", fallback=[])) dependency_installer.DependenciesInstaller.factory(list(packages_to_install)).run() Installer.factory(compiler_conf["install"], force).run() if get_global_conf().getboolean("install", "module_handling"): install_python_modules() if get_global_conf().getboolean("install", "llvm_bitcode"): install_wllvm(force)
def test_no_module_handling(): get_global_conf().set("install", "module_handling", "false") with \ mock.patch("lib.configuration.dependencies.install_python_modules", lambda: raise_(Exception("NO"))),\ mock.patch("lib.configuration.dependencies.install_wllvm", lambda _: 0),\ mock.patch("lib.configuration.dependencies.get_programs_dependencies", lambda: []): lib.configuration.dependencies.install(True)
def prepare_env(self) -> dict: """ Sets up the environment depending on the compiler chosen :return: the environment to use """ env = os.environ.copy() env["PREFIX"] = self.install_dir # if we are configuring utilities, stop here, we already have set everything necessary if self.conf.getboolean("utility"): return env compiler_full_name = get_global_conf().get("install", "compiler") compiler_package, compiler_name = compiler_full_name.split(".") compiler_conf = get_compiler_conf(compiler_package, compiler_name) for env_name, env_value in compiler_conf.items("env"): if env_name.upper() == "PATH": env[env_name.upper()] = "{}:{}".format(env_value, env["PATH"]) else: env[env_name.upper()] = env_value env["CFLAGS"] = env.get("CFLAGS", "") + " -g " env["CXXFLAGS"] = env.get("CXXFLAGS", "") + " -g " if get_global_conf().getboolean("install", "llvm_bitcode"): env["PATH"] = "{}:{}".format( os.path.join(get_global_conf().getdir("utilities", "install_directory"), "wllvm"), env["PATH"] ) env["LLVM_COMPILER"] = "clang" env["CC"] = "wllvm" env["CXX"] = "wllvm++" return env
def change_coredump_pattern() -> None: """ Changes the coredump pattern system wide """ core_dump_location = get_global_conf().get("trigger", "core_dump_location") core_dump = os.path.join(core_dump_location, get_global_conf().get("trigger", "core_dump_pattern")) last = False with open("/etc/sysctl.conf") as _file: for _line in _file: if core_dump in _line and ("#" not in _line or _line.index("#") > _line.index(core_dump)): last = True elif "kernel.core_pattern" in _line and\ ("#" not in _line or _line.index("#") > _line.index("kernel.core_pattern")): last = False if last: return command = ["echo", '"kernel.core_pattern={}"'.format(core_dump), ">>", "/etc/sysctl.conf"] try: launch_and_log_as_root(command) launch_and_log_as_root(["sysctl", "-p"]) except subprocess.CalledProcessError: logging.warning("Please add 'kernel.core_pattern=%(pattern)s' to /etc/sysctl.conf", dict(pattern=core_dump)) raise
def prepare_env(self) -> dict: """ Sets up the environment depending on the compiler chosen :return: the environment to use """ env = os.environ.copy() env["PREFIX"] = self.install_dir # if we are configuring utilities, stop here, we already have set everything necessary if self.conf.getboolean("utility"): return env compiler_full_name = get_global_conf().get("install", "compiler") compiler_package, compiler_name = compiler_full_name.split(".") compiler_conf = get_compiler_conf(compiler_package, compiler_name) for env_name, env_value in compiler_conf.items("env"): if env_name.upper() == "PATH": env[env_name.upper()] = "{}:{}".format(env_value, env["PATH"]) else: env[env_name.upper()] = env_value env["CFLAGS"] = env.get("CFLAGS", "") + " -g " env["CXXFLAGS"] = env.get("CXXFLAGS", "") + " -g " if get_global_conf().getboolean("install", "llvm_bitcode"): env["PATH"] = "{}:{}".format( os.path.join( get_global_conf().getdir("utilities", "install_directory"), "wllvm"), env["PATH"]) env["LLVM_COMPILER"] = "clang" env["CC"] = "wllvm" env["CXX"] = "wllvm++" return env
def setUpClass(cls) -> None: """ The class setup, ensures the log directory is ready """ # pylint: disable=no-member get_global_conf().set("install", "make_args", "-j,-l{}".format(multiprocessing.cpu_count())) setup_logging()
def choose_compiler() -> str: """ Allows the user to choose his compiler :return: the compiler to use """ compilers = [] for package in os.listdir(constants.PLUGINS_PATH): if os.path.isdir(os.path.join(constants.PLUGINS_PATH, package)): compilers_dir = os.path.join(constants.PLUGINS_PATH, package, "compilers") if os.path.exists(compilers_dir): compilers.extend([ "{}.{}".format(package, compiler.split(".")[0]) for compiler in os.listdir(compilers_dir) ]) return ask_question("Which compiler do you want to use ?\n\t{}\n".format( "\n\t".join( format_list_numbered(compilers, get_global_conf().get("install", "compiler")))), validate_answers=validate_multiple_choice, default=get_global_conf().get("install", "compiler"), answer_list=compilers)
def change_coredump_pattern() -> None: """ Changes the coredump pattern system wide """ core_dump_location = get_global_conf().get("trigger", "core_dump_location") core_dump = os.path.join( core_dump_location, get_global_conf().get("trigger", "core_dump_pattern")) last = False with open("/etc/sysctl.conf") as _file: for _line in _file: if core_dump in _line and ("#" not in _line or _line.index("#") > _line.index(core_dump)): last = True elif "kernel.core_pattern" in _line and\ ("#" not in _line or _line.index("#") > _line.index("kernel.core_pattern")): last = False if last: return command = [ "echo", '"kernel.core_pattern={}"'.format(core_dump), ">>", "/etc/sysctl.conf" ] try: launch_and_log_as_root(command) launch_and_log_as_root(["sysctl", "-p"]) except subprocess.CalledProcessError: logging.warning( "Please add 'kernel.core_pattern=%(pattern)s' to /etc/sysctl.conf", dict(pattern=core_dump)) raise
def test_module_handling(self): get_global_conf().set("install", "module_handling", "true") with \ mock.patch("lib.configuration.dependencies.install_python_modules", lambda: raise_(Exception("NO"))),\ mock.patch("lib.configuration.dependencies.install_wllvm", lambda _: 0),\ mock.patch("lib.configuration.dependencies.get_programs_dependencies", lambda: []): try: lib.configuration.dependencies.install(True) except Exception as exc: # pylint: disable=broad-except self.assertEqual(str(exc), "NO")
def choose_coredump_location() -> str: """ Choose whether to change the coredump location and which one to use if so :return the coredump location to use """ return ask_question( "What coredump location do you want ? Default is {}\n".format( get_global_conf().get("trigger", "core_dump_location")), validate_answers=validate_string_question, default=get_global_conf().get("trigger", "core_dump_location"))
def choose_coredump_pattern() -> str: """ Choose the coredump pattern :return the coredump pattern to use """ return ask_question( "What coredump pattern do you want ? Default is {}\n".format( get_global_conf().get("trigger", "core_dump_pattern")), validate_answers=validate_string_question, default=get_global_conf().get("trigger", "core_dump_pattern"))
def choose_install_dir() -> str: """ Choose in which directory to install programs and utilities :return the install director to use """ return ask_question( "Where do you want to install programs ? Default is {}\n".format( get_global_conf().get("install", "install_directory")), validate_answers=validate_string_question, default=get_global_conf().get("install", "install_directory"))
def choose_source_storage_dir() -> str: """ Choose in which directory to store downloaded sources :return the source directory to use """ return ask_question( "Where do you want to download sources ? Default is {}\n".format( get_global_conf().get("install", "source_directory")), validate_answers=validate_string_question, default=get_global_conf().get("install", "source_directory"))
def choose_build_dir() -> str: """ Choose in which build directory :return the build directory to use """ return ask_question( "Where do you want to set the build directory ? Default is {}\n". format(get_global_conf().get("install", "build_directory")), validate_answers=validate_string_question, default=get_global_conf().get("install", "build_directory"))
def __enter__(self): logging.getLogger().setLevel(0) wllvm = "wllvm" if self.compiler.bitcode else "no-wllvm" get_global_conf().set( "install", "compiler", "{}.{}".format(self.compiler.package, self.compiler.name)) get_global_conf().set("install", "llvm_bitcode", str(self.compiler.bitcode)) get_global_conf()["DEFAULT"]["default_directory"] = \ os.path.join(TEST_DIRECTORY, self.compiler.package, self.compiler.name, wllvm) get_global_conf().set("install", "source_directory", os.path.join(ROOT_PATH, "src")) handlers = logging.getLogger().handlers while len(handlers) > 0: handlers[0].close() logging.getLogger().removeHandler(handlers[0]) logging.getLogger().addHandler( logging.FileHandler( os.path.join(TestRunner.log_directory, self.filename))) get_global_conf().set( "plugins", "enabled_plugins", ",".join([ "{}.{}".format(plugin.package, plugin.name) for plugin in self.compiler.plugins ])) for plugin in self.compiler.plugins: importlib.import_module("plugins.{}.{}".format( plugin.package, plugin.name))
def choose_make_arguments() -> list: """ Choose which make arguments to add :return list of make arguments to send """ return ask_question( "What arguments do you want to give to make ? Default is {}\n".format( get_global_conf().get("install", "make_args")), validate_answers=validate_string_question, default=" ".join(get_global_conf().getlist("install", "make_args"))).split(" ")
def choose_module_handling() -> str: """ Choose whether or not to install required python modules automatically or not :return whether to handle python modules or not """ return str( ask_question( "Do you want the script to automatically install required python modules ? {}" .format( format_closed_question(get_global_conf().getboolean( "install", "module_handling"))), validate_answers=validate_closed_question, default=get_global_conf().get("install", "module_handling")))
def choose_wllvm() -> str: """ Allows the user to choose whether to produce llvm bitcode or not :return whether to return wllvm or not """ return str( ask_question( "Do you want to produce llvm bitcode from the binaries ? {}". format( format_closed_question(get_global_conf().getboolean( "install", "llvm_bitcode"))), validate_answers=validate_closed_question, default=get_global_conf().get("install", "llvm_bitcode")))
def show_progress() -> str: """ Asks user whether to show progress on long time running tasks or not :return: the answer """ return str( ask_question( "Do you want to show progress on long time running tasks ? {}". format( format_closed_question( get_global_conf()["DEFAULT"]["show_progress"])), validate_answers=validate_closed_question, default=get_global_conf()["DEFAULT"]["show_progress"]))
def choose_git_protocol() -> str: """ Choose which protocol to use with git :return the protocol to use with git """ return ask_question( "WHat protocol do you want to use for git ? \n\t{}\n".format( "\n\t".join( format_list_numbered(["https", "ssh"], get_global_conf().get( "install", "git_protocol")))), validate_answers=validate_multiple_choice, default=get_global_conf().get("install", "git_protocol"), answer_list=["https", "ssh"])
def test_all_programs_are_registered(self) -> None: """ Checks that all programs registered have a directory and vice-versa """ programs_registered = set(get_global_conf().getlist("install", "programs")) program_dirs = set(os.listdir(constants.PROGRAMS_SOURCE_PATH)) self.assertSetEqual(programs_registered, program_dirs)
def run(self) -> None: """ The main program, handles everything """ with suppress(FileNotFoundError): shutil.rmtree(self.working_dir) with FileLock( os.path.join("/tmp/", "." + self.conf.get("name") + ".build")): if not self.download_sources(): self.force_installation = True if os.path.exists(self.install_dir): if not self.force_installation: logging.warning( "The install directory is not empty. %(name)s will not be installed", dict(name=self.conf["name"])) return 1 else: logging.verbose( "%(name)s was already installed, removing it before continuing", dict(name=self.conf["name"])) shutil.rmtree(self.install_dir) logging.info("Treating " + self.conf["display_name"]) self.prepare_sources() self.patch(self.conf.getlist("patches_pre_config", []), self.working_dir) self.configure() self.patch(self.conf.getlist("patches_post_config", []), self.working_dir) self.copy_files(self.conf.getlist("copy_post_config", [])) if self.conf.getboolean("make", True): self.make() self.install() if get_global_conf().getboolean( "install", "llvm_bitcode") and ("bitcode_file" in self.conf.keys()): self.extract_bitcode() self.patch(self.conf.getlist("patches_post_install", []), self.install_dir) self.copy_files(self.conf.getlist("copy_post_install", [])) if os.path.exists( os.path.join(self.patches_path, self.conf["display_name"] + ".patch")): self.patch([self.conf["display_name"] + ".patch"], self.working_dir, True) logging.info("finished installing %(name)s", dict(name=self.conf["display_name"]))
def working_dir(self) -> str: """ The working directory to use """ return os.path.join( get_global_conf().getdir("install", "build_directory"), self.conf["name"])
def sources_dir(self) -> str: """ Where the sources are stored """ return os.path.expanduser( os.path.join(get_global_conf().get("install", "source_directory"), self.conf["name"]))
def extract_dir(self) -> str: """ The absolute path to the directory where to extract the files """ return os.path.join( get_global_conf().getdir("install", "build_directory"), self.conf["name"])
def prepare_sources(self) -> None: source_directory = os.path.join( get_global_conf().getdir("install", "source_directory"), "sources", self.conf.get("name")) os.makedirs(source_directory, exist_ok=True) archive_found = [ _file_ for _file_ in os.listdir(source_directory) if re.match(self.conf.get("source"), _file_) ] if not len(archive_found): print( "You need to accept a license agreement before downloading {}." .format(self.conf.get("name"))) print("Please go to {} then put the downloaded file in {}/".format( self.conf.get("url"), source_directory)) input("Please press enter when done") archive_found = [ _file_ for _file_ in os.listdir(source_directory) if re.match(self.conf.get("source"), _file_) ] if not len(archive_found): print( "Could not find the archive, please ensures that the name matches", self.conf.get("source")) return self.prepare_sources() tar = tarfile.open(os.path.join(source_directory, archive_found[0])) tar.extractall(self.extract_dir) tar.close() self.conf["source"] = archive_found[0]
def prepare_sources(self) -> None: source_directory = os.path.join( get_global_conf().getdir("install", "source_directory"), "sources", self.conf.get("name") ) os.makedirs(source_directory, exist_ok=True) archive_found = [_file_ for _file_ in os.listdir(source_directory) if re.match(self.conf.get("source"), _file_)] if not len(archive_found): print("You need to accept a license agreement before downloading {}.".format(self.conf.get("name"))) print( "Please go to {} then put the downloaded file in {}/".format(self.conf.get("url"), source_directory) ) input("Please press enter when done") archive_found = [ _file_ for _file_ in os.listdir(source_directory) if re.match(self.conf.get("source"), _file_) ] if not len(archive_found): print("Could not find the archive, please ensures that the name matches", self.conf.get("source")) return self.prepare_sources() tar = tarfile.open(os.path.join(source_directory, archive_found[0])) tar.extractall(self.extract_dir) tar.close() self.conf["source"] = archive_found[0]
def choose_plugins_to_enable() -> list: """ Seeks all findable plugins and asks which ones to enable :return list of plugins to enable """ plugins_to_enable = list() for package in os.listdir(constants.PLUGINS_PATH): package_full_path = os.path.join(constants.PLUGINS_PATH, package) if not os.path.isdir(package_full_path): continue for _file_ in os.listdir(package_full_path): if _file_.endswith(".py") and _file_ != "__init__.py": plugin = "{}.{}".format(package, os.path.splitext(_file_)[0]) plugin_is_enabled = True if plugin in get_global_conf().get( "plugins", "enabled_plugins") else False answer = ask_question( "Would you like to enable the {} plugin ? {}".format( plugin, format_closed_question(plugin_is_enabled)), validate_answers=validate_closed_question, default="y" if plugin_is_enabled else "n") if answer: plugins_to_enable.append(plugin) return plugins_to_enable
def test_all_programs_are_registered(self) -> None: """ Checks that all programs registered have a directory and vice-versa """ programs_registered = set(get_global_conf().getlist( "install", "programs")) program_dirs = set(os.listdir(constants.PROGRAMS_SOURCE_PATH)) self.assertSetEqual(programs_registered, program_dirs)
def pre_benchmark_run(self) -> None: """ For benchmarking, we need to work on bigger files. We use transmission for this purpose """ shutil.unpack_archive( os.path.join(get_global_conf().get("install", "source_directory"), "cppcheck-148/cppcheck-1.48.tar.gz"), "/tmp/cppcheck-148" ) self.cmd = " ".join(self.cmd.split(" ")[:-1]) + " /tmp/cppcheck-148/cppcheck-1.48"
def pre_benchmark_run(self) -> None: """ When benchmarking, it is better to have a bigger workload. We use transmission for this purpose """ shutil.unpack_archive( os.path.join(get_global_conf().get("install", "source_directory"), "cppcheck-152/cppcheck-1.52.tar.gz"), "/tmp/cppcheck-152" ) self.cmd = " ".join(self.cmd.split(" ")[:-1]) + " /tmp/cppcheck-152/cppcheck-1.52"
def make(self) -> None: """ runs 'make' """ logging.info("Compiling %(name)s", dict(name=self.conf["display_name"])) cmd = ["make"] + get_global_conf().getlist("install", "make_args") if self.conf.getlist("make_args", None): cmd += self.conf.getlist("make_args") helper.launch_and_log(cmd, cwd=self.working_dir, env=self.env, error_msg="Compilation failed")
def change_coredump_filter() -> None: """ Changes the coredump filter for the process and its children """ logging.debug("Changing coredump filter") coredump_filter = get_global_conf().get("trigger", "core_dump_filter") with open("/proc/{}/coredump_filter".format(os.getpid()), "w") as core_file: core_file.write(coredump_filter)
def create_coredump_directory() -> None: """ Creates the coredump directory and gives access to anybody """ logging.debug("Creating the coredump storage directory") core_dump_location = get_global_conf().get("trigger", "core_dump_location") os.makedirs(core_dump_location, exist_ok=True) os.chmod(core_dump_location, 0o777)
def pre_trigger_run(self, trigger: RawTrigger, *args, **kwargs) -> None: """ Updates the trigger command to run rr on top of the plugin's command :param trigger: the trigger that will run :param args: other arguments to pass to parents :param kwargs: other keywords arguments to pass to parents """ super().pre_trigger_run(trigger=trigger, **kwargs) rr_location = os.path.join(get_global_conf().getdir("utilities", "install_directory"), "rr") trigger.cmd = "{} record {}".format(os.path.join(rr_location, "bin/rr"), trigger.cmd)
def show_progress(done: int, total: int, section: str = "install") -> None: """ Shows the current status of the run if progress in enabled :param done: number of tasks already done :param total: total number of tasks to do """ if get_global_conf().getboolean(section, "show_progress"): time = datetime.datetime.strftime(datetime.datetime.now(), "%H:%M:%S") print("[\x1b[30;1m{time}\x1b[0m] [{done}/{total}]".format(time=time, done=done, total=total), end="\r")
def test_coredump_filter(self) -> None: """ Checks that the coredump filter indeed gets changed """ run.change_coredump_filter() my_filter = get_global_conf().get("trigger", "core_dump_filter") with open("/proc/{}/coredump_filter".format(os.getpid())) as proc_file: value = proc_file.read() self.assertEqual(my_filter, hex(int(value, 16)))
def pre_benchmark_run(self) -> None: """ When benchmarking, it is better to have a bigger workload. We use transmission for this purpose """ shutil.unpack_archive( os.path.join(get_global_conf().get("install", "source_directory"), "cppcheck-152/cppcheck-1.52.tar.gz"), "/tmp/cppcheck-152") self.cmd = " ".join( self.cmd.split(" ")[:-1]) + " /tmp/cppcheck-152/cppcheck-1.52"
def pre_benchmark_run(self) -> None: """ For benchmarking, we need to work on bigger files. We use transmission for this purpose """ shutil.unpack_archive( os.path.join(get_global_conf().get("install", "source_directory"), "cppcheck-148/cppcheck-1.48.tar.gz"), "/tmp/cppcheck-148") self.cmd = " ".join( self.cmd.split(" ")[:-1]) + " /tmp/cppcheck-148/cppcheck-1.48"
def extract_bitcode(self) -> None: """ Extracts and copies the bitcode file to the bin directory """ logging.info("Copying bitcode file") source = os.path.join(self.working_dir, self.conf["bitcode_file"].lstrip("/")) cmd = "{}/wllvm/extract-bc {}".format(get_global_conf().getdir("utilities", "install_directory"), source) helper.launch_and_log(cmd.split(" "), env=self.env, error_msg="Bitcode extraction failed") shutil.copy(source + ".bc", self.install_dir + "/bin/")
def __init__(self, destination_folder, upstream, protocol=None, **kwargs): self.destination_folder = destination_folder self.upstream = upstream self.kwargs = kwargs self.protocol = protocol or get_global_conf().get("install", "git_protocol") if self.protocol.startswith("http") and self.upstream.startswith("*****@*****.**"): self.upstream = self.upstream.replace("[email protected]:", "https://github.com/") elif self.protocol == "ssh" and self.upstream.startswith("https://github.com/"): self.upstream = self.upstream.replace("https://github.com/", "[email protected]:") if not os.path.exists(os.path.join(destination_folder, ".git")): self.init()
def run(self) -> None: """ The main program, handles everything """ with suppress(FileNotFoundError): shutil.rmtree(self.working_dir) with FileLock(os.path.join("/tmp/", "." + self.conf.get("name") + ".build")): if not self.download_sources(): self.force_installation = True if os.path.exists(self.install_dir): if not self.force_installation: logging.warning( "The install directory is not empty. %(name)s will not be installed", dict(name=self.conf["name"]) ) return 1 else: logging.verbose( "%(name)s was already installed, removing it before continuing", dict(name=self.conf["name"]) ) shutil.rmtree(self.install_dir) logging.info("Treating " + self.conf["display_name"]) self.prepare_sources() self.patch(self.conf.getlist("patches_pre_config", []), self.working_dir) self.configure() self.patch(self.conf.getlist("patches_post_config", []), self.working_dir) self.copy_files(self.conf.getlist("copy_post_config", [])) if self.conf.getboolean("make", True): self.make() self.install() if get_global_conf().getboolean("install", "llvm_bitcode") and ("bitcode_file" in self.conf.keys()): self.extract_bitcode() self.patch(self.conf.getlist("patches_post_install", []), self.install_dir) self.copy_files(self.conf.getlist("copy_post_install", [])) if os.path.exists(os.path.join(self.patches_path, self.conf["display_name"] + ".patch")): self.patch([self.conf["display_name"] + ".patch"], self.working_dir, True) logging.info("finished installing %(name)s", dict(name=self.conf["display_name"]))
def post_trigger_clean(self, trigger: RawTrigger, *args, **kwargs) -> None: """ Saves all coredumps to the exp-results directory :param trigger: the trigger instance that we run :param args: additional arguments :param kwargs: additional keyword arguments """ destination_folder = os.path.join(get_global_conf().getdir("trigger", "exp-results"), trigger.conf.get("name")) with suppress(FileNotFoundError): if not os.path.exists(destination_folder): os.makedirs(destination_folder) shutil.move( trigger.conf.get_core_path(), os.path.join(destination_folder, os.path.basename(trigger.conf.get_core_path())) )
def create_big_file(size: int=1) -> str: """ Used to create a very big file to use for some processing :param size: the number of times to duplicate the file, increasing its size :return: the file path """ return_file = os.path.join(get_global_conf().getdir("trigger", "workloads"), "{}-{}.tar".format("workloads", size)) if os.path.exists(return_file): return return_file os.makedirs(os.path.dirname(return_file), exist_ok=True) with open(return_file, "w") as big_file: for _ in range(size): big_file.write("0" * (1024 ** 2)) return return_file
def __enter__(self): logging.getLogger().setLevel(0) wllvm = "wllvm" if self.compiler.bitcode else "no-wllvm" get_global_conf().set("install", "compiler", "{}.{}".format(self.compiler.package, self.compiler.name)) get_global_conf().set("install", "llvm_bitcode", str(self.compiler.bitcode)) get_global_conf()["DEFAULT"]["default_directory"] = os.path.join( TEST_DIRECTORY, self.compiler.package, self.compiler.name, wllvm ) get_global_conf().set("install", "source_directory", os.path.join(ROOT_PATH, "src")) handlers = logging.getLogger().handlers while len(handlers) > 0: handlers[0].close() logging.getLogger().removeHandler(handlers[0]) logging.getLogger().addHandler(logging.FileHandler(os.path.join(TestRunner.log_directory, self.filename))) get_global_conf().set( "plugins", "enabled_plugins", ",".join(["{}.{}".format(plugin.package, plugin.name) for plugin in self.compiler.plugins]), ) for plugin in self.compiler.plugins: importlib.import_module("plugins.{}.{}".format(plugin.package, plugin.name))
def pre_trigger_run(self, trigger: RawTrigger, *args, **kwargs) -> None: """ Updates the coredumps information in order to generate some correctly :param trigger: the trigger instance to use :param args: additional arguments :param kwargs: additional keyword arguments """ trigger_full_path = trigger.cmd.split(" ")[0] if os.path.exists("{}-{}".format(trigger_full_path, self.extension)): trigger.cmd = trigger.cmd.replace(trigger_full_path, "{}-{}".format(trigger_full_path, self.extension)) trigger.conf["executable"] = "{}-{}".format(trigger.conf.get("executable"), self.extension) os.makedirs(get_global_conf().getdir("trigger", "core_dump_location"), exist_ok=True) core_path = trigger.conf.get_core_path() logging.verbose("core_path: %(core_path)s", dict(core_path=core_path)) with suppress(OSError): logging.debug("attempting to delete old coredump at %(core_path)s", dict(core_path=core_path)) os.remove(core_path)
def add_programs_compile(compiler: Compiler) -> None: """ For all programs, add them to the compiler run list and register a plugin call for them :param compiler: the compiler to use """ for program_name in get_global_conf().getlist("install", "programs"): program = Program(program_name, RESOURCES_MANAGER.Lock(), RESOURCES_MANAGER.Event()) function_name = "test_5{}_{}_{}_{}wllvm_{}".format( bound_value(compiler.priority), compiler.package, compiler.name, "no-" if not compiler.bitcode else "", program.name, ) setattr(TestRunner, function_name, lambda x, comp=compiler, prog=program: TestRunner.compile(x, comp, prog)) setattr(getattr(TestRunner, function_name), "__name__", function_name) for plugin in compiler.plugins: add_plugin_run(compiler, program, plugin)
def compile(self, _compiler_: Compiler, _program_: Program) -> None: """ Compiles and installs the given program with the given compiler :param _compiler_: the compiler to use :param _program_: the program to compile """ _compiler_.is_configured.wait() try: with TestRunner.EnvManager(_compiler_, _program_.name): error = main([_program_.name], True, 1) self.assertFalse( error, "The program {} failed to compile with {}".format( _program_.name, get_global_conf().get("install", "compiler") ), ) # Checks that bitcode was indeed created at the correct place if _compiler_.bitcode: conf = get_trigger_conf(_program_.name) self.assertTrue(os.path.exists(conf.get_executable() + ".bc")) finally: _program_.is_installed.set()
def load_plugins() -> None: """ Loads all enabled plugin modules """ for plugin in get_global_conf().getlist("plugins", "enabled_plugins"): importlib.import_module("plugins.{}".format(plugin))
#!/usr/bin/env python # coding=utf-8 """ Main module for tests. All tests should inherit this, in order to implement the base necessary functions to have """ __author__ = 'Benjamin Schubert, [email protected]' import os from lib.parsers.configuration import get_global_conf TEST_DIRECTORY = os.path.join(get_global_conf().getdir("trigger", "default_directory"), "tests-results") SAVE_DIRECTORY = os.path.join(TEST_DIRECTORY, "saved")
def expected_results(self) -> int: """ The number of positive results awaited """ return get_global_conf().getint("benchmark", "wanted_results")
def maximum_tries(self) -> int: """ The maximum number of tries to do before declaring a failure """ return get_global_conf().getint("benchmark", "maximum_tries")
def kept_runs(self) -> int: """ The total number of run kept """ return get_global_conf().getint("benchmark", "kept_runs")