new class Completer for simplifying all the code that tries to monitor
[tests.git] / system / TestSliceSfa.py
1 # Thierry Parmentelat <thierry.parmentelat@inria.fr>
2 # Copyright (C) 2010 INRIA 
3 #
4
5 import time
6 from datetime import datetime, timedelta
7
8 import utils
9 from TestNode import TestNode
10 from TestUser import TestUser
11 from TestBoxQemu import TestBoxQemu
12 from TestSsh import TestSsh
13
14 from Completer import Completer, CompleterTask
15 from TestSlice import CompleterTaskSshSlice
16
17 class TestSliceSfa:
18
19     def __init__ (self, test_auth_sfa, slice_spec):
20         self.test_auth_sfa=test_auth_sfa
21         self.slice_spec=slice_spec
22         # shortcuts
23         self.test_plc=self.test_auth_sfa.test_plc
24
25     def qualified(self,name): return self.test_auth_sfa.qualified(name)
26     def hrn (self): return self.qualified(self.slice_spec['name'])
27     def sfi_path (self): return self.test_auth_sfa.sfi_path()
28
29     # send back up to the TestAuthSfa
30     def rspec_style (self): return self.test_auth_sfa.rspec_style()
31     def sfi_pi(self,*args,**kwds): return self.test_auth_sfa.sfi_pi(*args, **kwds)
32     def sfi_user(self,*args,**kwds): return self.test_auth_sfa.sfi_user(*args, **kwds)
33
34     def discover_option(self):
35         if self.rspec_style()=='pg': return "-r protogeni"
36         else:                        return "-r sfa"
37
38     # those are step names exposed as methods of TestPlc, hence the _sfa
39
40     # needs to be run as pi
41     def sfa_add_slice(self,options):
42         "run sfi add (on Registry)"
43         sfi_command="add"
44         sfi_command += " --type slice"
45         sfi_command += " --xrn %s"%self.hrn()
46         for opt in self.slice_spec['add_options']:
47             sfi_command += " %s"%(opt)
48         return self.test_plc.run_in_guest(self.sfi_pi(sfi_command))==0
49
50     def sfa_renew_slice(self, options):
51         "run sfi renew (on Aggregates)"
52         too_late =  datetime.now() + timedelta(weeks=52)
53         one_month = datetime.now() + timedelta(weeks=4)
54         # we expect this to fail on too long term attemps, but to succeed otherwise
55         overall=True
56         for ( renew_until, expected) in [ (too_late, False), (one_month, True) ] :
57             sfi_command="renew"
58             sfi_command += " %s"%self.hrn()
59             sfi_command += " %s"%renew_until.strftime("%Y-%m-%d")
60             succeeded = self.test_plc.run_in_guest(self.sfi_user(sfi_command))==0
61             if succeeded!=expected:
62                 utils.header ("Expecting success=%s, got %s"%(expected,succeeded))
63                 # however it turns out sfi renew always returns fine....
64                 #overall=False
65             # so for helping manual checks:
66             sfi_command="show -k hrn -k expires %s"%self.hrn()
67             self.test_plc.run_in_guest(self.sfi_user(sfi_command))
68         return overall
69
70     # helper - filename to store a given result
71     def _resname (self,name,ext): return "%s.%s"%(name,ext)
72     def adfile (self): return self._resname("ad","rspec")
73     def reqfile (self): return self._resname("req","rspec")
74     def nodefile (self): return self._resname("nodes","txt")
75     
76     # run as user
77     def sfa_discover(self,options):
78         "discover resources into resouces_in.rspec"
79         return self.test_plc.run_in_guest(self.sfi_user(\
80                 "resources %s -o %s/%s"% (self.discover_option(),self.sfi_path(),self.adfile())))==0
81
82     # run sfi create as a regular user
83     def sfa_create_slice(self,options):
84         "run sfi create (on SM) - 1st time"
85         commands=[
86             "sfiListNodes.py -i %s/%s -o %s/%s"%(self.sfi_path(),self.adfile(),self.sfi_path(),self.nodefile()),
87             "sfiAddSliver.py -i %s/%s -n %s/%s -o %s/%s"%\
88                 (self.sfi_path(),self.adfile(),self.sfi_path(),self.nodefile(),self.sfi_path(),self.reqfile()),
89             self.sfi_user("create %s %s"%(self.hrn(),self.reqfile())),
90             ]
91         for command in commands:
92             if self.test_plc.run_in_guest(command)!=0: return False
93         return True
94
95     def plc_name (self):
96         return "%s_%s"%(self.test_auth_sfa.login_base,self.slice_spec['name'])
97
98     # all local nodes in slice ?
99     def sfa_check_slice_plc (self,options):
100         "check sfa_create_slice at the plcs - all local nodes should be in slice"
101         slice=self.test_plc.apiserver.GetSlices(self.test_plc.auth_root(), self.plc_name())[0]
102         nodes=self.test_plc.apiserver.GetNodes(self.test_plc.auth_root(), {'peer_id':None})
103         result=True
104         for node in nodes: 
105             if node['node_id'] in slice['node_ids']:
106                 utils.header("local node %s found in slice %s"%(node['hostname'],slice['name']))
107             else:
108                 utils.header("ERROR - local node %s NOT FOUND in slice %s"%(node['hostname'],slice['name']))
109                 result=False
110         return result
111
112     # actually the same for now
113     def sfa_update_slice(self,options):
114         "run sfi create (on SM) on existing object"
115         return self.sfa_create_slice(options)
116
117     # run as pi
118     def sfa_delete_slice(self,options):
119         "run sfi delete"
120         self.test_plc.run_in_guest(self.sfi_pi("delete %s"%(self.hrn(),)))
121         return self.test_plc.run_in_guest(self.sfi_pi("remove -t slice %s"%(self.hrn(),)))==0
122
123     def locate_private_key(self):
124         return self.test_plc.locate_private_key_from_key_names ( [ self.slice_spec['key_name'] ] )
125
126     # check the resulting sliver
127     def ssh_slice_sfa(self,options,timeout_minutes=40,silent_minutes=0,period_seconds=15):
128         "tries to ssh-enter the SFA slice"
129         timeout  = timedelta(minutes=timeout_minutes)
130         graceout = timedelta(minutes=silent_minutes)
131         period   = timedelta(seconds=period_seconds)
132         # locate a key
133         private_key=self.locate_private_key()
134         if not private_key :
135             utils.header("WARNING: Cannot find a valid key for slice %s"%self.name())
136             return False
137         command="echo hostname ; hostname; echo id; id; echo uname -a ; uname -a"
138         
139         tasks=[]
140         slicename=self.slice_spec['name']
141         dry_run = getattr(options,'dry_run',False)
142         for nodename in self.slice_spec['nodenames']:
143             (site_spec,node_spec) = self.test_plc.locate_node(nodename)
144             tasks.append( CompleterTaskSshSlice(self.test_plc,node_spec['node_fields']['hostname'],
145                                                 slicename,private_key,command,expected=True,dry_run=dry_run))
146         return Completer (tasks).run (timeout, graceout, period)