X-Git-Url: http://git.ipfire.org/?p=nitsi.git;a=blobdiff_plain;f=test.py;h=2b26e6815cfe09440eb36127715f0f6984e16bb7;hp=d5be079ad1d5f72b78e180c077bd636e3b899bb5;hb=14cd493f0bb7cfffe753b0575f1a4ac4a650a98e;hpb=0486853d7e847e551af0e5fd87f29a31ac20f597 diff --git a/test.py b/test.py index d5be079..2b26e68 100755 --- a/test.py +++ b/test.py @@ -14,6 +14,8 @@ import os import configparser +from disk import disk + class log(): def __init__(self, log_level): self.log_level = log_level @@ -74,6 +76,7 @@ class vm(): self.log.error("No such file: {}".format(self.image)) self.root_uid = root_uid + self.disk = disk(image) self.username = username self.password = password @@ -150,6 +153,15 @@ class vm(): def cmd(self, cmd): return self.serial_con.command(cmd) + def copy_in(self, fr, to): + try: + self.disk.mount(self.root_uid, "/") + self.disk.copy_in(fr, to) + except BaseException as e: + self.log.error(e) + finally: + self.disk.umount("/") + self.disk.close() class connection(): def __init__(self, device, username=None): @@ -408,10 +420,21 @@ class RecipeExeption(Exception): # Should read the test, check if the syntax are valid # and return tuples with the ( host, command ) structure class recipe(): - def __init__(self, path): + def __init__(self, path, circle=[]): self.log = log(4) self.recipe_file = path + self.path = os.path.dirname(self.recipe_file) + self.log.debug("Path of recipe is: {}".format(self.recipe_file)) self._recipe = None + self._machines = None + + self.in_recursion = True + if len(circle) == 0: + self.in_recursion = False + + self.circle = circle + self.log.debug(circle) + self.log.debug(self.circle) if not os.path.isfile(self.recipe_file): self.log.error("No such file: {}".format(self.recipe_file)) @@ -429,6 +452,16 @@ class recipe(): return self._recipe + @property + def machines(self): + if not self._machines: + self._machines = [] + for line in self._recipe: + if line[0] != "all" and line[0] not in self._machines: + self._machines.append(line[0]) + + return self._machines + def parse(self): self._recipe = [] i = 1 @@ -437,24 +470,55 @@ class recipe(): if len(raw_line) < 2: self.log.error("Error parsing the recipe in line {}".format(i)) raise RecipeExeption - cmd = raw_line[1] + cmd = raw_line[1].strip() raw_line = raw_line[0].strip().split(" ") if len(raw_line) == 0: self.log.error("Failed to parse the recipe in line {}".format(i)) raise RecipeExeption - elif len(raw_line) == 1: - if raw_line[0] == "": + + if raw_line[0].strip() == "": self.log.error("Failed to parse the recipe in line {}".format(i)) raise RecipeExeption - machine = raw_line[0] + + machine = raw_line[0].strip() + + if len(raw_line) == 2: + extra = raw_line[1].strip() + else: extra = "" - elif len(raw_line) == 2: - machine = raw_line[0] - extra = raw_line[1] - self._recipe.append((machine.strip(), extra.strip(), cmd.strip())) + # We could get a machine here or a include statement + if machine == "include": + path = cmd.strip() + path = os.path.normpath(self.path + "/" + path) + path = path + "/recipe" + if path in self.circle: + self.log.error("Detect import loop!") + raise RecipeExeption + self.circle.append(path) + recipe_to_include = recipe(path, circle=self.circle) + + if machine == "include": + self._recipe.extend(recipe_to_include.recipe) + else: + # Support also something like 'alice,bob: echo' + machines = machine.split(",") + for machine in machines: + self._recipe.append((machine.strip(), extra.strip(), cmd.strip())) i = i + 1 + if not self.in_recursion: + tmp_recipe = [] + for line in self._recipe: + if line[0] != "all": + tmp_recipe.append(line) + else: + for machine in self.machines: + tmp_recipe.append((machine.strip(), line[1], line[2])) + + self._recipe = tmp_recipe + + class test(): def __init__(self, path): @@ -479,6 +543,17 @@ class test(): 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"] @@ -499,6 +574,7 @@ 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) self.virtual_machines[name].start() self.log.debug("Try to login on all machines") @@ -515,12 +591,15 @@ class test(): def run_recipe(self): for line in self.recipe.recipe: return_value = self.virtual_machines[line[0]].cmd(line[2]) - if not return_value and line[1] == "": - self.log.error("Failed to execute command '{}' on {}".format(line[2],line[0])) + self.log.debug("Return value is: {}".format(return_value)) + if return_value != "0" and line[1] == "": + self.log.error("Failed to execute command '{}' on {}, return code: {}".format(line[2],line[0], return_value)) return False - elif return_value == True and line[1] == "!": - self.log.error("Succeded to execute command '{}' on {}".format(line[2],line[0])) + elif return_value == "0" and line[1] == "!": + self.log.error("Succeded to execute command '{}' on {}, return code: {}".format(line[2],line[0],return_value)) return False + else: + self.log.debug("Command '{}' on {} returned with: {}".format(line[2],line[0],return_value)) def virtual_environ_stop(self): for name in self.virtual_environ.machine_names: @@ -609,6 +688,11 @@ if __name__ == "__main__": currenttest.read_settings() currenttest.virtual_environ_setup() currenttest.load_recipe() - currenttest.virtual_environ_start() - currenttest.run_recipe() - currenttest.virtual_environ_stop() \ No newline at end of file + try: + currenttest.virtual_environ_start() + currenttest.run_recipe() + except BaseException as e: + print(e) + finally: + currenttest.virtual_environ_stop() +