before we switch to using new Shell.py
[plcapi.git] / TestPeers.py
1 #!/usr/bin/env python
2 ###
3 ##############################
4 ###
5 ### preparation / requirements
6 ###
7 ### two separate instances of myplc
8 ### for now they are located on the same box on lurch
9 ###
10 ### expectations :
11 ### your myplcs should more or less come out of the box, 
12 ### I prefer not to alter the default PLC_ROOT_USER value,
13 ### instead we create a PI account on the site_id=1
14 ###
15 ##############################
16
17 ### xxx todo
18 # check sites
19 # check persons
20
21 # support reloading without wiping everything off
22 # dunno how to do (defvar plc)
23
24 import getopt
25 import sys
26 import time
27
28 ## we use indexes 1 and 2 
29 try:
30     dir(plc)
31 except:
32     plc=[None,None,None]
33 ## the server objects
34 try:
35     dir(s)
36 except:
37     s=[None,None,None]
38 ## the authentication objects
39 ## our user
40 try:
41     dir(a)
42 except:
43     a=[None,None,None]
44 ## the builtin root user for bootstrapping
45 try:
46     dir(aa)
47 except:
48     aa=[None,None,None]
49
50 ####################
51 import xmlrpclib
52 import os
53
54 ####################
55 # predefined stuff
56 # number of 'system' persons
57 # builtin maint, local root, 2 persons for the peering
58 system_persons = 4
59 # among that, 1 gets refreshed - other ones have conflicting names
60 system_persons_cross = 1
61
62 system_slices_ids = (1,2)
63 def system_slices ():
64     return len(system_slices_ids)
65 def total_slices ():
66     return number_slices+system_slices()
67
68 # temporary - the myplc I use doesnt know about 'system' yet
69 def system_slivers ():
70 #    return len(system_slices_ids)
71     return 0
72 def total_slivers ():
73     return number_slices+system_slivers()
74
75 ####################
76 # set initial conditions
77 # actual persons_per_slice is min(number_persons,number_persons_per_slice)
78 # actual nodes_per_slice is min(number_nodes,number_nodes_per_slice)
79 # this is to prevent quadractic test times on big tests
80 def define_test (keys,sites,persons,nodes,slices,
81                  nodes_per_slice,persons_per_slice,fast_mode=None):
82     global number_keys, number_sites, number_persons, number_nodes, number_slices
83     global number_nodes_per_slice, number_persons_per_slice, fast_flag
84     number_keys=keys
85     number_sites = sites
86     number_persons=persons
87     number_nodes=nodes
88     number_slices=slices
89     number_nodes_per_slice=nodes_per_slice
90     number_persons_per_slice=persons_per_slice
91     if fast_mode is not None:
92         fast_flag=fast_mode
93
94 # when we run locally on a given peer
95 local_peer=None
96
97 def show_test():
98     print '%d keys, %d sites, %d persons, %d nodes & %d slices'%(
99         number_keys, number_sites,number_persons,number_nodes,number_slices)
100     print '%d keys/person, %d nodes/slice & %d persons/slice'%(
101         number_keys,number_nodes_per_slice,number_persons_per_slice)
102     print 'fast_flag',fast_flag
103     if local_peer is not None:
104         print 'Running locally on index %d'%local_peer
105
106 def mini():
107     define_test(1,1,1,1,1,1,1,True)
108     
109 def normal():
110     define_test (keys=2,sites=4,persons=4,nodes=5,slices=4,
111                  nodes_per_slice=5,persons_per_slice=8,fast_mode=False)
112
113 # use only 1 key in this case
114 big_factor=4
115 def big():
116     global number_sites, number_persons, number_nodes, number_slices
117     normal()
118     (number_sites,number_persons,number_nodes,number_slices) = [
119         big_factor * x for x in (number_sites,number_persons,number_nodes,number_slices)]
120     global number_keys
121     number_keys=1
122
123 huge_factor=100
124 def huge():
125     global number_sites, number_persons, number_nodes, number_slices
126     normal()
127     (number_sites,number_persons,number_nodes,number_slices) = [
128         huge_factor * x for x in (number_sites,number_persons,number_nodes,number_slices)]
129     global number_keys
130     number_keys=1
131     global number_persons_per_slice
132     number_persons_per_slice=2
133
134 # use mini test by default in interactive mode
135 mini()
136 #normal()
137
138 ####################
139 # argh, for login_name that doesn't accept digits
140 plain_numbers=['zero','one','two','three','four','five','six','seven','eight','nine','ten',
141                'eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen','twenty']
142 plain_digits=['a','b','c','d','e','f','g','h','i','j']
143 ####################
144 plc1={ 'plcname':'plc1 in federation',
145        'hostname':'lurch.cs.princeton.edu',
146        'url-format':'https://%s:443/PLCAPI/',
147        'builtin-admin-id':'root@plc1.org',
148        'builtin-admin-password':'root',
149        'peer-admin-name':'peer1@planet-lab.org',
150        'peer-admin-password':'peer',
151        'node-format':'n1%02d.plc1.org',
152        'plainname' : 'one',
153        'site-format':'one%s',
154        'person-format' : 'user1-%d@plc1.org',
155        'key-format':'ssh-rsa 11key4plc11 user%d-key%d',
156        'person-password' : 'password1',
157        }
158 plc2={ 'plcname':'plc2 in federation',
159        'hostname':'planetlab-devbox.inria.fr',
160        'url-format':'https://%s:443/PLCAPI/',
161        'builtin-admin-id':'root@plc2.org',
162        'builtin-admin-password':'root',
163        'peer-admin-name':'peer2@planet-lab.org',
164        'peer-admin-password':'peer',
165        'node-format':'n2%02d.plc2.org',
166        'plainname' : 'two',
167        'site-format':'two%s',
168        'person-format' : 'user2-%d@plc2.org',
169        'key-format':'ssh-rsa 22key4plc22 user%d-key%d',
170        'person-password' : 'password2',
171        }
172
173 ####################
174 def peer_index(i):
175     return 3-i
176
177 def plc_name (i):
178     return plc[i]['plcname']
179
180 def site_name (i,n):
181     x=site_login_base(i,n)
182     return 'Site fullname '+x
183
184 def site_login_base (i,n):
185     # for huge
186     if number_sites<len(plain_numbers):
187         return plc[i]['site-format']%plain_numbers[n]
188     else:
189         string=''
190         while True:
191             quo=n/10
192             rem=n%10
193             string=plain_digits[rem]+string
194             if quo == 0:
195                 break
196             else:
197                 n=quo
198         return plc[i]['site-format']%string
199
200 def person_name (i,n):
201     return plc[i]['person-format']%n
202
203 def key_name (i,n,k):
204     return plc[i]['key-format']%(n,k)
205
206 def node_name (i,n):
207     return plc[i]['node-format']%n
208
209 def map_on_site (n):
210     result=(n%number_sites)
211     if (result==0):
212         result=number_sites
213     return result
214
215 def slice_name (i,n):
216     site_index=map_on_site(n)
217     return "%s_slice%d"%(site_login_base(i,site_index),n)
218
219 def sat_name (i):
220     return 'sat_%d'%i
221
222 # to have indexes start at 1
223 def myrange (n):
224     return range (1,n+1,1)
225
226 def message (*args):
227     print "====================",
228     print args
229     
230 ##########
231 def timer_start ():
232     global epoch,last_time
233     epoch = time.time()
234     last_time=epoch
235     print '+++ timer start'
236
237 def timer_show ():
238     global last_time
239     now=time.time()
240     print '+++ %.02f seconds ellapsed (%.02f)'%(now-epoch,now-last_time)
241     last_time=now
242
243 ####################
244 def test00_init (args=[1,2]):
245     timer_start()
246     global plc,s,a,aa
247     ## have you loaded this file already (support for reload)
248     if plc[1]:
249         pass
250     else:
251         plc=[None,plc1,plc2]
252         for i in args:
253             url=plc[i]['url-format']%plc[i]['hostname']
254             plc[i]['url']=url
255             s[i]=xmlrpclib.ServerProxy(url,allow_none=True)
256             print 'initializing s[%d]'%i,url
257             aa[i]={'Username':plc[i]['builtin-admin-id'],
258                    'AuthMethod':'password',
259                    'AuthString':plc[i]['builtin-admin-password'],
260                    'Role':'admin'}
261             print 'initialized aa[%d]'%i, aa[i]
262             a[i]={'Username':plc[i]['peer-admin-name'],
263                   'AuthMethod':'password',
264                   'AuthString':plc[i]['peer-admin-password'],
265                   'Role':'admin'}
266             print 'initialized a[%d]'%i, a[i]
267
268 def test00_print (args=[1,2]):
269     for i in args:
270         print 's[%d]'%i,s[i]
271         print 'aa[%d]'%i, aa[i]
272         print 'a[%d]'%i, a[i]
273
274 def check_nodes (el,ef,args=[1,2]):
275     for i in args:
276         # use a single request and sort afterwards for efficiency
277         # could have used GetNodes's scope as well
278         all_nodes = s[i].GetNodes(a[i])
279         n = len ([ x for x in all_nodes if x['peer_id'] is None])
280         f = len ([ x for x in all_nodes if x['peer_id'] is not None])
281         print '%02d: Checking nodes: got %d local (e=%d) & %d foreign (e=%d)'%(i,n,el,f,ef)
282         assert n==el
283         assert f==ef
284
285 def check_keys (el,ef,args=[1,2]):
286     for i in args:
287         # use a single request and sort afterwards for efficiency
288         # could have used GetKeys's scope as well
289         all_keys = s[i].GetKeys(a[i])
290         n = len ([ x for x in all_keys if x['peer_id'] is None])
291         f = len ([ x for x in all_keys if x['peer_id'] is not None])
292         print '%02d: Checking keys: got %d local (e=%d) & %d foreign (e=%d)'%(i,n,el,f,ef)
293         assert n==el
294         assert f==ef
295
296 def check_persons (el,ef,args=[1,2]):
297     for i in args:
298         # use a single request and sort afterwards for efficiency
299         # could have used GetPersons's scope as well
300         all_persons = s[i].GetPersons(a[i])
301         n = len ([ x for x in all_persons if x['peer_id'] is None])
302         f = len ([ x for x in all_persons if x['peer_id'] is not None])
303         print '%02d: Checking persons: got %d local (e=%d) & %d foreign (e=%d)'%(i,n,el,f,ef)
304         assert n==el
305         assert f==ef
306
307 # expected : local slices, foreign slices
308 def check_slices (els,efs,args=[1,2]):
309     for i in args:
310         ls=len(s[i].GetSlices(a[i],{'peer_id':None}))
311         fs=len(s[i].GetSlices(a[i],{'~peer_id':None}))
312         print '%02d: Checking slices: got %d local (e=%d) & %d foreign (e=%d)'%(i,ls,els,fs,efs)
313         assert els==ls
314         assert efs==fs
315
316 def show_nodes (i,node_ids):
317     # same as above
318     all_nodes = s[i].GetNodes(a[i],node_ids)
319     loc_nodes = filter (lambda n: n['peer_id'] is None, all_nodes)
320     for_nodes = filter (lambda n: n['peer_id'] is not None, all_nodes)
321
322     for message,nodes in [ ['LOC',loc_nodes], ['FOR',for_nodes] ] :
323         if nodes:
324             print '[%s:%d] : '%(message,len(nodes)),
325             for node in nodes:
326                 print node['hostname']+' ',
327             print ''
328
329 def check_slice_nodes (expected_nodes, is_local_slice, args=[1,2]):
330     for ns in myrange(number_slices):
331         check_slice_nodes_n (ns,expected_nodes, is_local_slice, args)
332
333 def check_slice_nodes_n (ns,expected_nodes, is_local_slice, args=[1,2]):
334     for i in args:
335         peer=peer_index(i)
336         if is_local_slice:
337             sname=slice_name(i,ns)
338             slice=s[i].GetSlices(a[i],{'name':[sname],'peer_id':None})[0]
339             message='local'
340         else:
341             sname=slice_name(peer,ns)
342             slice=s[i].GetSlices(a[i],{'name':[sname],'~peer_id':None})[0]
343             message='foreign'
344         print '%02d: %s slice %s (e=%d) '%(i,message,sname,expected_nodes),
345         slice_node_ids=slice['node_ids']
346         print 'on nodes ',slice_node_ids
347         show_nodes (i,slice_node_ids)
348         assert len(slice_node_ids)>=expected_nodes
349         if len(slice_node_ids) != expected_nodes:
350             print 'TEMPORARY'
351
352 # expected : nodes on local slice
353 def check_local_slice_nodes (expected, args=[1,2]):
354     check_slice_nodes(expected,True,args)
355
356 # expected : nodes on foreign slice
357 def check_foreign_slice_nodes (expected, args=[1,2]):
358     check_slice_nodes(expected,False,args)
359
360 def check_conf_files (args=[1,2]):
361     for nn in myrange(number_nodes):
362         check_conf_files_n (nn,args)
363
364 def check_conf_files_n (nn,args=[1,2]):
365     for i in args:
366         nodename=node_name(i,nn)
367         ndict= s[i].GetSlivers(a[i],[nodename])[0]
368         assert ndict['hostname'] == nodename
369         conf_files = ndict['conf_files']
370         print '%02d: %d conf_files in GetSlivers for node %s'%(i,len(conf_files),nodename)
371         for conf_file in conf_files:
372             print 'source=',conf_file['source'],'|',
373             print 'dest=',conf_file['dest'],'|',
374             print 'enabled=',conf_file['enabled'],'|',
375             print ''
376
377 import pprint
378 pp = pprint.PrettyPrinter(indent=3)
379
380 def check_slivers (esn,args=[1,2]):
381     for nn in myrange(number_nodes):
382         check_slivers_n (nn,esn,args)
383
384 # too verbose to check all nodes, let's check only the first one
385 def check_slivers_1 (esn,args=[1,2]):
386     check_slivers_n (1,esn,args)
387
388 def check_slivers_n (nn,esn,args=[1,2]):
389     for i in args:
390         nodename=node_name(i,nn)
391         ndict= s[i].GetSlivers(a[i],[nodename])[0]
392         assert ndict['hostname'] == nodename
393         slivers = ndict['slivers']
394         print '%02d: %d slivers (exp. %d) in GetSlivers for node %s'\
395               %(i,len(slivers),esn,nodename)
396         for sliver in slivers:
397             print '>>slivername = ',sliver['name']
398             pretty_printer.pprint(sliver)
399         assert len(slivers) == esn
400                 
401
402 ####################
403 def test00_admin_person (args=[1,2]):
404     global plc
405     for i in args:
406         email = plc[i]['peer-admin-name']
407         try:
408             p=s[i].GetPersons(a[i],[email])[0]
409             plc[i]['peer-admin-id']=p['person_id']
410         except:
411             person_id=s[i].AddPerson(aa[i],{'first_name':'Local', 
412                                             'last_name':'PeerPoint', 
413                                             'role_ids':[10],
414                                             'email':email,
415                                             'password':plc[i]['peer-admin-password']})
416             print '%02d:== created peer admin account %d, %s - %s'%(i,
417                                                                   person_id,plc[i]['peer-admin-name'],
418                                                                   plc[i]['peer-admin-password'])
419             plc[i]['peer-admin-id']=person_id
420
421 def test00_admin_enable (args=[1,2]):
422     for i in args:
423         s[i].AdmSetPersonEnabled(aa[i],plc[i]['peer-admin-id'],True)
424         s[i].AddRoleToPerson(aa[i],'admin',plc[i]['peer-admin-id'])
425         print '%02d:== enabled+admin on account %d:%s'%(i,plc[i]['peer-admin-id'],plc[i]['peer-admin-name'])
426
427 def test00_peer_person (args=[1,2]):
428     global plc
429     for i in args:
430         peer=peer_index(i)
431         email=plc[peer]['peer-admin-name']
432         try:
433             p=s[i].GetPersons(a[i],[email])[0]
434             plc[i]['peer_person_id']=p['person_id']
435         except:
436             person_id = s[i].AddPerson (a[i], {'first_name':'Peering(plain passwd)', 'last_name':plc_name(peer), 'role_ids':[3000],
437                                                'email':email,'password':plc[peer]['peer-admin-password']})
438             print '%02d:Created person %d as the peer person'%(i,person_id)
439             plc[i]['peer_person_id']=person_id
440
441 ####################
442 def test00_peer (args=[1,2]):
443     global plc
444     for i in args:
445         peer=peer_index(i)
446         peername = plc_name(peer)
447         try:
448             p=s[i].GetPeers (a[i], [peername])[0]
449             plc[i]['peer_id']=p['peer_id']
450         except:
451             peer_id=s[i].AddPeer (a[i], {'peername':peername,'peer_url':plc[peer]['url'],'person_id':plc[i]['peer_person_id']})
452             # NOTE : need to manually reset the encrypted password through SQL at this point
453             print '%02d:Created peer %d'%(i,peer_id)
454             plc[i]['peer_id']=peer_id
455             print "PLEASE manually set password for person_id=%d in DB%d"%(plc[i]['peer_person_id'],i)
456
457 def test00_peer_passwd (args=[1,2]):
458     for i in args:
459         # using an ad-hoc local command for now - never could get quotes to reach sql....
460         print "Attempting to set passwd for person_id=%d in DB%d"%(plc[i]['peer_person_id'],i),
461         retcod=os.system("ssh root@%s new_plc_api/person-password.sh %d"%(plc[i]['hostname'],plc[i]['peer_person_id']))
462         print '-> system returns',retcod
463     
464 # this one gets cached 
465 def get_peer_id (i):
466     try:
467         return plc[i]['peer_id']
468     except:
469         peername = plc_name (peer_index(i))
470         peer_id = s[i].GetPeers(a[i],[peername])[0]['peer_id']
471         plc[i]['peer_id'] = peer_id
472         return peer_id
473
474 ##############################
475 def test00_refresh (message,args=[1,2]):
476     print '=== refresh',message
477     timer_show()
478     for i in args:
479         print '%02d:== Refreshing peer'%(i),
480         retcod=s[i].RefreshPeer(a[i],get_peer_id(i))
481         keys=retcod.keys()
482         keys.sort()
483         print "Result: {",
484         for key in keys:
485             if "time_" not in key:
486                 print key,retcod[key],
487         print "}"
488         print "+++ ellapsed: {",
489         for key in keys:
490             if "time_" in key:
491                 print key,retcod[key],
492         print "}"
493         timer_show()
494
495 ####################
496 def test01_site (args=[1,2]):
497     for ns in myrange(number_sites):
498         test01_site_n (ns,True,args)
499
500 def test01_del_site (args=[1,2]):
501     for ns in myrange(number_sites):
502         test01_site_n (ns,False,args)
503
504 def test01_site_n (ns,add_if_true,args=[1,2]):
505     for i in args:
506         login_base = site_login_base (i,ns)
507         try:
508             site_id = s[i].GetSites(a[i],[login_base])[0]['site_id']
509             if not add_if_true:
510                 s[i].DeleteSite(a[i],site_id)
511                 print "%02d:== deleted site_id %d"%(i,site_id)
512         except:
513             if add_if_true:
514                 sitename=site_name(i,ns)
515                 abbrev_name="abbr"+str(i)
516                 max_slices = number_slices
517                 site_id=s[i].AddSite (a[i], {'name':plc_name(i),
518                                              'abbreviated_name': abbrev_name,
519                                              'login_base': login_base,
520                                              'is_public': True,
521                                              'url': 'http://%s.com/'%abbrev_name,
522                                              'max_slices':max_slices})
523                 ### max_slices does not seem taken into account at that stage
524                 s[i].UpdateSite(a[i],site_id,{'max_slices':max_slices})
525                 print '%02d:== Created site %d with max_slices=%d'%(i,site_id,max_slices)
526
527 ####################
528 def test02_person (args=[1,2]):
529     for np in myrange(number_persons):
530         test02_person_n (np,True,args)
531
532 def test02_del_person (args=[1,2]):
533     for np in myrange(number_persons):
534         test02_person_n (np,False,args)
535
536 def test02_person_n (np,add_if_true,args=[1,2]):
537     test02_person_n_ks (np, myrange(number_keys),add_if_true,args)
538
539 def test02_person_n_ks (np,nks,add_if_true,args=[1,2]):
540     for i in args:
541         email = person_name(i,np)
542         try:
543             person_id=s[i].GetPersons(a[i],[email])[0]['person_id']
544             if not add_if_true:
545                 s[i].DeletePerson(a[i],person_id)
546                 print "%02d:== deleted person_id %d"%(i,person_id)
547         except:
548             if add_if_true:
549                 password = plc[i]['person-password']
550                 person_id=s[i].AddPerson(a[i],{'first_name':'Your average', 
551                                                'last_name':'User%d'%np, 
552                                                'role_ids':[30],
553                                                'email':email,
554                                                'password': password })
555                 print '%02d:== created user account %d, %s - %s'%(i, person_id,email,password)
556                 for nk in nks:
557                     key=key_name(i,np,nk)
558                     s[i].AddPersonKey(aa[i],email,{'key_type':'ssh', 'key':key})
559                     print '%02d:== added key %s to person %s'%(i,key,email)
560
561 ####################
562 # retrieves node_id from hostname - checks for local nodes only
563 def get_local_node_id(i,nodename):
564     return s[i].GetNodes(a[i],{'hostname':nodename,'peer_id':None})[0]['node_id']
565
566 # clean all local nodes - foreign nodes are not supposed to be cleaned up manually
567 def clean_all_nodes (args=[1,2]):
568     for i in args:
569         print '%02d:== Cleaning all nodes'%i
570         loc_nodes = s[i].GetNodes(a[i],{'peer_id':None})
571         for node in loc_nodes:
572             print '%02d:==== Cleaning node %d'%(i,node['node_id'])
573             s[i].DeleteNode(a[i],node['node_id'])
574
575 def test03_node (args=[1,2]):
576     for nn in myrange(number_nodes):
577         test03_node_n (nn,args)
578
579 def test03_node_n (nn,args=[1,2]):
580     for i in args:
581         nodename = node_name(i,nn)
582         try:
583             get_local_node_id(i,nodename)
584         except:
585             login_base=site_login_base(i,map_on_site(nn))
586             n=s[i].AddNode(a[i],login_base,{'hostname': nodename})
587             print '%02d:== Added node %d %s'%(i,n,node_name(i,nn))
588
589 def test02_delnode (args=[1,2]):
590     for nn in myrange(number_nodes):
591         test02_delnode_n (nn,args)
592
593 def test02_delnode_n (nn,args=[1,2]):
594     for i in args:
595         nodename = node_name(i,nn)
596         node_id = get_local_node_id (i,nodename)
597         retcod=s[i].DeleteNode(a[i],nodename)
598         print '%02d:== Deleted node %d, returns %s'%(i,node_id,retcod)
599
600 ####################
601 def clean_all_slices (args=[1,2]):
602     for i in args:
603         print '%02d:== Cleaning all slices'%i
604         for slice in s[i].GetSlices(a[i],{'peer_id':None}):
605             slice_id = slice['slice_id']
606             if slice_id not in system_slices_ids:
607                 print '%02d:==== Cleaning slice %d'%(i,slice_id)
608                 s[i].DeleteSlice(a[i],slice_id)
609
610 def test04_slice (args=[1,2]):
611     for n in myrange(number_slices):
612         test04_slice_n (n,args)
613
614 def test04_slice_n (ns,args=[1,2]):
615     for i in args:
616         peer=peer_index(i)
617         plcname=plc_name(i)
618         slicename=slice_name(i,ns)
619         max_nodes=number_nodes
620         try:
621             s[i].GetSlices(a[i],[slicename])[0]
622         except:
623             slice_id=s[i].AddSlice (a[i],{'name':slicename,
624                                           'description':'slice %s on %s'%(slicename,plcname),
625                                           'url':'http://planet-lab.org/%s'%slicename,
626                                           'max_nodes':max_nodes,
627                                           'instanciation':'plc-instantiated',
628                                           })
629             print '%02d:== created slice %d - max nodes=%d'%(i,slice_id,max_nodes)
630             actual_persons_per_slice = min (number_persons,number_persons_per_slice)
631             for np in myrange(actual_persons_per_slice):
632                 email = person_name (i,np)
633                 retcod = s[i].AddPersonToSlice (a[i], email, slicename)
634                 print '%02d:== Attached person %s to slice %s'%(i,email,slicename)
635         
636
637 def test04_node_slice (is_local, add_if_true, args=[1,2]):
638     for ns in myrange(number_slices):
639         test04_node_slice_ns (ns,is_local, add_if_true, args)
640
641 def test04_node_slice_ns (ns,is_local, add_if_true, args=[1,2]):
642     actual_nodes_per_slice = min (number_nodes,number_nodes_per_slice)
643     test04_node_slice_nl_n (myrange(actual_nodes_per_slice),ns,is_local, add_if_true, args)
644
645 def test04_node_slice_nl_n (nnl,ns,is_local, add_if_true, args=[1,2]):
646     for i in args:
647         peer=peer_index(i)
648         sname = slice_name (i,ns)
649         
650         if is_local:
651             hostnames=[node_name(i,nn) for nn in nnl]
652             nodetype='local'
653         else:
654             hostnames=[node_name(peer,nn) for nn in nnl]
655             nodetype='foreign'
656         if add_if_true:
657             s[i].AddSliceToNodes (a[i], sname,hostnames)
658             message="added"
659         else:
660             s[i].DeleteSliceFromNodes (a[i], sname,hostnames)
661             message="deleted"
662         print '%02d:== %s in slice %s %s '%(i,message,sname,nodetype),
663         print hostnames
664
665 def test04_slice_add_lnode (args=[1,2]):
666     test04_node_slice (True,True,args)
667
668 def test04_slice_add_fnode (args=[1,2]):
669     test04_node_slice (False,True,args)
670
671 def test04_slice_del_lnode (args=[1,2]):
672     test04_node_slice (True,False,args)
673
674 def test04_slice_del_fnode (args=[1,2]):
675     test04_node_slice (False,False,args)
676
677 ####################
678 def test05_sat (args=[1,2]):
679     for i in args:
680         name = sat_name(i)
681         try:
682             sat_id=s[i].GetSliceAttributeTypes (a[i],[name])[0]
683         except:
684             description="custom sat on plc%d"%i
685             min_role_id=10
686             sat_id=s[i].AddSliceAttributeType (a[i],
687                                                { 'name':name,
688                                                  'description': description,
689                                                  'min_role_id' : min_role_id})
690             print '%02d:== created SliceAttributeType = %d'%(i,sat_id)
691
692 # for test, we create 4 slice_attributes
693 # on slice1 - sat=custom_made (see above) - all nodes
694 # on slice1 - sat=custom_made (see above) - node=n1
695 # on slice1 - sat='net_max' - all nodes
696 # on slice1 - sat='net_max' - node=n1
697
698 def test05_sa_atom (slice_name,sat_name,value,node,i):
699     sa_id=s[i].GetSliceAttributes(a[i],{'name':sat_name,
700                                         'value':value})
701     if not sa_id:
702         if node:
703             sa_id=s[i].AddSliceAttribute(a[i],
704                                          slice_name,
705                                          sat_name,
706                                          value,
707                                          node)
708         else:
709             print 'slice_name',slice_name,'sat_name',sat_name
710             sa_id=s[i].AddSliceAttribute(a[i],
711                                          slice_name,
712                                          sat_name,
713                                          value)
714         print '%02d:== created SliceAttribute = %d'%(i,sa_id),
715         print 'On slice',slice_name,'and node',node
716         
717 def test05_sa (args=[1,2]):
718     for i in args:
719         test05_sa_atom (slice_name(i,1),sat_name(i),'custom sat/all nodes',None,i)
720         test05_sa_atom (slice_name(i,1),sat_name(i),'custom sat/node1',node_name(i,1),i)
721         test05_sa_atom (slice_name(i,1),'net_max','predefined sat/all nodes',None,i)
722         test05_sa_atom (slice_name(i,1),'net_max','predefined sat/node1',node_name(i,1),i)
723         
724 ##############################
725 # readable dumps
726 ##############################
727 def p_site (s):
728     print s['site_id'],s['peer_id'],s['login_base'],s['name'],s['node_ids']
729
730 def p_key (k):
731     print  k['key_id'],k['peer_id'],k['key']
732     
733 def p_person (p):
734     print  p['person_id'],p['peer_id'],p['email'],'keys:',p['key_ids'],'sites:',p['site_ids']
735
736 def p_node(n):
737     print n['node_id'],n['peer_id'],n['hostname'],'sls=',n['slice_ids'],'site=',n['site_id']
738
739 def p_slice(s):
740     print s['slice_id'],s['peer_id'],s['name'],'nodes=',s['node_ids'],'persons=',s['person_ids']
741     print '---','sas=',s['slice_attribute_ids'],s['name'],'crp=',s['creator_person_id']
742     print "--- 'expires':",s['expires']
743
744 def p_sat(sat):
745     print sat['attribute_type_id'],sat['peer_id'], sat['name'], sat['min_role_id'], sat['description']
746
747 def p_sa (sa):
748         print sa['slice_attribute_id'],sa['peer_id'],sa['name'],'AT_id:',sa['attribute_type_id']
749         print '---','v=',sa['value'],'sl=',sa['slice_id'],'n=',sa['node_id']
750
751 import pprint
752 pretty_printer=pprint.PrettyPrinter(5)
753
754 def p_sliver (margin,x):
755     print margin,'SLIVERS for : hostname',x['hostname']
756     print margin,'%d config files'%len(x['conf_files'])
757     for sv in x['slivers']:
758         p_sliver_slice(margin,sv,x['hostname'])
759
760 def p_sliver_slice(margin,sliver,hostname):
761     print margin,'SLIVER on hostname %s, s='%hostname,sliver['name']
762     print margin,'KEYS',
763     pretty_printer.pprint(sliver['keys'])
764     print margin,'ATTRIBUTES',
765     pretty_printer.pprint(sliver['attributes'])
766
767 def dump (args=[1,2]):
768     for i in args:
769         print '%02d:============================== DUMPING'%i
770         print '%02d: SITES'%i
771         [p_site(x) for x in s[i].GetSites(a[i])]
772         print '%02d: KEYS'%i
773         [p_key(x) for x in s[i].GetKeys(a[i])]
774         print '%02d: PERSONS'%i
775         [p_person(x) for x in s[i].GetPersons(a[i])]
776         print '%02d: NODES'%i
777         [p_node(x) for x in s[i].GetNodes(a[i])]
778         print '%02d: SLICES'%i
779         [p_slice(x) for x in s[i].GetSlices(a[i])]
780         print '%02d: Slice Attribute Types'%i
781         [p_sat(x) for x in s[i].GetSliceAttributeTypes(a[i])]
782         print '%02d: Slice Attributes'%i
783         [p_sa(x) for x in s[i].GetSliceAttributes(a[i])]
784         print '%02d: SLIVERS'%i
785         [p_sliver('%02d:'%i,x) for x in s[i].GetSlivers(a[i])]
786         print '%02d:============================== END DUMP'%i
787     
788
789 ## for usage under the api
790 def pt ():
791     for x in GetSites():
792         p_site(x)
793         
794 def pk ():
795     for x in GetKeys():
796         print  (x['key_id'],x['peer_id'],x['key']) 
797
798 def pp ():
799     for x in GetPersons():
800         p_person(x)
801
802 def pn ():
803     for x in GetNodes():
804         p_node(x)
805
806 def ps ():
807     for x in GetSlices():
808         p_slice(x)
809
810 def psat():
811     for x in GetSliceAttributeTypes():
812         p_sat(x)
813         
814 def psa():
815     for x in GetSliceAttributes():
816         p_sa(x)
817         
818 def pv ():
819     for s in GetSlivers():
820         p_sliver('',s)
821
822 def all():
823     print 'SITES'
824     pt()
825     print 'KEYS'
826     pk()
827     print 'PERSONS'
828     pp()
829     print 'NODES'
830     pn()
831     print 'SLICES'
832     ps()
833     print 'SLICE ATTR TYPES'
834     psat()
835     print 'SLICE ATTRS'
836     psa()
837     print 'SLIVERS'
838     pv()
839
840
841 ####################
842 def test_all_init ():
843     message ("INIT")
844     test00_init ()
845     test00_print ()
846     test00_admin_person ()
847     test00_admin_enable ()
848     test00_peer_person ()
849     test00_peer ()
850     test00_peer_passwd ()
851
852 def test_all_sites ():
853     test01_site ()
854     test00_refresh ('after site creation')
855
856 def test_all_persons ():
857     test02_del_person()
858     test00_refresh ('before persons&keys creation')
859     check_keys(0,0)
860     check_persons(system_persons,system_persons_cross)
861     message ("Creating persons&keys")
862     test02_person ()
863     if not fast_flag:
864         message ("1 extra del/add cycle for unique indexes")
865         test02_del_person([2])
866         test02_person([2])
867     check_keys(number_persons*number_keys,0)
868     check_persons(system_persons+number_persons,system_persons_cross)
869     test00_refresh ('after persons&keys creation')
870     check_keys(number_persons*number_keys,number_persons*number_keys)
871     check_persons(system_persons+number_persons,system_persons_cross+number_persons)
872
873 def test_all_nodes ():
874
875     message ("RESETTING NODES")
876     clean_all_nodes ()
877     test00_refresh ('cleaned nodes')
878     check_nodes(0,0)
879
880     # create one node on each site
881     message ("CREATING NODES")
882     test03_node ()
883     check_nodes(number_nodes,0)
884     test00_refresh ('after node creation')
885     check_nodes(number_nodes,number_nodes)
886     test02_delnode([2])
887     if not fast_flag:
888         message ("2 extra del/add cycles on plc2 for different indexes")
889         test03_node ([2])
890         test02_delnode([2])
891         test03_node ([2])
892         test02_delnode([2])
893     check_nodes(0,number_nodes,[2])
894     test00_refresh('after deletion on plc2')
895     check_nodes(number_nodes,0,[1])
896     check_nodes(0,number_nodes,[2])
897     message ("ADD on plc2 for different indexes")
898     test03_node ([2])
899     check_nodes (number_nodes,0,[1])
900     check_nodes (number_nodes,number_nodes,[2])
901     test00_refresh('after re-creation on plc2')
902     check_nodes (number_nodes,number_nodes,)
903
904 def test_all_addslices ():
905
906     # reset
907     message ("RESETTING SLICES TEST")
908     clean_all_nodes ()
909     test03_node ()
910     clean_all_slices ()
911     test00_refresh ("After slices init")
912
913     # create slices on plc1
914     message ("CREATING SLICES on plc1")
915     test04_slice ([1])
916     # each site has 3 local slices and 0 foreign slice
917     check_slices (total_slices(),0,[1])
918     check_slices (system_slices(),0,[2])
919     test00_refresh ("after slice created on plc1")
920     check_slices (total_slices(),0,[1])
921     check_slices (system_slices(),number_slices,[2])
922     # no slice has any node yet
923     check_local_slice_nodes(0,[1])
924     check_foreign_slice_nodes(0,[2])
925
926     # insert local nodes in local slice on plc1
927     message ("ADDING LOCAL NODES IN SLICES")
928     test04_slice_add_lnode ([1])
929     # of course the change is only local
930     check_local_slice_nodes (number_nodes,[1])
931     check_foreign_slice_nodes(0,[2])
932
933     # refreshing
934     test00_refresh ("After local nodes were added on plc1")
935     check_local_slice_nodes (number_nodes,[1])
936     check_foreign_slice_nodes (number_nodes,[2])
937
938     # now we add foreign nodes into local slice
939     message ("ADDING FOREIGN NODES IN SLICES")
940     test04_slice_add_fnode ([1])
941     check_local_slice_nodes (2*number_nodes,[1])
942     check_foreign_slice_nodes (number_nodes,[2])
943
944     # refreshing
945     test00_refresh ("After foreign nodes were added in plc1")
946     # remember that foreign slices only know about LOCAL nodes
947     # so this does not do anything
948     check_local_slice_nodes (2*number_nodes,[1])
949     check_foreign_slice_nodes (2*number_nodes,[2])
950
951     check_slivers_1(total_slivers())
952
953 def test_all_delslices ():
954
955     message ("DELETING FOREIGN NODES FROM SLICES")
956     test04_slice_del_fnode([1])
957     check_local_slice_nodes (number_nodes,[1])
958     check_foreign_slice_nodes (2*number_nodes,[2])
959     # mmh?
960     check_slivers_1(total_slivers(),[1])
961
962     test00_refresh ("After foreign nodes were removed on plc1")
963     check_local_slice_nodes (number_nodes,[1])
964     check_foreign_slice_nodes (number_nodes,[2])
965     
966     message ("DELETING LOCAL NODES FROM SLICES")
967     test04_slice_del_lnode([1])
968     check_local_slice_nodes (0,[1])
969     check_foreign_slice_nodes (number_nodes,[2])
970
971     test00_refresh ("After local nodes were removed on plc1")
972     check_local_slice_nodes (0,[1])
973     check_foreign_slice_nodes (0,[2])
974
975     message ("CHECKING SLICES CLEAN UP")
976     clean_all_slices([1])
977     check_slices (system_slices(),0,[1])
978     check_slices (system_slices(),number_slices,[2])
979     test00_refresh ("After slices clenaup")
980     check_slices(system_slices(),0)
981
982 def test_all_slices ():
983     test_all_addslices ()
984     test_all_delslices ()
985     
986 def test_all_sats ():
987     test05_sat ()
988     test00_refresh("after SliceAttributeType creation")                   
989
990 def test_all ():
991     test_all_init ()
992     timer_show()
993     test_all_sites ()
994     timer_show()
995     test_all_persons ()
996     timer_show()
997     test_all_nodes ()
998     timer_show()
999     test_all_slices ()
1000     timer_show()
1001     test_all_sats ()
1002     timer_show()
1003     dump()
1004     timer_show()
1005     message("END")
1006
1007 ### ad hoc test sequences
1008 # we just create objects here so we can dump the DB
1009 def populate ():
1010     timer_start()
1011     test_all_init()
1012     timer_show()
1013     test01_site()
1014     timer_show()
1015     test02_person()
1016     timer_show()
1017     test03_node()
1018     timer_show()
1019     test04_slice([1])
1020     timer_show()
1021     test04_slice_add_lnode([1])
1022     timer_show()
1023     test05_sat()
1024     timer_show()
1025     test05_sa([1])
1026     timer_show()
1027
1028 def populate_end():
1029     test00_init()
1030     test00_refresh ("populate: refreshing peer 1",[1])
1031     timer_show()
1032     test04_slice_add_fnode([1])
1033     timer_show()
1034     test00_refresh("populate: refresh all")
1035     timer_show()
1036     test00_refresh("empty refresh")
1037     dump()
1038     timer_show()
1039     message("END")
1040
1041 # temporary - scratch as needed
1042 def test_now ():
1043     test_all_init()
1044     test_all_sites ()
1045 #    clean_all_nodes()
1046 #    clean_all_slices()
1047 #    populate()
1048
1049 #####
1050 def usage ():
1051     print "Usage: %s [-n] [-f]"%sys.argv[0]
1052     print " -n runs test_now instead of test_all"
1053     print " -p runs populate instead of test_all"
1054     print " -e runs populate_end of test_all"
1055     print " -m run in mini mode (1 instance of each class)"
1056     print " -b performs big run (%d times as large as normal)"%big_factor
1057     print " -H performs huge run (%d times as large as normal)"%huge_factor
1058     print " -l n : tester runs locally for peer <n>, rather than through xmlrpc"
1059     
1060     sys.exit(1)
1061
1062 def main ():
1063     try:
1064         (o,a) = getopt.getopt(sys.argv[1:], "emnpbHl:")
1065     except:
1066         usage()
1067     func = test_all
1068     for (opt,val) in o:
1069         if opt=='-n':
1070             print 'Running test_now'
1071             func = test_now
1072         elif opt=='-p':
1073             print 'Running populate'
1074             func = populate
1075         elif opt=='-e':
1076             print 'Running populate_end'
1077             func = populate_end
1078         elif opt=='-m':
1079             mini()
1080         elif opt=='-b':
1081             big()
1082         elif opt=='-H':
1083             huge()
1084         elif opt=='-l':
1085             if val in (1,2):
1086                 local_peer=val
1087                 print '-l option not implemented yet'
1088                 # need to figure a way to use Shell.py-like calling paradigm
1089             else:
1090                 usage()
1091         else:
1092             usage()
1093     if a:
1094         usage()
1095     show_test()
1096     func()   
1097     timer_show()
1098
1099 if __name__ == '__main__':
1100     normal()
1101     main()
1102