- unicmp() unnecessary, fixed PostgreSQL.py interface to cast 8-bit
[plcapi.git] / Test.py
1 #!/usr/bin/env ./Shell.py
2 #
3 # Test script example
4 #
5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2006 The Trustees of Princeton University
7 #
8 # $Id$
9 #
10
11 from pprint import pprint
12 from string import letters, digits, punctuation
13 import re
14 import socket
15 import struct
16 import base64
17 import os
18
19 from random import Random
20 random = Random()
21
22 def randfloat(min = 0.0, max = 1.0):
23     return float(min) + (random.random() * (float(max) - float(min)))
24
25 def randint(min = 0, max = 1):
26     return int(randfloat(min, max + 1))
27
28 # See "2.2 Characters" in the XML specification:
29 #
30 # #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
31 # avoiding
32 # [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF]
33
34 ascii_xml_chars = map(unichr, [0x9, 0xA, 0xD])
35 ascii_xml_chars += map(unichr, xrange(0x20, 0x7F - 1))
36 low_xml_chars = list(ascii_xml_chars)
37 low_xml_chars += map(unichr, xrange(0x84 + 1, 0x86 - 1))
38 low_xml_chars += map(unichr, xrange(0x9F + 1, 0xFF))
39 valid_xml_chars = list(low_xml_chars)
40 valid_xml_chars += map(unichr, xrange(0xFF + 1, 0xD7FF))
41 valid_xml_chars += map(unichr, xrange(0xE000, 0xFDD0 - 1))
42 valid_xml_chars += map(unichr, xrange(0xFDDF + 1, 0xFFFD))
43
44 def randstr(length, pool = valid_xml_chars, encoding = "utf-8"):
45     sample = random.sample(pool, min(length, len(pool)))
46     while True:
47         s = u''.join(sample)
48         bytes = len(s.encode(encoding))
49         if bytes > length:
50             sample.pop()
51         elif bytes < length:
52             sample += random.sample(pool, min(length - bytes, len(pool)))
53             random.shuffle(sample)
54         else:
55             break
56     return s
57
58 def randhostname():
59     # 1. Each part begins and ends with a letter or number.
60     # 2. Each part except the last can contain letters, numbers, or hyphens.
61     # 3. Each part is between 1 and 64 characters, including the trailing dot.
62     # 4. At least two parts.
63     # 5. Last part can only contain between 2 and 6 letters.
64     hostname = 'a' + randstr(61, letters + digits + '-') + '1.' + \
65                'b' + randstr(61, letters + digits + '-') + '2.' + \
66                'c' + randstr(5, letters)
67     return hostname
68
69 def randpath(length):
70     parts = []
71     for i in range(randint(1, 10)):
72         parts.append(randstr(randint(1, 30), ascii_xml_chars))
73     return os.sep.join(parts)[0:length]
74
75 def randemail():
76     return (randstr(100, letters + digits) + "@" + randhostname()).lower()
77
78 def randkey(bits = 2048):
79     key_types = ["ssh-dss", "ssh-rsa"]
80     key_type = random.sample(key_types, 1)[0]
81     return ' '.join([key_type,
82                      base64.b64encode(''.join(randstr(bits / 8).encode("utf-8"))),
83                      randemail()])
84
85 admin = {'AuthMethod': "capability",
86          'Username': config.PLC_API_MAINTENANCE_USER,
87          'AuthString': config.PLC_API_MAINTENANCE_PASSWORD,
88          'Role': "admin"}
89
90 user = {'AuthMethod': "password",
91         'Role': "user"}
92
93 pi = {'AuthMethod': "password",
94       'Role': "pi"}
95
96 tech = {'AuthMethod': "password",
97         'Role': "tech"}
98
99 # Add sites
100 site_ids = []
101 for i in range(3):
102     def random_site():
103         return {
104             'name': randstr(254),
105             'abbreviated_name': randstr(50),
106             'login_base': randstr(20, letters).lower(),
107             'latitude': int(randfloat(-90.0, 90.0) * 1000) / 1000.0,
108             'longitude': int(randfloat(-180.0, 180.0) * 1000) / 1000.0,
109             }
110             
111     # Add site
112     site_fields = random_site()
113     print "AddSite",
114     site_id = AddSite(admin, site_fields)
115
116     # Should return a unique site_id
117     assert site_id not in site_ids
118     site_ids.append(site_id)
119     print "=>", site_id
120
121     # Check site
122     print "GetSites(%d)" % site_id,
123     site = GetSites(admin, [site_id])[0]
124     for field in site_fields:
125         assert site[field] == site_fields[field]
126     print "=> OK"
127
128     # Update site
129     site_fields = random_site()
130     # XXX Currently cannot change login_base
131     del site_fields['login_base']
132     site_fields['max_slices'] = randint(1, 10)
133     print "UpdateSite(%d)" % site_id,
134     UpdateSite(admin, site_id, site_fields)
135     print "=> OK"
136
137     # Check site again
138     site = GetSites(admin, [site_id])[0]
139     for field in site_fields:
140         assert site[field] == site_fields[field]
141
142 print "GetSites",
143 sites = GetSites(admin, site_ids)
144 assert set(site_ids) == set([site['site_id'] for site in sites])
145 print "=>", site_ids
146
147 # Add address types
148 address_type_ids = []
149 for i in range(3):
150     def random_address_type():
151         return {
152             'name': randstr(20),
153             'description': randstr(254),
154             }
155
156     print "AddAddressType",
157     address_type_fields = random_address_type()
158     address_type_id = AddAddressType(admin, address_type_fields)
159
160     # Should return a unique address_type_id
161     assert address_type_id not in address_type_ids
162     address_type_ids.append(address_type_id)
163     print "=>", address_type_id
164
165     # Check address type
166     print "GetAddressTypes(%d)" % address_type_id,
167     address_type = GetAddressTypes(admin, [address_type_id])[0]
168     for field in 'name', 'description':
169         assert address_type[field] == address_type_fields[field]
170     print "=> OK"
171
172     # Update address type
173     address_type_fields = random_address_type()
174     print "UpdateAddressType(%d)" % address_type_id,
175     UpdateAddressType(admin, address_type_id, address_type_fields)
176     print "=> OK"
177
178     # Check address type again
179     address_type = GetAddressTypes(admin, [address_type_id])[0]
180     for field in 'name', 'description':
181         assert address_type[field] == address_type_fields[field]
182
183 print "GetAddressTypes",
184 address_types = GetAddressTypes(admin, address_type_ids)
185 assert set(address_type_ids) == set([address_type['address_type_id'] for address_type in address_types])
186 print "=>", address_type_ids
187
188 # Add site addresses
189 address_ids = []
190 for site_id in site_ids:
191     for i in range(3):
192         def random_address():
193             return {
194                 'line1': randstr(254),
195                 'line2': randstr(254),
196                 'line3': randstr(254),
197                 'city': randstr(254),
198                 'state': randstr(254),
199                 'postalcode': randstr(64),
200                 'country': randstr(128),
201                 }
202
203         print "AddSiteAddress",
204         address_fields = random_address()
205         address_id = AddSiteAddress(admin, site_id, address_fields)
206
207         # Should return a unique address_id
208         assert address_id not in address_ids
209         address_ids.append(address_id)
210         print "=>", address_id
211
212         # Check address
213         print "GetAddresses(%d)" % address_id,
214         address = GetAddresses(admin, [address_id])[0]
215         for field in address_fields:
216             assert address[field] == address_fields[field]
217         print "=> OK"
218
219         # Update address
220         address_fields = random_address()
221         print "UpdateAddress(%d)" % address_id,
222         UpdateAddress(admin, address_id, address_fields)
223         print "=> OK"
224
225         # Check address again
226         address = GetAddresses(admin, [address_id])[0]
227         for field in address_fields:
228             assert address[field] == address_fields[field]
229
230         # Add address types
231         for address_type_id in address_type_ids:
232             print "AddAddressTypeToAddress(%d, %d)" % (address_type_id, address_id),
233             AddAddressTypeToAddress(admin, address_type_id, address_id)
234             print "=> OK"
235         
236 print "GetAddresses",
237 addresses = GetAddresses(admin, address_ids)
238 assert set(address_ids) == set([address['address_id'] for address in addresses])
239 for address in addresses:
240     assert set(address_type_ids) == set(address['address_type_ids'])
241 print "=>", address_ids
242
243 print "GetRoles",
244 roles = GetRoles(admin)
245 role_ids = [role['role_id'] for role in roles]
246 roles = [role['name'] for role in roles]
247 roles = dict(zip(roles, role_ids))
248 print "=>", role_ids
249
250 print "GetKeyTypes",
251 key_types = GetKeyTypes(admin)
252 print "=>", key_types
253
254 # Add users
255 person_ids = []
256 key_ids = []
257 for auth in user, pi, tech:
258     def random_person():
259         global auth
260
261         person_fields = {
262             'first_name': randstr(128),
263             'last_name': randstr(128),
264             'email': randemail(),
265             'bio': randstr(254),
266             # Accounts are disabled by default
267             'enabled': False,
268             'password': randstr(254),
269             }
270
271         auth['Username'] = person_fields['email']
272         auth['AuthString'] = person_fields['password']
273
274         return person_fields
275
276     # Add account
277     person_fields = random_person()
278     print "AddPerson",
279     person_id = AddPerson(admin, person_fields)
280
281     # Should return a unique person_id
282     assert person_id not in person_ids
283     person_ids.append(person_id)
284     print "=>", person_id
285
286     # Check account
287     print "GetPersons(%d)" % person_id,
288     person = GetPersons(admin, [person_id])[0]
289     for field in person_fields:
290         if field != 'password':
291             assert person[field] == person_fields[field]
292     print "=> OK"
293
294     # Update account
295     person_fields = random_person()
296     print "UpdatePerson(%d)" % person_id,
297     UpdatePerson(admin, person_id, person_fields)
298     print "=> OK"
299
300     # Check account again
301     person = GetPersons(admin, [person_id])[0]
302     for field in person_fields:
303         if field != 'password':
304             assert person[field] == person_fields[field]
305
306     # Check that account is really disabled
307     try:
308         assert not AuthCheck(auth)
309     except:
310         pass
311
312     # Add role
313     role_id = roles[auth['Role']]
314     print "AddRoleToPerson(%d, %d)" % (role_id, person_id),
315     AddRoleToPerson(admin, role_id, person_id)
316     person = GetPersons(admin, [person_id])[0]
317     assert [role_id] == person['role_ids']
318     print "=> OK"
319
320     # Enable account
321     UpdatePerson(admin, person_id, {'enabled': True})
322
323     # Check authentication
324     print "AuthCheck(%s)" % auth['Username'],
325     assert AuthCheck(auth)
326     print "=> OK"
327
328     # Associate account with each site
329     for site_id in site_ids:
330         print "AddPersonToSite(%d, %d)" % (person_id, site_id),
331         AddPersonToSite(admin, person_id, site_id)
332         print "=> OK"
333
334     # Make sure it really did it
335     person = GetPersons(admin, [person_id])[0]
336     person_site_ids = person['site_ids']
337     assert set(site_ids) == set(person['site_ids'])
338
339     # First site should be the primary site
340     print "SetPersonPrimarySite(%d, %d)" % (person_id, person_site_ids[1]),
341     SetPersonPrimarySite(auth, person_id, person_site_ids[1])
342     person = GetPersons(admin, [person_id])[0]
343     assert person['site_ids'][0] == person_site_ids[1]
344     print "=> OK"
345
346     def random_key():
347         return {
348             'key_type': random.sample(key_types, 1)[0],
349             'key': randkey()
350             }
351
352     # Add keys
353     for i in range(3):
354         # Add slice attribute
355         key_fields = random_key()
356         print "AddPersonKey",
357         key_id = AddPersonKey(admin, person_id, key_fields)
358
359         # Should return a unique key_id
360         assert key_id not in key_ids
361         key_ids.append(key_id)
362         print "=>", key_id
363
364         # Check key
365         print "GetKeys(%d)" % key_id,
366         key = GetKeys(admin, [key_id])[0]
367         for field in key_fields:
368             assert key[field] == key_fields[field]
369         print "=> OK"
370
371         # Update key
372         key_fields = random_key()
373         print "UpdateKey(%d)" % key_id,
374         UpdateKey(admin, key_id, key_fields)
375         key = GetKeys(admin, [key_id])[0]
376         for field in key_fields:
377             assert key[field] == key_fields[field]
378         print "=> OK"
379
380     # Add and immediately blacklist a key
381     key_fields = random_key()
382     print "AddPersonKey",
383     key_id = AddPersonKey(admin, person_id, key_fields)
384     print "=>", key_id
385
386     print "BlacklistKey(%d)" % key_id,
387     BlacklistKey(admin, key_id)
388
389     # Is effectively deleted
390     assert not GetKeys(admin, [key_id])
391     person = GetPersons(admin, [person_id])[0]
392     assert key_id not in person['key_ids']
393
394     # Cannot be added again
395     try:
396         key_id = AddPersonKey(admin, person_id, key_fields)
397         assert False
398     except Exception, e:
399         pass
400
401     print "=> OK"
402
403 print "GetPersons",
404 persons = GetPersons(admin, person_ids)
405 assert set(person_ids) == set([person['person_id'] for person in persons])
406 print "=>", person_ids
407
408 # Add node groups
409 nodegroup_ids = []
410 for i in range(3):
411     def random_nodegroup():
412         return {
413             'name': randstr(50),
414             'description': randstr(200),
415             }
416
417     # Add node group
418     print "AddNodeGroup",
419     nodegroup_fields = random_nodegroup()
420     nodegroup_id = AddNodeGroup(admin, nodegroup_fields)
421
422     # Should return a unique nodegroup_id
423     assert nodegroup_id not in nodegroup_ids
424     nodegroup_ids.append(nodegroup_id)
425     print "=>", nodegroup_id
426
427     # Check node group
428     print "GetNodeGroups(%d)" % nodegroup_id,
429     nodegroup = GetNodeGroups(admin, [nodegroup_id])[0]
430     for field in nodegroup_fields:
431         assert nodegroup[field] == nodegroup_fields[field]
432     print "=> OK"
433
434     # Update node group, with a readable name
435     nodegroup_fields = random_nodegroup()
436     nodegroup_fields['name'] = randstr(16, letters + ' ' + digits)
437     print "UpdateNodeGroup",
438     UpdateNodeGroup(admin, nodegroup_id, nodegroup_fields)
439     print "=> OK"
440
441     # Check node group again
442     nodegroup = GetNodeGroups(admin, [nodegroup_id])[0]
443     for field in nodegroup_fields:
444         assert nodegroup[field] == nodegroup_fields[field]
445
446 print "GetNodeGroups",
447 nodegroups = GetNodeGroups(admin, nodegroup_ids)
448 assert set(nodegroup_ids) == set([nodegroup['nodegroup_id'] for nodegroup in nodegroups])
449 print "=>", nodegroup_ids
450
451 print "GetBootStates",
452 boot_states = GetBootStates(admin)
453 print "=>", boot_states
454
455 # Add nodes
456 node_ids = []
457 for site_id in site_ids:
458     for i in range(3):
459         def random_node():
460             return {
461                 'hostname': randhostname(),
462                 'boot_state': random.sample(boot_states, 1)[0],
463                 'model': randstr(255),
464                 'version': randstr(64),
465                 }
466
467         # Add node
468         node_fields = random_node()
469         print "AddNode",
470         node_id = AddNode(admin, site_id, node_fields)
471
472         # Should return a unique node_id
473         assert node_id not in node_ids
474         node_ids.append(node_id)
475         print "=>", node_id
476
477         # Check node
478         print "GetNodes(%d)" % node_id,
479         node = GetNodes(admin, [node_id])[0]
480         for field in node_fields:
481             assert node[field] == node_fields[field]
482         print "=> OK"
483
484         # Update node
485         node_fields = random_node()
486         print "UpdateNode(%d)" % node_id,
487         UpdateNode(admin, node_id, node_fields)
488         print "=> OK"
489
490         # Check node again
491         node = GetNodes(admin, [node_id])[0]
492         for field in node_fields:
493             assert node[field] == node_fields[field]
494
495         # Add to node groups
496         for nodegroup_id in nodegroup_ids:
497             print "AddNodeToNodeGroup(%d, %d)" % (node_id, nodegroup_id),
498             AddNodeToNodeGroup(admin, node_id, nodegroup_id)
499             print "=> OK"
500         
501 print "GetNodes",
502 nodes = GetNodes(admin, node_ids)
503 assert set(node_ids) == set([node['node_id'] for node in nodes])
504 print "=>", node_ids
505
506 print "GetNodeGroups",
507 nodegroups = GetNodeGroups(admin, nodegroup_ids)
508 for nodegroup in nodegroups:
509     assert set(nodegroup['node_ids']) == set(node_ids)
510 print "=> OK"
511
512 print "GetNetworkMethods",
513 network_methods = GetNetworkMethods(admin)
514 print "=>", network_methods
515
516 print "GetNetworkTypes",
517 network_types = GetNetworkTypes(admin)
518 print "=>", network_types
519
520 # Add node networks
521 nodenetwork_ids = []
522 for node_id in node_ids:
523     def random_nodenetwork(method, type):
524         nodenetwork_fields = {
525             'method': method,
526             'type': type,
527             'bwlimit': randint(500000, 10000000),
528             }
529
530         if method != 'dhcp':
531             ip = randint(0, 0xffffffff)
532             netmask = (0xffffffff << randint(2, 31)) & 0xffffffff
533             network = ip & netmask
534             broadcast = ((ip & netmask) | ~netmask) & 0xffffffff
535             gateway = randint(network + 1, broadcast - 1)
536             dns1 = randint(0, 0xffffffff)
537
538             for field in 'ip', 'netmask', 'network', 'broadcast', 'gateway', 'dns1':
539                 nodenetwork_fields[field] = socket.inet_ntoa(struct.pack('>L', locals()[field]))
540
541         return nodenetwork_fields
542
543     for method in network_methods:
544         for type in network_types:
545             # Add node network
546             print "AddNodeNetwork",
547             nodenetwork_fields = random_nodenetwork(method, type)
548             nodenetwork_id = AddNodeNetwork(admin, node_id, nodenetwork_fields)
549
550             # Should return a unique nodenetwork_id
551             assert nodenetwork_id not in nodenetwork_ids
552             nodenetwork_ids.append(nodenetwork_id)
553             print "=>", nodenetwork_id
554
555             # Check node network
556             print "GetNodeNetworks(%d)" % nodenetwork_id,
557             nodenetwork = GetNodeNetworks(admin, [nodenetwork_id])[0]
558             for field in nodenetwork_fields:
559                 assert nodenetwork[field] == nodenetwork_fields[field]
560             print "=> OK"
561
562             # Update node network
563             nodenetwork_fields = random_nodenetwork(method, type)
564             print "UpdateNodeNetwork(%d)" % nodenetwork_id,
565             UpdateNodeNetwork(admin, nodenetwork_id, nodenetwork_fields)
566             print "=> OK"
567
568             # Check node network again
569             nodenetwork = GetNodeNetworks(admin, [nodenetwork_id])[0]
570             for field in nodenetwork_fields:
571                 assert nodenetwork[field] == nodenetwork_fields[field]
572
573 print "GetNodeNetworks",
574 nodenetworks = GetNodeNetworks(admin, nodenetwork_ids)
575 assert set(nodenetwork_ids) == set([nodenetwork['nodenetwork_id'] for nodenetwork in nodenetworks])
576 print "=>", nodenetwork_ids
577
578 # Add PCUs
579 pcu_ids = []
580 for site_id in site_ids:
581     def random_pcu():
582         return {
583             'hostname': randhostname(),
584             'ip': socket.inet_ntoa(struct.pack('>L', randint(0, 0xffffffff))),
585             'protocol': randstr(16),
586             'username': randstr(254),
587             'password': randstr(254),
588             'notes': randstr(254),
589             'model': randstr(32),
590             }
591
592     # Add PCU
593     pcu_fields = random_pcu()
594     print "AddPCU",
595     pcu_id = AddPCU(admin, site_id, pcu_fields)
596
597     # Should return a unique pcu_id
598     assert pcu_id not in pcu_ids
599     pcu_ids.append(pcu_id)
600     print "=>", pcu_id
601
602     # Check PCU
603     print "GetPCUs(%d)" % pcu_id,
604     pcu = GetPCUs(admin, [pcu_id])[0]
605     for field in pcu_fields:
606         assert pcu[field] == pcu_fields[field]
607     print "=> OK"
608
609     # Update PCU
610     pcu_fields = random_pcu()
611     print "UpdatePCU(%d)" % pcu_id,
612     UpdatePCU(admin, pcu_id, pcu_fields)
613     print "=> OK"
614
615     # Check PCU again
616     pcu = GetPCUs(admin, [pcu_id])[0]
617     for field in pcu_fields:
618         assert pcu[field] == pcu_fields[field]
619
620     # Add each node at this site to a different port on this PCU
621     site = GetSites(admin, [site_id])[0]
622     port = randint(1, 10)
623     for node_id in site['node_ids']:
624         print "AddNodeToPCU(%d, %d, %d)" % (node_id, pcu_id, port),
625         AddNodeToPCU(admin, node_id, pcu_id, port)
626         print "=> OK"
627         port += 1
628
629 print "GetPCUs",
630 pcus = GetPCUs(admin, pcu_ids)
631 assert set(pcu_ids) == set([pcu['pcu_id'] for pcu in pcus])
632 print "=>", pcu_ids
633
634 # Add configuration files
635 conf_file_ids = []
636 for nodegroup_id in nodegroup_ids:
637     def random_conf_file():
638         return {
639             'enabled': bool(randint()),
640             'source': randpath(255),
641             'dest': randpath(255),
642             'file_permissions': "%#o" % randint(0, 512),
643             'file_owner': randstr(32, letters + '_' + digits),
644             'file_group': randstr(32, letters + '_' + digits),
645             'preinstall_cmd': randpath(100),
646             'postinstall_cmd': randpath(100),
647             'error_cmd': randpath(100),
648             'ignore_cmd_errors': bool(randint()),
649             'always_update': bool(randint()),
650             }
651
652     # Add configuration file
653     conf_file_fields = random_conf_file()
654     print "AddConfFile",
655     conf_file_id = AddConfFile(admin, conf_file_fields)
656
657     # Should return a unique conf_file_id
658     assert conf_file_id not in conf_file_ids
659     conf_file_ids.append(conf_file_id)
660     print "=>", conf_file_id
661
662     # Check configuration file
663     print "GetConfFiles(%d)" % conf_file_id,
664     conf_file = GetConfFiles(admin, [conf_file_id])[0]
665     for field in conf_file_fields:
666         assert conf_file[field] == conf_file_fields[field]
667     print "=> OK"
668
669     # Update configuration file
670     conf_file_fields = random_conf_file()
671     print "UpdateConfFile(%d)" % conf_file_id,
672     UpdateConfFile(admin, conf_file_id, conf_file_fields)
673     print "=> OK"
674
675     # Check configuration file
676     conf_file = GetConfFiles(admin, [conf_file_id])[0]
677     for field in conf_file_fields:
678         assert conf_file[field] == conf_file_fields[field]
679
680     # Add to all node groups
681     for nodegroup_id in nodegroup_ids:
682         print "AddConfFileToNodeGroup(%d, %d)" % (conf_file_id, nodegroup_id),
683         AddConfFileToNodeGroup(admin, conf_file_id, nodegroup_id)
684         print "=> OK"
685
686     # Add to all nodes
687     for node_id in node_ids:
688         print "AddConfFileToNode(%d, %d)" % (conf_file_id, node_id),
689         AddConfFileToNode(admin, conf_file_id, node_id)
690         print "=> OK"
691
692 print "GetConfFiles",
693 conf_files = GetConfFiles(admin, conf_file_ids)
694 assert set(conf_file_ids) == set([conf_file['conf_file_id'] for conf_file in conf_files])
695 for conf_file in conf_files:
696     assert set(nodegroup_ids) == set(conf_file['nodegroup_ids'])
697     assert set(node_ids) == set(conf_file['node_ids'])
698 print "=>", conf_file_ids
699
700 # Add slice attribute types
701 attribute_type_ids = []
702 for i in range(3):
703     def random_attribute_type():
704         return {
705             'name': randstr(100),
706             'description': randstr(254),
707             'min_role_id': random.sample(roles.values(), 1)[0],
708             }
709
710     # Add slice attribute type
711     attribute_type_fields = random_attribute_type()
712     print "AddSliceAttributeType",
713     attribute_type_id = AddSliceAttributeType(admin, attribute_type_fields)
714
715     # Should return a unique attribute_type_id
716     assert attribute_type_id not in attribute_type_ids
717     attribute_type_ids.append(attribute_type_id)
718     print "=>", attribute_type_id
719
720     # Check slice attribute type
721     print "GetSliceAttributeTypes(%d)" % attribute_type_id,
722     attribute_type = GetSliceAttributeTypes(admin, [attribute_type_id])[0]
723     for field in attribute_type_fields:
724         assert attribute_type[field] == attribute_type_fields[field]
725     print "=> OK"
726
727     # Update slice attribute type
728     attribute_type_fields = random_attribute_type()
729     print "UpdateSliceAttributeType(%d)" % attribute_type_id,
730     UpdateSliceAttributeType(admin, attribute_type_id, attribute_type_fields)
731     print "=> OK"
732
733     # Check slice attribute type again
734     attribute_type = GetSliceAttributeTypes(admin, [attribute_type_id])[0]
735     for field in attribute_type_fields:
736         assert attribute_type[field] == attribute_type_fields[field]
737
738 # Add slices and slice attributes
739 slice_ids = []
740 slice_attribute_ids = []
741 for site in sites:
742     for i in range(site['max_slices']):
743         def random_slice():
744             return {
745                 'name': site['login_base'] + "_" + randstr(11, letters).lower(),
746                 'url': "http://" + randhostname() + "/",
747                 'description': randstr(2048),
748                 }
749
750         # Add slice
751         slice_fields = random_slice()
752         print "AddSlice",
753         slice_id = AddSlice(admin, slice_fields)
754
755         # Should return a unique slice_id
756         assert slice_id not in slice_ids
757         slice_ids.append(slice_id)
758         print "=>", slice_id
759
760         # Check slice
761         print "GetSlices(%d)" % slice_id,
762         slice = GetSlices(admin, [slice_id])[0]
763         for field in slice_fields:
764             assert slice[field] == slice_fields[field]
765         print "=> OK"
766
767         # Update slice
768         slice_fields = random_slice()
769         # Cannot change slice name
770         del slice_fields['name']
771         print "UpdateSlice(%d)" % slice_id,
772         UpdateSlice(admin, slice_id, slice_fields)
773         slice = GetSlices(admin, [slice_id])[0]
774         for field in slice_fields:
775             assert slice[field] == slice_fields[field]
776         print "=> OK"
777
778         # Add slice to all nodes
779         print "AddSliceToNodes(%d, %s)" % (slice_id, str(node_ids)),
780         AddSliceToNodes(admin, slice_id, node_ids)
781         slice = GetSlices(admin, [slice_id])[0]
782         assert set(node_ids) == set(slice['node_ids'])
783         print "=> OK"
784
785         # Add users to slice
786         for person_id in person_ids:
787             print "AddPersonToSlice(%d, %d)" % (person_id, slice_id),
788             AddPersonToSlice(admin, person_id, slice_id)
789             print "=> OK" 
790         slice = GetSlices(admin, [slice_id])[0]
791         assert set(person_ids) == set(slice['person_ids'])
792
793         # Set slice/sliver attributes
794         for attribute_type_id in attribute_type_ids:
795             value = randstr(16, letters + '_' + digits)
796             # Make it a sliver attribute with 50% probability
797             node_id = random.sample(node_ids + [None] * len(node_ids), 1)[0]
798
799             # Add slice attribute
800             print "AddSliceAttribute(%d, %d)" % (slice_id, attribute_type_id),
801             if node_id is None:
802                 slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value)
803             else:
804                 slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value, node_id)
805
806             # Should return a unique slice_attribute_id
807             assert slice_attribute_id not in slice_attribute_ids
808             slice_attribute_ids.append(slice_attribute_id)
809             print "=>", slice_attribute_id
810
811             # Check slice attribute
812             print "GetSliceAttributes(%d)" % slice_attribute_id,
813             slice_attribute = GetSliceAttributes(admin, [slice_attribute_id])[0]
814             for field in 'attribute_type_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value':
815                 assert slice_attribute[field] == locals()[field]
816             print "=> OK"
817
818             # Update slice attribute
819             value = randstr(16, letters + '_' + digits)
820             print "UpdateSliceAttribute(%d)" % slice_attribute_id,
821             UpdateSliceAttribute(admin, slice_attribute_id, value)
822             slice_attribute = GetSliceAttributes(admin, [slice_attribute_id])[0]
823             for field in 'attribute_type_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value':
824                 assert slice_attribute[field] == locals()[field]
825             print "=> OK"
826
827 # Delete slices
828 for slice_id in slice_ids:
829     # Delete slice attributes
830     slice = GetSlices(admin, [slice_id])[0]
831     for slice_attribute_id in slice['slice_attribute_ids']:
832         print "DeleteSliceAttribute(%d, %d)" % (slice_id, slice_attribute_id),
833         DeleteSliceAttribute(admin, slice_attribute_id)
834         print "=> OK"
835     slice = GetSlices(admin, [slice_id])[0]
836     assert not slice['slice_attribute_ids']
837
838     # Delete users from slice
839     for person_id in person_ids:
840         print "DeletePersonFromSlice(%d, %d)" % (person_id, slice_id),
841         DeletePersonFromSlice(admin, person_id, slice_id)
842         print "=> OK"
843     slice = GetSlices(admin, [slice_id])[0]
844     assert not slice['person_ids']
845
846     # Delete nodes from slice
847     print "DeleteSliceFromNodes(%d, %s)" % (slice_id, node_ids),
848     DeleteSliceFromNodes(admin, slice_id, node_ids)
849     print "=> OK"
850     slice = GetSlices(admin, [slice_id])[0]
851     assert not slice['node_ids']
852
853     # Delete slice
854     print "DeleteSlice(%d)" % slice_id,
855     DeleteSlice(admin, slice_id)
856     assert not GetSlices(admin, [slice_id])
857
858     # Make sure it really deleted it
859     slices = GetSlices(admin, slice_ids)
860     assert slice_id not in [slice['slice_id'] for slice in slices]
861     print "=> OK"
862
863 print "GetSlices",
864 assert not GetSlices(admin, slice_ids)
865 print "=> []"
866
867 # Delete slice attribute types
868 for attribute_type_id in attribute_type_ids:
869     # Delete slice attribute type
870     print "DeleteSliceAttributeType(%d)" % attribute_type_id,
871     DeleteSliceAttributeType(admin, attribute_type_id)
872     assert not GetSliceAttributeTypes(admin, [attribute_type_id])
873
874     # Make sure it really deleted it
875     attribute_types = GetSliceAttributeTypes(admin, attribute_type_ids)
876     assert attribute_type_id not in [attribute_type['attribute_type_id'] for attribute_type in attribute_types]
877     print "=> OK"
878
879 print "GetSliceAttributeTypes",
880 assert not GetSliceAttributeTypes(admin, attribute_type_ids)
881 print "=> []"
882
883 # Delete configuration files
884 for conf_file in conf_files:
885     conf_file_id = conf_file['conf_file_id']
886
887     for node_id in conf_file['node_ids']:
888         print "DeleteConfFileFromNode(%d, %d)" % (conf_file_id, node_id),
889         DeleteConfFileFromNode(admin, conf_file_id, node_id)
890         print "=> OK"
891
892     for nodegroup_id in conf_file['nodegroup_ids']:
893         print "DeleteConfFileFromNodeGroup(%d, %d)" % (conf_file_id, nodegroup_id),
894         DeleteConfFileFromNodeGroup(admin, conf_file_id, nodegroup_id)
895         print "=> OK"
896
897     print "DeleteConfFile(%d)" % conf_file_id,
898     DeleteConfFile(admin, conf_file_id)
899     print "=> OK"
900
901 print "GetConfFiles",
902 assert not GetConfFiles(admin, conf_file_ids)
903 print "=> []"
904
905 # Delete PCUs
906 for pcu in pcus:
907     pcu_id = pcu['pcu_id']
908
909     for node_id in pcu['node_ids']:
910         print "DeleteNodeFromPCU(%d, %d)" % (node_id, pcu_id),
911         DeleteNodeFromPCU(admin, node_id, pcu_id)
912         print "=> OK"
913
914     print "DeletePCU(%d)" % pcu_id,
915     DeletePCU(admin, pcu_id)
916     print "=> OK"
917
918 print "GetPCUs",
919 assert not GetPCUs(admin, pcu_ids)
920 print "=> []"
921     
922 # Delete node networks
923 for nodenetwork_id in nodenetwork_ids:
924     print "DeleteNodeNetwork(%d)" % nodenetwork_id,
925     DeleteNodeNetwork(admin, nodenetwork_id)
926     print "=>", "OK"
927
928 print "GetNodeNetworks",
929 assert not GetNodeNetworks(admin, nodenetwork_ids)
930 print "=> []"
931
932 # Delete nodes
933 for node_id in node_ids:
934     # Remove from node groups
935     for nodegroup_id in nodegroup_ids:
936         print "DeleteNodeFromNodeGroup(%d, %d)" % (node_id, nodegroup_id),
937         DeleteNodeFromNodeGroup(admin, node_id, nodegroup_id)
938         print "=> OK"
939     node = GetNodes(admin, [node_id])[0]
940     assert not node['nodegroup_ids']
941
942     # Delete node
943     print "DeleteNode(%d)" % node_id,
944     DeleteNode(admin, node_id)
945     assert not GetNodes(admin, [node_id])
946
947     # Make sure it really deleted it
948     nodes = GetNodes(admin, node_ids)
949     assert node_id not in [node['node_id'] for node in nodes]
950     print "=> OK"
951
952 print "GetNodes",
953 assert not GetNodes(admin, node_ids)
954 print "=> []"
955
956 nodegroups = GetNodeGroups(admin, nodegroup_ids)
957 for nodegroup in nodegroups:
958     assert not set(node_ids).intersection(nodegroup['node_ids'])
959
960 # Delete users
961 for person_id in person_ids:
962     # Delete keys
963     person = GetPersons(admin, [person_id])[0]
964     for key_id in person['key_ids']:
965         print "DeleteKey(%d)" % key_id,
966         DeleteKey(admin, key_id)
967         print "=> OK"
968     person = GetPersons(admin, [person_id])[0]
969     assert not person['key_ids']
970
971     # Remove from each site
972     for site_id in site_ids:
973         print "DeletePersonFromSite(%d, %d)" % (person_id, site_id),
974         DeletePersonFromSite(admin, person_id, site_id)
975         print "=> OK"
976     person = GetPersons(admin, [person_id])[0]
977     assert not person['site_ids']
978
979     # Revoke role
980     person = GetPersons(admin, [person_id])[0]
981     for role_id in person['role_ids']:
982         print "DeleteRoleFromPerson(%d, %d)" % (role_id, person_id),
983         DeleteRoleFromPerson(admin, role_id, person_id)
984         print "=> OK"
985     person = GetPersons(admin, [person_id])[0]
986     assert not person['role_ids']
987
988     # Disable account
989     UpdatePerson(admin, person_id, {'enabled': False})
990     person = GetPersons(admin, [person_id])[0]
991     assert not person['enabled']
992
993     # Delete account
994     print "DeletePerson(%d)" % person_id,
995     DeletePerson(admin, person_id)
996     assert not GetPersons(admin, [person_id])                         
997     print "=> OK"
998
999 print "GetPersons",
1000 assert not GetPersons(admin, person_ids)
1001 print "=> []"
1002
1003 # Delete node groups
1004 for nodegroup_id in nodegroup_ids:
1005     print "DeleteNodeGroup(%d)" % nodegroup_id,
1006     DeleteNodeGroup(admin, nodegroup_id)
1007     assert not GetNodeGroups(admin, [nodegroup_id])
1008     print "=> OK"
1009
1010 print "GetNodeGroups",
1011 assert not GetNodeGroups(admin, nodegroup_ids)
1012 print "=> []"
1013
1014 # Delete site addresses
1015 for address_id in address_ids:
1016     # Remove address types
1017     for address_type_id in address_type_ids:
1018         print "DeleteAddressTypeFromAddress(%d, %d)" % (address_type_id, address_id),
1019         DeleteAddressTypeFromAddress(admin, address_type_id, address_id)
1020         print "=> OK"
1021     address = GetAddresses(admin, [address_id])[0]
1022     assert not address['address_type_ids']
1023
1024     print "DeleteAddress(%d)" % address_id,
1025     DeleteAddress(admin, address_id)
1026     assert not GetAddresses(admin, [address_id])
1027     print "=> OK"
1028
1029 print "GetAddresss",
1030 assert not GetAddresses(admin, address_ids)
1031 print "=> []"
1032
1033 # Delete address types
1034 for address_type_id in address_type_ids:
1035     print "DeleteAddressType(%d)" % address_type_id,
1036     DeleteAddressType(admin, address_type_id)
1037     assert not GetAddressTypes(admin, [address_type_id])
1038     print "=> OK"
1039     
1040 print "GetAddressTypes",
1041 assert not GetAddressTypes(admin, address_type_ids)
1042 print "=> []"
1043
1044 # Delete sites
1045 for site_id in site_ids:
1046     print "DeleteSite(%d)" % site_id,
1047     DeleteSite(admin, site_id)
1048     assert not GetSites(admin, [site_id])
1049     print "=> OK"
1050
1051 print "GetSites",
1052 assert not GetSites(admin, site_ids)
1053 print "=> []"