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