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