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