From: Anil-Kumar Vengalil Date: Mon, 3 Aug 2009 14:35:55 +0000 (+0000) Subject: test modules for sfa X-Git-Tag: tests-4.3-3~5 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=6ea3c825254eefc7c9dc80f30745e5b200ba7b0b;p=tests.git test modules for sfa --- diff --git a/system/TestMain.py b/system/TestMain.py index 74dd39e..188b0ff 100755 --- a/system/TestMain.py +++ b/system/TestMain.py @@ -311,6 +311,9 @@ steps refer to a method in TestPlc or to a step_* module # do all steps on all plcs TRACE_FORMAT="TRACE: time=%(time)s plc=%(plcname)s step=%(stepname)s status=%(status)s force=%(force)s\n" for (stepname,method,force) in all_step_infos: + if stepname.endswith('sfa') and (self.options.personality != 'linux32' or self.options.pldistro != 'onelab' or self.options.fcdistro != 'f8'): + utils.header("SFA testing currently not enabled on this dist.") + continue for (spec,obj) in all_plcs: plcname=spec['name'] diff --git a/system/TestPlc.py b/system/TestPlc.py index 38f2cc0..cc844e4 100644 --- a/system/TestPlc.py +++ b/system/TestPlc.py @@ -17,6 +17,8 @@ from TestSliver import TestSliver from TestBox import TestBox from TestSsh import TestSsh from TestApiserver import TestApiserver +from TestSliceSfa import TestSliceSfa +from TestUserSfa import TestUserSfa # step methods must take (self) and return a boolean (options is a member of the class) @@ -62,6 +64,21 @@ def slice_mapper_options (method): actual.__doc__=method.__doc__ return actual +def slice_mapper_options_sfa (method): + def actual(self): + test_plc=self + overall=True + slice_method = TestSliceSfa.__dict__[method.__name__] + for slice_spec in self.plc_spec['sfa']['slices_sfa']: + site_spec = self.locate_site (slice_spec['sitename']) + test_site = TestSite(self,site_spec) + test_slice=TestSliceSfa(test_plc,test_site,slice_spec) + if not slice_method(test_slice,self.options): overall=False + return overall + # restore the doc text + actual.__doc__=method.__doc__ + return actual + SEP='' class TestPlc: @@ -76,6 +93,9 @@ class TestPlc: # better use of time: do this now that the nodes are taking off 'plcsh_stress_test', SEP, 'nodes_ssh_debug', 'nodes_ssh_boot', 'check_slice', 'check_initscripts', SEP, + 'install_sfa', 'configure_sfa', 'import_sfa', 'start_sfa', SEP, + 'setup_sfa', 'add_sfa', 'update_sfa', SEP, + 'view_sfa', 'check_slice_sfa', 'delete_sfa', 'stop_sfa', SEP, 'check_tcp', 'check_hooks', SEP, 'force_gather_logs', 'force_local_post', ] @@ -471,6 +491,8 @@ class TestPlc: 'PLC_MAIL_ENABLED', 'PLC_MAIL_SUPPORT_ADDRESS', 'PLC_DB_HOST', + 'PLC_DB_PASSWORD', + # Above line was added for integrating SFA Testing 'PLC_API_HOST', 'PLC_WWW_HOST', 'PLC_BOOT_HOST', @@ -917,6 +939,171 @@ class TestPlc: # populate runs the same utility without slightly different options # in particular runs with --preserve (dont cleanup) and without --check # also it gets run twice, once with the --foreign option for creating fake foreign entries + + ### install_sfa_rpm + def install_sfa(self): + "yum install sfa, sfa-plc and sfa-client" + if self.options.personality == "linux32": + arch = "i386" + elif self.options.personality == "linux64": + arch = "x86_64" + else: + raise Exception, "Unsupported personality %r"%self.options.personality + return \ + self.run_in_guest("yum -y install sfa")==0 and \ + self.run_in_guest("yum -y install sfa-client")==0 and \ + self.run_in_guest("yum -y install sfa-plc")==0 + ### + def configure_sfa(self): + "run sfa-config-tty" + tmpname='%s.sfa-config-tty'%(self.name()) + fileconf=open(tmpname,'w') + fileconf.write ('u\n') + for var in [ 'SFA_REGISTRY_ROOT_AUTH', + 'SFA_REGISTRY_LEVEL1_AUTH', + 'SFA_PLC_USER', + 'SFA_PLC_PASSWORD', + 'SFA_PLC_DB_HOST', + 'SFA_PLC_DB_USER', + 'SFA_PLC_DB_PASSWORD']: + fileconf.write ('%s\n'%(self.plc_spec['sfa'][var])) + fileconf.write('w\n') + fileconf.write('q\n') + fileconf.close() + utils.system('cat %s'%tmpname) + self.run_in_guest_piped('cat %s'%tmpname,'sfa-config-tty') + utils.system('rm %s'%tmpname) + return True + + def import_sfa(self): + "sfa-import-plc" + auth=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'] + self.run_in_guest('sfa-import-plc.py') + self.run_in_guest('cp /etc/sfa/authorities/%s/%s.pkey /etc/sfa/authorities/server.key'%(auth,auth)) + return True + + def start_sfa(self): + "service sfa start" + self.run_in_guest('service sfa start') + return True + + def setup_sfa(self): + "sfi client configuration" + dir_name=".sfi" + if os.path.exists(dir_name): + utils.system('rm -rf %s'%dir_name) + utils.system('mkdir %s'%dir_name) + file_name=dir_name + os.sep + 'fake-pi1.pkey' + fileconf=open(file_name,'w') + fileconf.write (self.plc_spec['keys'][0]['private']) + fileconf.close() + + file_name=dir_name + os.sep + 'sfi_config' + fileconf=open(file_name,'w') + SFI_AUTH=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH']+".main" + fileconf.write ("SFI_AUTH='%s'"%SFI_AUTH) + fileconf.write('\n') + SFI_USER=SFI_AUTH+'.fake-pi1' + fileconf.write ("SFI_USER='%s'"%SFI_USER) + fileconf.write('\n') + fileconf.write ("SFI_REGISTRY='http://localhost:12345/'") + fileconf.write('\n') + fileconf.write ("SFI_SM='http://localhost:12347/'") + fileconf.write('\n') + fileconf.close() + + file_name=dir_name + os.sep + 'person.xml' + fileconf=open(file_name,'w') + for record in self.plc_spec['sfa']['sfa_person_xml']: + person_record=record + fileconf.write(person_record) + fileconf.write('\n') + fileconf.close() + + file_name=dir_name + os.sep + 'slice.xml' + fileconf=open(file_name,'w') + for record in self.plc_spec['sfa']['sfa_slice_xml']: + slice_record=record + #slice_record=self.plc_spec['sfa']['sfa_slice_xml'] + fileconf.write(slice_record) + fileconf.write('\n') + fileconf.close() + + file_name=dir_name + os.sep + 'slice.rspec' + fileconf=open(file_name,'w') + slice_rspec='' + for (key, value) in self.plc_spec['sfa']['sfa_slice_rspec'].items(): + slice_rspec +=value + fileconf.write(slice_rspec) + fileconf.write('\n') + fileconf.close() + location = "root/" + remote="/vservers/%s/%s"%(self.vservername,location) + self.test_ssh.copy_abs(dir_name, remote, recursive=True) + + #utils.system('cat %s'%tmpname) + utils.system('rm -rf %s'%dir_name) + return True + + def add_sfa(self): + "run sfi.py add (on Registry) and sfi.py create (on SM) to form new objects" + test_plc=self + test_user_sfa=TestUserSfa(test_plc,self.plc_spec['sfa']) + success=test_user_sfa.add_user() + + for slice_spec in self.plc_spec['sfa']['slices_sfa']: + site_spec = self.locate_site (slice_spec['sitename']) + test_site = TestSite(self,site_spec) + test_slice_sfa=TestSliceSfa(test_plc,test_site,slice_spec) + success1=test_slice_sfa.add_slice() + success2=test_slice_sfa.create_slice() + return success and success1 and success2 + + def update_sfa(self): + "run sfi.py update (on Registry) and sfi.py create (on SM) on existing objects" + test_plc=self + test_user_sfa=TestUserSfa(test_plc,self.plc_spec['sfa']) + success1=test_user_sfa.update_user() + + for slice_spec in self.plc_spec['sfa']['slices_sfa']: + site_spec = self.locate_site (slice_spec['sitename']) + test_site = TestSite(self,site_spec) + test_slice_sfa=TestSliceSfa(test_plc,test_site,slice_spec) + success2=test_slice_sfa.update_slice() + return success1 and success2 + + def view_sfa(self): + "run sfi.py list and sfi.py show (both on Registry) and sfi.py slices and sfi.py resources (both on SM)" + auth=self.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'] + return \ + self.run_in_guest("sfi.py -d /root/.sfi/ list %s.main"%auth)==0 and \ + self.run_in_guest("sfi.py -d /root/.sfi/ show %s.main"%auth)==0 and \ + self.run_in_guest("sfi.py -d /root/.sfi/ slices")==0 and \ + self.run_in_guest("sfi.py -d /root/.sfi/ resources")==0 + + @slice_mapper_options_sfa + def check_slice_sfa(self): + "tries to ssh-enter the SFA slice" + pass + + def delete_sfa(self): + "run sfi.py delete (on SM), sfi.py remove (on Registry)" + test_plc=self + test_user_sfa=TestUserSfa(test_plc,self.plc_spec['sfa']) + success1=test_user_sfa.delete_user() + for slice_spec in self.plc_spec['sfa']['slices_sfa']: + site_spec = self.locate_site (slice_spec['sitename']) + test_site = TestSite(self,site_spec) + test_slice_sfa=TestSliceSfa(test_plc,test_site,slice_spec) + success2=test_slice_sfa.delete_slice() + + return success1 and success2 + + def stop_sfa(self): + "service sfa stop" + self.run_in_guest('service sfa stop') + return True + def populate (self): "creates random entries in the PLCAPI" # install the stress-test in the plc image diff --git a/system/TestResources.py b/system/TestResources.py index 93dd9f0..8e94dd9 100644 --- a/system/TestResources.py +++ b/system/TestResources.py @@ -30,6 +30,11 @@ class TestResources: except Exception,e: print 'Could not localize plcs','--',e,'--','exiting' sys.exit(1) + try: + plcs = self.localize_rspec(plcs,options) + except Exception,e: + print 'Could not localize RSpec','--',e,'--','exiting' + sys.exit(1) return plcs def localize_qemus (self,plcs,options): @@ -67,7 +72,7 @@ class TestResources: def localize_nodes (self, plcs, options): - + ip_pool = TestPoolIP (self.nodes_ip_pool(),options) network_dict = self.network_dict() @@ -100,7 +105,6 @@ class TestResources: def localize_plcs (self,plcs,options): utils.header ("Turning configuration into a vserver-based one for onelab") - ip_pool = TestPoolIP (self.plcs_ip_pool(),options) plc_counter=0 @@ -202,3 +206,14 @@ class TestResources: def trplc_list (self,plc): TrackerPlc(plc.options,instances=self.max_plcs()).list() return True + + def localize_rspec (self,plcs,options): + + utils.header ("Localize SFA Slice RSpec") + + for plc in plcs: + for site in plc['sites']: + for node in site['nodes']: + plc['sfa']['sfa_slice_rspec']['part4'] = node['node_fields']['hostname'] + + return plcs diff --git a/system/TestSliceSfa.py b/system/TestSliceSfa.py new file mode 100644 index 0000000..a4ad875 --- /dev/null +++ b/system/TestSliceSfa.py @@ -0,0 +1,109 @@ +import utils +import os, os.path +import datetime +import time + +from TestKey import TestKey +from TestUser import TestUser +from TestNode import TestNode +from TestSsh import TestSsh + +class TestSliceSfa: + + def __init__ (self,test_plc,test_site,slice_spec): + self.test_plc=test_plc + self.test_site=test_site + #self.slice_spec=plc_spec_sfa['slices_sfa'][0] + self.slice_spec=slice_spec + self.test_ssh=TestSsh(self.test_plc.test_ssh) + + def name(self): + return self.slice_spec['slice_fields']['name'] + + def locate_key(self): + for username,keyname in self.slice_spec['usernames']: + key_spec=self.test_plc.locate_key(keyname) + test_key=TestKey(self.test_plc,key_spec) + publickey=test_key.publicpath() + privatekey=test_key.privatepath() + if os.path.isfile(publickey) and os.path.isfile(privatekey): + found=True + return (found,privatekey) + + def add_slice(self): + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ add slice.xml")==0 + + def create_slice(self): + auth=self.test_plc.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'] + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ create %s.main.sfaslicea1 slice.rspec"%auth)==0 + + def update_slice(self): + auth=self.test_plc.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'] + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ create %s.main.sfaslicea1 slice.rspec"%auth)==0 + + def delete_slice(self): + auth=self.test_plc.plc_spec['sfa']['SFA_REGISTRY_ROOT_AUTH'] + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ delete %s.main.sfaslicea1"%auth) + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ remove -t slice %s.main.sfaslicea1"%auth)==0 + + def check_slice_sfa(self,options,timeout_minutes=40,silent_minutes=4,period=15): + timeout = datetime.datetime.now()+datetime.timedelta(minutes=timeout_minutes) + graceout = datetime.datetime.now()+datetime.timedelta(minutes=silent_minutes) + # locate a key + (found,remote_privatekey)=self.locate_key() + if not found : + utils.header("WARNING: Cannot find a valid key for slice %s"%self.name()) + return False + + # convert nodenames to real hostnames + slice_spec = self.slice_spec + restarted=[] + tocheck=[] + for nodename in slice_spec['nodenames']: + (site_spec,node_spec) = self.test_plc.locate_node(nodename) + tocheck.append(node_spec['node_fields']['hostname']) + + utils.header("checking ssh access into slice %s on nodes %r"%(self.name(),tocheck)) + utils.header("max timeout is %d minutes, silent for %d minutes (period is %s)"%\ + (timeout_minutes,silent_minutes,period)) + while tocheck: + for hostname in tocheck: + (site_spec,node_spec) = self.test_plc.locate_hostname(hostname) + date_test_ssh = TestSsh (hostname,key=remote_privatekey,username=self.name()) + if datetime.datetime.now() >= graceout: + utils.header('Trying to enter into slice %s@%s'%(self.name(),hostname)) + # this can be ran locally as we have the key + date = date_test_ssh.run("echo hostname ; hostname; echo id; id; echo uname -a ; uname -a")==0 + if date: + utils.header("Successfuly entered slice %s on %s"%(self.name(),hostname)) + tocheck.remove(hostname) + else: + # real nodes will have been checked once in case they're up - skip if not + if TestNode.is_real_model(node_spec['node_fields']['model']): + utils.header("WARNING : Checking slice %s on real node %s skipped"%(self.name(),hostname)) + tocheck.remove(hostname) + # nm restart after first failure, if requested + if options.forcenm and hostname not in restarted: + utils.header ("forcenm option : restarting nm on %s"%hostname) + restart_test_ssh=TestSsh(hostname,key="/etc/planetlab/root_ssh_key.rsa") + access=self.test_plc.run_in_guest(restart_test_ssh.actual_command('service nm restart')) + if (access==0): + utils.header('nm restarted on %s'%hostname) + else: + utils.header('Failed to restart nm on %s'%(hostname)) + restarted.append(hostname) + if not tocheck: + # we're done + return True + if datetime.datetime.now() > timeout: + for hostname in tocheck: + utils.header("FAILURE to ssh into %s@%s"%(self.name(),hostname)) + return False + # wait for the period + time.sleep (period) + # for an empty slice + return True diff --git a/system/TestUserSfa.py b/system/TestUserSfa.py new file mode 100644 index 0000000..a460f78 --- /dev/null +++ b/system/TestUserSfa.py @@ -0,0 +1,27 @@ +import os, sys, time +import xmlrpclib + +import utils + +class TestUserSfa: + + def __init__ (self,test_plc,plc_spec_sfa): + self.test_plc=test_plc + self.spec_sfa=plc_spec_sfa + + def name(self): + return self.user_spec['user_fields']['email'] + + def add_user (self): + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ add person.xml")==0 + + def update_user (self): + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ update person.xml")==0 + + def delete_user(self): + auth=self.spec_sfa['SFA_REGISTRY_ROOT_AUTH'] + return \ + self.test_plc.run_in_guest("sfi.py -d /root/.sfi/ remove -t user %s.main.sfafakeuser1"%auth)==0 + diff --git a/system/config_default.py b/system/config_default.py index 65451bb..60b786a 100644 --- a/system/config_default.py +++ b/system/config_default.py @@ -193,6 +193,7 @@ def plc (options,index) : 'PLC_MAIL_ENABLED':'true', 'PLC_MAIL_SUPPORT_ADDRESS' : 'thierry.parmentelat@sophia.inria.fr', 'PLC_DB_HOST' : 'deferred-myplc-hostname', + 'PLC_DB_PASSWORD' : 'test++', 'PLC_API_HOST' : 'deferred-myplc-hostname', 'PLC_WWW_HOST' : 'deferred-myplc-hostname', 'PLC_BOOT_HOST' : 'deferred-myplc-hostname', @@ -203,8 +204,71 @@ def plc (options,index) : 'initscripts': initscripts(options,index), 'slices' : slices(options,index), 'tcp_test' : tcp_tests(options,index), + 'sfa' : sfa(options,index), } +def sfa (options,index) : + if index==1: + root_auth='plc' + else: + root_auth='ple' + return { + 'SFA_REGISTRY_ROOT_AUTH' : root_auth, + 'SFA_REGISTRY_LEVEL1_AUTH' : '', + 'SFA_PLC_USER' : 'root@test.onelab.eu', + 'SFA_PLC_PASSWORD' : 'test++', + 'SFA_PLC_DB_HOST':'localhost', + 'SFA_PLC_DB_USER' : 'pgsqluser', + 'SFA_PLC_DB_PASSWORD' : 'test++', + 'slices_sfa' : slices_sfa(options,index), + 'sfa_slice_xml' : sfa_slice_xml(options,index), + 'sfa_person_xml' : sfa_person_xml(options,index), + 'sfa_slice_rspec' : sfa_slice_rspec(options,index) + } + +def slices_sfa (options,index): + return [ { 'slice_fields': {'name':'main_sfaslicea1', + 'url':'http://foo%d@foo.com'%index, + 'description':'SFA-testing', + 'max_nodes':2, + }, + 'usernames' : [ ('sfafakeuser1','key1') ], + 'nodenames' : all_nodenames(options,index), + 'sitename' : 'main', + }] + +def sfa_slice_xml(options,index): + if index==1: + hrn='plc.main.sfaslicea1' + researcher='plc.main.fake-pi1' + else: + hrn='ple.main.sfaslicea1' + researcher='ple.main.fake-pi1' + + return ["""%s"""%(hrn, researcher)] + +def sfa_person_xml(options,index): + if index==1: + hrn='plc.main.sfafakeuser1' + else: + hrn='ple.main.sfafakeuser1' + + return ["""%s20101piadminplc.main"""%(hrn,hrn,public_key)] + +def sfa_slice_rspec(options,index): + node_name='deferred' + if index==1: + netspec_name='\"plc\"' + else: + netspec_name='\"ple\"' + + return { 'part1' : """""" + } + def config (plc_specs,options): result=plc_specs for i in range (options.size):