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