default some value types
[tests.git] / qaapi / qa / Nodes.py
1 import utils
2 import os
3 import re
4 import time
5 from time import sleep
6 from Remote import Remote, VRemote
7 from Table import Table
8 from logger import Logfile
9
10
11 class Node(dict, VRemote):
12
13     fields = {
14         'plcs': ['TestPLC'],
15         'hostname': None,                             # Node Hostname
16         'host': 'localhost',                          # host where node lives
17         'redir_ssh_port': '51022',                    # Port on host where ssh is redirected to virtual node
18         'vserver': None,                              # vserver where this node lives
19         'type': 'vm',                                 # type of node
20         'model': '/minhw',
21         'nodegroups': [],
22         'nodenetworks': [],                           # node networks
23         'homedir': '/var/VirtualMachines/',
24         'rootkey': '/etc/planetlab/root_ssh_key.rsa', # path to root ssh key
25         'host_rootkey': None,                         # path to host root ssh key
26         'tests_dir': '/usr/share/tests/',
27         'tests': []                                   # which test to run. None or empty list means run all             
28         }
29
30     def __init__(self, config, fields = {}):
31
32         # XX Filter out fields not specified in fields
33         dict.__init__(self, self.fields)
34         
35         # Merge defined fields with defaults
36         self.update(fields)
37         self.config = config
38         self.__init_logfile__()
39         
40     get_host_command = Remote.get_remote_command
41     get_host_scp_command = Remote.get_scp_command
42
43     def __init_logfile__(self, filename = None):
44         if not filename:
45             filename = '%s/%s.log' % (self.config.logdir, self['hostname'])
46         self.logfile = Logfile(filename)
47
48     def rotate_logfile(self):
49         if os.path.isfile(self.logfile.filename):
50             (status, output) = utils.commands("ls %s*" % self.logfile.filename)
51             files = output.split("\n")
52             files.sort()
53             lastfile = files[-1:][0]
54             index = lastfile.split(self.logfile.filename)[1].replace(".", "")                                   
55             if not index:
56                 index = "1"
57             else:
58                 index = str(int(index) + 1)
59             utils.commands("mv %s %s.%s" % (self.logfile.filename, self.logfile.filename, index))
60                 
61     def get_host_ip(self):
62         self.__init_logfile__()
63
64         # Used to get ip of this nodes host
65         ip_command = "/sbin/ifconfig eth0 | grep -v inet6 | grep inet | awk '{print$2;}'" 
66         (status, output) = self.host_commands(ip_command)            
67         ip = re.findall(r'[0-9\.]+', output)[0] 
68         return ip
69
70     def is_ready(self, timeout=30):
71         # Node is considered ready when Node Manager has started avuseradd processes have stopped
72         log = self.config.logfile 
73         class test:
74             def __init__(self, name, description, system, cmd, check, inverse = False, logfile = log):
75                 self.system = system
76                 self.cmd = cmd
77                 self.check = check
78                 self.name = name
79                 self.description = description
80                 self.inverse = inverse
81                 self.logfile = logfile
82  
83             def run(self, logfile, verbose = True):
84                 if verbose:
85                     utils.header(self.description, logfile =  self.logfile)     
86                 (status, output) = self.system(self.cmd)
87                 if self.inverse and output.find(self.check) == -1:
88                     if verbose: utils.header("%s Passed Test" % self.name, logfile = self.logfile)
89                     return True
90                 elif not self.inverse and output and output.find(self.check)  -1:               
91                     if verbose: utils.header("%s Passed Test" % self.name, logfile = self.logfile)
92                     return True
93                 
94                 if verbose: utils.header("%s Failed Test" % self.name, logfile = self.logfile)
95                 return False
96
97         ready = False
98         start_time = time.time()
99         end_time = start_time + 60 * timeout
100         vcheck_cmd = "ps -elfy | grep vuseradd | grep -v grep"  
101         grep_cmd = "grep 'Starting Node Manager' %s" % self.logfile.filename
102         tests = {
103         '1':  test("NodeManager", "Checking if NodeManager has started", utils.commands, grep_cmd, "OK", logfile = self.config.logfile),
104         '2':  test("vuseradd", "Checking if vuseradd is done", self.commands, vcheck_cmd, "vuseradd", True, logfile = self.config.logfile)      
105         }
106         
107         while time.time() < end_time and ready == False:
108             # Run tests in order
109             steps = tests.keys()
110             steps.sort()
111             results = {}
112             for step in steps:
113                 test = tests[step]
114                 results[step] = result = test.run(self.config.verbose)
115                 if not result: break
116                                                 
117             # Check results. We are ready if all passed                 
118             if not set(results.values()).intersection([False, None]):
119                 ready = True
120             else:
121                 if self.config.verbose:
122                     utils.header("%s not ready. Waiting 30 seconds. %s seconds left" % \
123                                  (self['hostname'], int(end_time - time.time())) )
124                 time.sleep(30)                          
125
126         return ready  
127
128     def download_testscripts(self):
129         node_tests_dir = self['tests_dir']
130         (archive_filename, archive_path) = self.config.archive_node_tests()
131         self.scp_to(archive_path, node_tests_dir)   
132         
133         # Extract tests archive
134         tarx_cmd = "cd %(tests_dir)s && tar -xzm -f %(archive_filename)s" % locals()
135         print >> self.logfile, tarx_cmd
136         self.popen(tarx_cmd)    
137
138         # Make tests executable
139         # XX Should find a better way to do this
140         chmod_cmd = "cd %s/node && chmod -R 755 * " % (tests_dir )
141         print >> self.logfile, chmod_cmd
142         self.popen(chmod_cmd)
143  
144 class Nodes(Table):
145
146     def __init__(self, config, nodes):
147         nodelist = [Node(config, node) for node in nodes]
148         Table.__init__(self, nodelist)
149         self.config = config
150