X-Git-Url: http://git.ipfire.org/?p=nitsi.git;a=blobdiff_plain;f=src%2Fnitsi%2Ftest.py;h=9cc1188c2b1bdb09144af37055b0eecb1758104e;hp=1f7728f2f3b4747c40e5960b72b64a8e4abe2583;hb=aadbafc3e29c99e76174d3c3218be76268881ad8;hpb=4cbb829aec6393925475763f5fa9ee5cd341ddc4 diff --git a/src/nitsi/test.py b/src/nitsi/test.py index 1f7728f..9cc1188 100755 --- a/src/nitsi/test.py +++ b/src/nitsi/test.py @@ -1,18 +1,13 @@ #!/usr/bin/python3 - +import configparser import libvirt - +import logging import os - -import configparser - import time -from nitsi.virtual_environ import virtual_environ -from nitsi.recipe import recipe - -import logging +from . import recipe +from . import virtual_environ logger = logging.getLogger("nitsi.test") @@ -21,49 +16,131 @@ class TestException(Exception): def __init__(self, message): self.message = message -class test(): - def __init__(self, path, log_path): - try: - self.path = os.path.abspath(path) - self.log = logger.getChild(os.path.basename(self.path)) - except BaseException as e: - logger.error("Could not get absolute path") +class Test(): + def __init__(self, log_path, dir=None, recipe_file=None, settings_file=None, cmd_settings=None): + # init settings var + self.settings = {} - self.log.debug("Path of this test is: {}".format(self.path)) + # Set default values for the settings dict + self.settings["name"] = "" + self.settings["description"] = "" + self.settings["copy_from"] = None + self.settings["copy_to"] = None + self.settings["virtual_environ_path"] = None + self.cmd_settings = cmd_settings self.log_path = log_path - self.settings_file = "{}/settings".format(self.path) - if not os.path.isfile(self.settings_file): - self.log.error("No such file: {}".format(self.settings_file)) + # Init all vars with None + self.settings_file = None + self.recipe_file = None + self.path = None + + # We need at least a path to a recipe file or a dir to a test + if not dir and not recipe: + raise TestException("Did not get a path to a test or to a recipe file") + + # We cannot decide which to use when we get both + if (dir and recipe_file) or (dir and settings_file): + raise TestException("Get dir and path to recipe or settings file") + + if dir: + try: + if not os.path.isabs(dir): + self.path = os.path.abspath(dir) + except BaseException as e: + logger.error("Could not get absolute path") + raise e + + logger.debug("Path of this test is: {}".format(self.path)) - self.recipe_file = "{}/recipe".format(self.path) - if not os.path.isfile(self.recipe_file): - self.log.error("No such file: {}".format(self.recipe_file)) + self.recipe_file = "{}/recipe".format(self.path) + self.settings_file = "{}/settings".format(self.path) + + if recipe_file: + if not os.path.isabs(recipe_file): + self.recipe_file = os.path.abspath(recipe_file) + else: + self.recipe_file = recipe_file + + if settings_file: + if not os.path.isabs(settings_file): + self.settings_file = os.path.abspath(settings_file) + else: + self.settings_file = settings_file + + # We can also go on without a settings file + if self.settings_file: + if not os.path.isfile(self.settings_file): + logger.error("No such file: {}".format(self.settings_file)) + raise TestException("No settings file found") + + # os.path.isfile fails if self.recipe_file is None so we need to catch exceptions here + try: + if not (self.recipe_file or os.path.isfile(self.recipe_file)): + logger.error("No such file: {}".format(self.recipe_file)) + raise TestException("No recipe file found") + except BaseException: + pass + + + # Init logging + if dir: + self.log = logger.getChild(os.path.basename(self.path)) + + if recipe: + self.log = logger.getChild(os.path.basename(self.recipe_file)) def read_settings(self): - self.config = configparser.ConfigParser() - self.config.read(self.settings_file) - self.name = self.config["DEFAULT"]["Name"] - self.description = self.config["DEFAULT"]["Description"] - self.copy_to = self.config["DEFAULT"]["Copy_to"] - self.copy_from = self.config["DEFAULT"]["Copy_from"] - self.copy_from = self.copy_from.split(",") - - tmp = [] - for file in self.copy_from: - file = file.strip() - file = os.path.normpath(self.path + "/" + file) - tmp.append(file) - - self.copy_from = tmp - - self.virtual_environ_name = self.config["VIRTUAL_ENVIRONMENT"]["Name"] - self.virtual_environ_path = self.config["VIRTUAL_ENVIRONMENT"]["Path"] - self.virtual_environ_path = os.path.normpath(self.path + "/" + self.virtual_environ_path) + if self.settings_file: + self.log.debug("Going to read all settings from the ini file") + try: + self.config = configparser.ConfigParser() + self.config.read(self.settings_file) + except BaseException as e: + self.log.error("Failed to parse the config") + raise e + + self.settings["name"] = self.config.get("GENERAL","name", fallback="") + self.settings["description"] = self.config.get("GENERAL", "description", fallback="") + self.settings["copy_to"] = self.config.get("GENERAL", "copy_to", fallback=None) + self.settings["copy_from"] = self.config.get("GENERAL", "copy_from", fallback=None) + self.settings["virtual_environ_path"] = self.config.get("VIRTUAL_ENVIRONMENT", "path", fallback=None) + + if not self.settings["virtual_environ_path"]: + self.log.error("No path for virtual environment found.") + raise TestException("No path for virtual environment found.") + + self.settings["virtual_environ_path"] = os.path.normpath(self.path + "/" + self.settings["virtual_environ_path"]) + + # Parse copy_from setting + if self.settings["copy_from"]: + self.log.debug("Going to parse the copy_from setting.") + self.settings["copy_from"] = self.settings["copy_from"].split(",") + + tmp = [] + for file in self.settings["copy_from"]: + file = file.strip() + # If file is empty we do not want to add it to the list + if not file == "": + # If we get an absolut path we do nothing + # If not we add self.path to get an absolut path + if not os.path.isabs(file): + file = os.path.normpath(self.path + "/" + file) + + # We need to check if file is a valid file or dir + if not (os.path.isdir(file) or os.path.isfile(file)): + raise TestException("'{}' is not a valid file nor a valid directory".format(file)) + + self.log.debug("'{}' will be copied into all images".format(file)) + tmp.append(file) + + self.settings["copy_from"] = tmp + + def virtual_environ_setup(self): - self.virtual_environ = virtual_environ(self.virtual_environ_path) + self.virtual_environ = virtual_environ.Virtual_environ(self.settings["virtual_environ_path"]) self.virtual_networks = self.virtual_environ.get_networks() @@ -77,7 +154,9 @@ class test(): for name in self.virtual_environ.machine_names: self.virtual_machines[name].define() self.virtual_machines[name].create_snapshot() - self.virtual_machines[name].copy_in(self.copy_from, self.copy_to) + # We can only copy files when we know which and to which dir + if self.settings["copy_from"] and self.settings["copy_to"]: + self.virtual_machines[name].copy_in(self.settings["copy_from"], self.settings["copy_to"]) self.virtual_machines[name].start() # Time to which all serial output log entries are relativ @@ -86,9 +165,9 @@ class test(): # Number of chars of the longest machine name longest_machine_name = self.virtual_environ.longest_machine_name - self.log.debug("Try to login on all machines") + self.log.info("Try to login on all machines") for name in self.virtual_environ.machine_names: - self.log.debug("Try to login on {}".format(name)) + self.log.info("Try to login on {}".format(name)) self.virtual_machines[name].login("{}/test.log".format(self.log_path), log_start_time=log_start_time, longest_machine_name=longest_machine_name) @@ -96,7 +175,7 @@ class test(): def load_recipe(self): self.log.info("Going to load the recipe") try: - self.recipe = recipe(self.recipe_file) + self.recipe = recipe.Recipe(self.recipe_file, machines=self.virtual_environ.machine_names) for line in self.recipe.recipe: self.log.debug(line) @@ -118,12 +197,18 @@ class test(): def virtual_environ_stop(self): for name in self.virtual_environ.machine_names: - self.virtual_machines[name].shutdown() - self.virtual_machines[name].revert_snapshot() - self.virtual_machines[name].undefine() + # We just catch exception here to avoid + # that we stop the cleanup process if only one command fails + try: + self.virtual_machines[name].shutdown() + self.virtual_machines[name].revert_snapshot() + self.virtual_machines[name].undefine() + except BaseException as e: + self.log.exception(e) for name in self.virtual_environ.network_names: - self.virtual_networks[name].undefine() - - + try: + self.virtual_networks[name].undefine() + except BaseException as e: + self.log.exception(e)