X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=qaapi%2Fqa%2FNodes.py;h=3c19a35c95b0ae964e8a15f32b4d959c478351be;hb=4857039877f0316276a6d918e4e540aed4983c74;hp=d1375e86920c655b0d4c202d8b750649fd401a4b;hpb=527c043bb1c9dfb1ca76a54ffe082b56cbd93674;p=tests.git diff --git a/qaapi/qa/Nodes.py b/qaapi/qa/Nodes.py index d1375e8..3c19a35 100644 --- a/qaapi/qa/Nodes.py +++ b/qaapi/qa/Nodes.py @@ -1,23 +1,33 @@ import utils import os -from Remote import Remote +import re +import time +from time import sleep +from Remote import Remote, VRemote from Table import Table +from logger import Logfile -class Node(dict, Remote): +class Node(dict, VRemote): fields = { - 'plc': None, - 'hostname': None, # Node Hostname - 'host': 'localhost', # host where node lives - 'redir_port': None, # Port on host where ssh is redirected to virtual node - 'vserver': None, # vserver where this node lives - 'type': 'vm', # type of node - 'nodenetworks': [], # node networks + 'plcs': ['TestPLC'], + 'hostname': None, # Node Hostname + 'host': 'localhost', # host where node lives + 'redir_ssh_port': '51022', # Port on host where ssh is redirected to virtual node + 'vserver': None, # vserver where this node lives + 'type': 'vm', # type of node + 'model': '/minhw', + 'nodegroups': [], + 'nodenetworks': [], # node networks 'homedir': '/var/VirtualMachines/', - 'rootkey': None # path to root ssh key + 'rootkey': '/etc/planetlab/root_ssh_key.rsa', # path to root ssh key + 'host_rootkey': None, # path to host root ssh key + 'tests_dir': '/usr/share/tests/', + 'tests': [] # which test to run. None or empty list means run all } - + + def __init__(self, config, fields = {}): # XX Filter out fields not specified in fields @@ -25,12 +35,141 @@ class Node(dict, Remote): # Merge defined fields with defaults self.update(fields) - self.config = config - -class Nodes(list, Table): + self.config = config + self.__init_logfile__() + + get_host_command = Remote.get_remote_command + get_host_scp_command = Remote.get_scp_command + + def __init_logfile__(self, filename = None): + if not filename: + filename = '%s/%s.log' % (self.config.logdir, self['hostname']) + self.logfile = Logfile(filename) + + def rotate_logfile(self): + if os.path.isfile(self.logfile.filename): + (status, output) = utils.commands("ls %s*" % self.logfile.filename) + files = output.split("\n") + files.sort() + lastfile = files[-1:][0] + index = lastfile.split(self.logfile.filename)[1].replace(".", "") + if not index: + index = "1" + else: + index = str(int(index) + 1) + utils.commands("mv %s %s.%s" % (self.logfile.filename, self.logfile.filename, index)) + + def get_host_ip(self): + self.__init_logfile__() + + # Used to get ip of this nodes host + ip_command = "/sbin/ifconfig eth0 | grep -v inet6 | grep inet | awk '{print$2;}'" + (status, output) = self.host_commands(ip_command) + ip = re.findall(r'[0-9\.]+', output)[0] + return ip + + def is_ready(self, timeout=30): + # Node is considered ready when Node Manager has started avuseradd processes have stopped + log = self.config.logfile + class test: + def __init__(self, name, description, system, cmd, check, inverse = False, logfile = log): + self.system = system + self.cmd = cmd + self.check = check + self.name = name + self.description = description + self.inverse = inverse + self.logfile = logfile + + def run(self, logfile, verbose = True): + if verbose: + utils.header(self.description, logfile = self.logfile) + (status, output) = self.system(self.cmd) + if self.inverse and output.find(self.check) == -1: + if verbose: utils.header("%s Passed Test" % self.name, logfile = self.logfile) + return True + elif not self.inverse and output and output.find(self.check) -1: + if verbose: utils.header("%s Passed Test" % self.name, logfile = self.logfile) + return True + + if verbose: utils.header("%s Failed Test" % self.name, logfile = self.logfile) + return False + + ready = False + start_time = time.time() + end_time = start_time + 60 * timeout + vcheck_cmd = "ps -elfy | grep vuseradd | grep -v grep" + grep_cmd = "grep 'Starting Node Manager' %s" % self.logfile.filename + tests = { + '1': test("NodeManager", "Checking if NodeManager has started", utils.commands, grep_cmd, "OK", logfile = self.config.logfile), + '2': test("vuseradd", "Checking if vuseradd is done", self.commands, vcheck_cmd, "vuseradd", True, logfile = self.config.logfile) + } + + while time.time() < end_time and ready == False: + # Run tests in order + steps = tests.keys() + steps.sort() + results = {} + for step in steps: + test = tests[step] + results[step] = result = test.run(self.config.verbose) + if not result: break + + # Check results. We are ready if all passed + if not set(results.values()).intersection([False, None]): + utils.header("%s is ready" % (self['hostname'])) + ready = True + else: + if self.config.verbose: + utils.header("%s not ready. Waiting 30 seconds. %s seconds left" % \ + (self['hostname'], int(end_time - time.time())) ) + time.sleep(30) + + return ready + + def download_testscripts(self): + node_tests_dir = self['tests_dir'] + self.commands("mkdir %(node_tests_dir)s" % locals(), fatal = False) + (archive_filename, archive_path) = self.config.archive_node_tests() + self.scp_to(archive_path, node_tests_dir) + + # Extract tests archive + tarx_cmd = "cd %(node_tests_dir)s && tar -xzm -f %(archive_filename)s" % locals() + print >> self.logfile, tarx_cmd + self.popen(tarx_cmd) + + # Make tests executable + # XX Should find a better way to do this + chmod_cmd = "cd %s/node && chmod -R 755 * " % (node_tests_dir) + print >> self.logfile, chmod_cmd + self.popen(chmod_cmd) + + def slice_commands(self, command, slice, key = None): + if key is None: + print self.config.slices + # get a valid key + persons = self.config.slices[slice]['persons'] + if not persons: raise Exception + name, domain = persons[0].split('@') + key = "/%s/%s" % (self.config.KEYS_PATH, name) + + return VRemote.slice_commands(command, slice, key, False) + + def get_logs(self, files = None): + + hostname = self['hostname'] + logs_dir = '/var/log/' + dest = "%s/%s-var.log/" % (self.logfile.dir, hostname) + try: os.mkdir(dest) + except: pass + #utils.commands('rm -Rf %(dest)s/*' % locals()) + self.scp_from(logs_dir, dest, recursive = True) + + +class Nodes(Table): def __init__(self, config, nodes): nodelist = [Node(config, node) for node in nodes] - list.__init__(self, nodelist) + Table.__init__(self, nodelist) self.config = config