- fix calling convention for Add() and Update()
[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: Test.py,v 1.11 2006/10/23 20:35:49 mlhuang Exp $
9 #
10
11 from pprint import pprint
12 from string import letters, digits, punctuation
13 import re
14 import socket
15 import struct
16
17 from random import Random
18 random = Random()
19
20 def randfloat(min = 0.0, max = 1.0):
21     return float(min) + (random.random() * (float(max) - float(min)))
22
23 def randint(min = 0, max = 1):
24     return int(randfloat(min, max + 1))
25
26 # See "2.2 Characters" in the XML specification:
27 #
28 # #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
29 # avoiding
30 # [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF]
31
32 low_xml_chars  = map(unichr, [0x9, 0xA, 0xD])
33 low_xml_chars += map(unichr, xrange(0x20, 0x7F - 1))
34 low_xml_chars += map(unichr, xrange(0x84 + 1, 0x86 - 1))
35 low_xml_chars += map(unichr, xrange(0x9F + 1, 0xFF))
36 valid_xml_chars  = list(low_xml_chars)
37 valid_xml_chars += map(unichr, xrange(0xFF + 1, 0xD7FF))
38 valid_xml_chars += map(unichr, xrange(0xE000, 0xFDD0 - 1))
39 valid_xml_chars += map(unichr, xrange(0xFDDF + 1, 0xFFFD))
40
41 def randstr(length, pool = valid_xml_chars, encoding = "utf-8"):
42     sample = random.sample(pool, min(length, len(pool)))
43     while True:
44         s = u''.join(sample)
45         bytes = len(s.encode(encoding))
46         if bytes > length:
47             sample.pop()
48         elif bytes < length:
49             sample += random.sample(pool, min(length - bytes, len(pool)))
50             random.shuffle(sample)
51         else:
52             break
53     return s
54
55 def randhostname():
56     # 1. Each part begins and ends with a letter or number.
57     # 2. Each part except the last can contain letters, numbers, or hyphens.
58     # 3. Each part is between 1 and 64 characters, including the trailing dot.
59     # 4. At least two parts.
60     # 5. Last part can only contain between 2 and 6 letters.
61     hostname = 'a' + randstr(61, letters + digits + '-') + '1.' + \
62                'b' + randstr(61, letters + digits + '-') + '2.' + \
63                'c' + randstr(5, letters)
64     return hostname
65
66 def unicmp(a, b, encoding = "utf-8"):
67     """
68     When connected directly to the DB, values are returned as raw
69     8-bit strings that may need to be decoded (as UTF-8 by default) in
70     order to compare them against expected Python Unicode strings.
71     """
72     
73     is8bit = re.compile("[\x80-\xff]").search
74     if isinstance(a, str) and is8bit(a):
75         a = unicode(a, encoding)
76     if isinstance(b, str) and is8bit(b):
77         b = unicode(b, encoding)
78     return a == b
79
80 admin = {'AuthMethod': "capability",
81          'Username': config.PLC_API_MAINTENANCE_USER,
82          'AuthString': config.PLC_API_MAINTENANCE_PASSWORD,
83          'Role': "admin"}
84
85 user = {'AuthMethod': "password",
86         'Role': "user"}
87
88 pi = {'AuthMethod': "password",
89       'Role': "pi"}
90
91 tech = {'AuthMethod': "password",
92         'Role': "tech"}
93
94 # Add sites
95 site_ids = []
96 for i in range(3):
97     def random_site():
98         return {
99             'name': randstr(254),
100             'abbreviated_name': randstr(50),
101             'login_base': randstr(20, letters).lower(),
102             'latitude': int(randfloat(-90.0, 90.0) * 1000) / 1000.0,
103             'longitude': int(randfloat(-180.0, 180.0) * 1000) / 1000.0,
104             }
105             
106     # Add site
107     site_fields = random_site()
108     print "AddSite",
109     site_id = AddSite(admin, site_fields)
110
111     # Should return a unique site_id
112     assert site_id not in site_ids
113     site_ids.append(site_id)
114     print "=>", site_id
115
116     # Check site
117     print "GetSites(%d)" % site_id,
118     site = GetSites(admin, [site_id])[0]
119     for key in site_fields:
120         assert unicmp(site[key], site_fields[key])
121     print "=> OK"
122
123     # Update site
124     site_fields = random_site()
125     # Currently cannot change login_base
126     del site_fields['login_base']
127     site_fields['max_slices'] = randint(1, 10)
128     print "UpdateSite(%d)" % site_id,
129     UpdateSite(admin, site_id, site_fields)
130     print "=> OK"
131
132     # Check site again
133     site = GetSites(admin, [site_id])[0]
134     for key in site_fields:
135         if key != 'login_base':
136             assert unicmp(site[key], site_fields[key])
137
138 print "GetSites",
139 sites = GetSites(admin, site_ids)
140 assert set(site_ids) == set([site['site_id'] for site in sites])
141 print "=>", site_ids
142
143 # Add address types
144 address_type_ids = []
145 for i in range(3):
146     def random_address_type():
147         return {
148             'name': randstr(20),
149             'description': randstr(254),
150             }
151
152     print "AddAddressType",
153     address_type_fields = random_address_type()
154     address_type_id = AddAddressType(admin, address_type_fields)
155
156     # Should return a unique address_type_id
157     assert address_type_id not in address_type_ids
158     address_type_ids.append(address_type_id)
159     print "=>", address_type_id
160
161     # Check address type
162     print "GetAddressTypes(%d)" % address_type_id,
163     address_type = GetAddressTypes(admin, [address_type_id])[0]
164     for key in 'name', 'description':
165         assert unicmp(address_type[key], address_type_fields[key])
166     print "=> OK"
167
168     # Update address type
169     address_type_fields = random_address_type()
170     print "UpdateAddressType(%d)" % address_type_id,
171     UpdateAddressType(admin, address_type_id, address_type_fields)
172     print "=> OK"
173
174     # Check address type again
175     address_type = GetAddressTypes(admin, [address_type_id])[0]
176     for key in 'name', 'description':
177         assert unicmp(address_type[key], address_type_fields[key])
178
179 print "GetAddressTypes",
180 address_types = GetAddressTypes(admin, address_type_ids)
181 assert set(address_type_ids) == set([address_type['address_type_id'] for address_type in address_types])
182 print "=>", address_type_ids
183
184 # Add site addresses
185 address_ids = []
186 for site_id in site_ids:
187     for i in range(3):
188         def random_address():
189             return {
190                 'line1': randstr(254),
191                 'line2': randstr(254),
192                 'line3': randstr(254),
193                 'city': randstr(254),
194                 'state': randstr(254),
195                 'postalcode': randstr(64),
196                 'country': randstr(128),
197                 }
198
199         print "AddSiteAddress",
200         address_fields = random_address()
201         address_id = AddSiteAddress(admin, site_id, address_fields)
202
203         # Should return a unique address_id
204         assert address_id not in address_ids
205         address_ids.append(address_id)
206         print "=>", address_id
207
208         # Check address
209         print "GetAddresses(%d)" % address_id,
210         address = GetAddresses(admin, [address_id])[0]
211         for key in address_fields:
212             assert unicmp(address[key], address_fields[key])
213         print "=> OK"
214
215         # Update address
216         address_fields = random_address()
217         print "UpdateAddress(%d)" % address_id,
218         UpdateAddress(admin, address_id, address_fields)
219         print "=> OK"
220
221         # Check address again
222         address = GetAddresses(admin, [address_id])[0]
223         for key in address_fields:
224             assert unicmp(address[key], address_fields[key])
225
226         # Add address types
227         for address_type_id in address_type_ids:
228             print "AddAddressTypeToAddress(%d, %d)" % (address_type_id, address_id),
229             AddAddressTypeToAddress(admin, address_type_id, address_id)
230             print "=> OK"
231         
232 print "GetAddresses",
233 addresses = GetAddresses(admin, address_ids)
234 assert set(address_ids) == set([address['address_id'] for address in addresses])
235 for address in addresses:
236     assert set(address_type_ids) == set(address['address_type_ids'])
237 print "=>", address_ids
238
239 print "GetRoles",
240 roles = GetRoles(admin)
241 role_ids = [role['role_id'] for role in roles]
242 roles = [role['name'] for role in roles]
243 roles = dict(zip(roles, role_ids))
244 print "=>", role_ids
245
246 # Add users
247 person_ids = []
248 for auth in user, pi, tech:
249     def random_person():
250         global auth
251
252         person_fields = {
253             'first_name': randstr(128),
254             'last_name': randstr(128),
255             # 119 + 1 + 64 + 64 + 6 = 254
256             'email': (randstr(119, letters + digits) + "@" + randhostname()).lower(),
257             'bio': randstr(254),
258             # Accounts are disabled by default
259             'enabled': False,
260             'password': randstr(254),
261             }
262
263         auth['Username'] = person_fields['email']
264         auth['AuthString'] = person_fields['password']
265
266         return person_fields
267
268     # Add account
269     person_fields = random_person()
270     print "AddPerson",
271     person_id = AddPerson(admin, person_fields)
272
273     # Should return a unique person_id
274     assert person_id not in person_ids
275     person_ids.append(person_id)
276     print "=>", person_id
277
278     # Check account
279     print "GetPersons(%d)" % person_id,
280     person = GetPersons(admin, [person_id])[0]
281     for key in person_fields:
282         if key != 'password':
283             assert unicmp(person[key], person_fields[key])
284     print "=> OK"
285
286     # Update account
287     person_fields = random_person()
288     print "UpdatePerson(%d)" % person_id,
289     UpdatePerson(admin, person_id, person_fields)
290     print "=> OK"
291
292     # Check account again
293     person = GetPersons(admin, [person_id])[0]
294     for key in person_fields:
295         if key != 'password':
296             assert unicmp(person[key], person_fields[key])
297
298     # Check that account is really disabled
299     try:
300         assert not AuthCheck(auth)
301     except:
302         pass
303
304     # Add role
305     role_id = roles[auth['Role']]
306     print "AddRoleToPerson(%d, %d)" % (role_id, person_id),
307     AddRoleToPerson(admin, role_id, person_id)
308     person = GetPersons(admin, [person_id])[0]
309     assert [role_id] == person['role_ids']
310     print "=> OK"
311
312     # Enable account
313     UpdatePerson(admin, person_id, {'enabled': True})
314
315     # Check authentication
316     print "AuthCheck(%s)" % auth['Username'],
317     assert AuthCheck(auth)
318     print "=> OK"
319
320     # Associate account with each site
321     for site_id in site_ids:
322         print "AddPersonToSite(%d, %d)" % (person_id, site_id),
323         AddPersonToSite(admin, person_id, site_id)
324         print "=> OK"
325
326     # Make sure it really did it
327     person = GetPersons(admin, [person_id])[0]
328     person_site_ids = person['site_ids']
329     assert set(site_ids) == set(person['site_ids'])
330
331     # First site should be the primary site
332     print "SetPersonPrimarySite(%d, %d)" % (person_id, person_site_ids[1]),
333     SetPersonPrimarySite(auth, person_id, person_site_ids[1])
334     person = GetPersons(admin, [person_id])[0]
335     assert person['site_ids'][0] == person_site_ids[1]
336     print "=> OK"
337
338 print "GetPersons",
339 persons = GetPersons(admin, person_ids)
340 assert set(person_ids) == set([person['person_id'] for person in persons])
341 print "=>", person_ids
342
343 # Add node groups
344 nodegroup_ids = []
345 for i in range(3):
346     def random_nodegroup():
347         return {
348             'name': randstr(50),
349             'description': randstr(200),
350             }
351
352     # Add node group
353     print "AddNodeGroup",
354     nodegroup_fields = random_nodegroup()
355     nodegroup_id = AddNodeGroup(admin, nodegroup_fields)
356
357     # Should return a unique nodegroup_id
358     assert nodegroup_id not in nodegroup_ids
359     nodegroup_ids.append(nodegroup_id)
360     print "=>", nodegroup_id
361
362     # Check node group
363     print "GetNodeGroups(%d)" % nodegroup_id,
364     nodegroup = GetNodeGroups(admin, [nodegroup_id])[0]
365     for key in nodegroup_fields:
366         assert unicmp(nodegroup[key], nodegroup_fields[key])
367     print "=> OK"
368
369     # Update node group, with a readable name
370     nodegroup_fields = random_nodegroup()
371     nodegroup_fields['name'] = randstr(16, letters + ' ' + digits)
372     print "UpdateNodeGroup",
373     UpdateNodeGroup(admin, nodegroup_id, nodegroup_fields)
374     print "=> OK"
375
376     # Check node group again
377     nodegroup = GetNodeGroups(admin, [nodegroup_id])[0]
378     for key in nodegroup_fields:
379         assert unicmp(nodegroup[key], nodegroup_fields[key])
380
381 print "GetNodeGroups",
382 nodegroups = GetNodeGroups(admin, nodegroup_ids)
383 assert set(nodegroup_ids) == set([nodegroup['nodegroup_id'] for nodegroup in nodegroups])
384 print "=>", nodegroup_ids
385
386 print "GetBootStates",
387 boot_states = GetBootStates(admin)
388 print "=>", boot_states
389
390 # Add nodes
391 node_ids = []
392 for site_id in site_ids:
393     for i in range(3):
394         def random_node():
395             return {
396                 'hostname': randhostname(),
397                 'boot_state': random.sample(boot_states, 1)[0],
398                 'model': randstr(255),
399                 'version': randstr(64),
400                 }
401
402         # Add node
403         node_fields = random_node()
404         print "AddNode",
405         node_id = AddNode(admin, site_id, node_fields)
406
407         # Should return a unique node_id
408         assert node_id not in node_ids
409         node_ids.append(node_id)
410         print "=>", node_id
411
412         # Check node
413         print "GetNodes(%d)" % node_id,
414         node = GetNodes(admin, [node_id])[0]
415         for key in node_fields:
416             assert unicmp(node[key], node_fields[key])
417         print "=> OK"
418
419         # Update node
420         node_fields = random_node()
421         print "UpdateNode(%d)" % node_id,
422         UpdateNode(admin, node_id, node_fields)
423         print "=> OK"
424
425         # Check node again
426         node = GetNodes(admin, [node_id])[0]
427         for key in node_fields:
428             assert unicmp(node[key], node_fields[key])
429
430         # Add to node groups
431         for nodegroup_id in nodegroup_ids:
432             print "AddNodeToNodeGroup(%d, %d)" % (nodegroup_id, node_id),
433             AddNodeToNodeGroup(admin, nodegroup_id, node_id)
434             print "=> OK"
435         
436 print "GetNodes",
437 nodes = GetNodes(admin, node_ids)
438 assert set(node_ids) == set([node['node_id'] for node in nodes])
439 print "=>", node_ids
440
441 print "GetNodeGroups",
442 nodegroups = GetNodeGroups(admin, nodegroup_ids)
443 for nodegroup in nodegroups:
444     assert set(nodegroup['node_ids']) == set(node_ids)
445 print "=> OK"
446
447 print "GetNetworkMethods",
448 network_methods = GetNetworkMethods(admin)
449 print "=>", network_methods
450
451 print "GetNetworkTypes",
452 network_types = GetNetworkTypes(admin)
453 print "=>", network_types
454
455 # Add node networks
456 nodenetwork_ids = []
457 for node_id in node_ids:
458     def random_nodenetwork(method, type):
459         nodenetwork_fields = {
460             'method': method,
461             'type': type,
462             'bwlimit': randint(500000, 10000000),
463             }
464
465         if method != 'dhcp':
466             ip = randint(0, 0xffffffff)
467             netmask = (0xffffffff << randint(2, 31)) & 0xffffffff
468             network = ip & netmask
469             broadcast = ((ip & netmask) | ~netmask) & 0xffffffff
470             gateway = randint(network + 1, broadcast - 1)
471             dns1 = randint(0, 0xffffffff)
472
473             for field in 'ip', 'netmask', 'network', 'broadcast', 'gateway', 'dns1':
474                 nodenetwork_fields[field] = socket.inet_ntoa(struct.pack('>L', locals()[field]))
475
476         return nodenetwork_fields
477
478     for method in network_methods:
479         for type in network_types:
480             # Add node network
481             print "AddNodeNetwork",
482             nodenetwork_fields = random_nodenetwork(method, type)
483             nodenetwork_id = AddNodeNetwork(admin, node_id, nodenetwork_fields)
484
485             # Should return a unique nodenetwork_id
486             assert nodenetwork_id not in nodenetwork_ids
487             nodenetwork_ids.append(nodenetwork_id)
488             print "=>", nodenetwork_id
489
490             # Check node network
491             print "GetNodeNetworks(%d)" % nodenetwork_id,
492             nodenetwork = GetNodeNetworks(admin, [nodenetwork_id])[0]
493             for key in nodenetwork_fields:
494                 assert unicmp(nodenetwork[key], nodenetwork_fields[key])
495             print "=> OK"
496
497             # Update node network
498             nodenetwork_fields = random_nodenetwork(method, type)
499             print "UpdateNodeNetwork(%d)" % nodenetwork_id,
500             UpdateNodeNetwork(admin, nodenetwork_id, nodenetwork_fields)
501             print "=> OK"
502
503             # Check node network again
504             nodenetwork = GetNodeNetworks(admin, [nodenetwork_id])[0]
505             for key in nodenetwork_fields:
506                 assert unicmp(nodenetwork[key], nodenetwork_fields[key])
507
508 print "GetNodeNetworks",
509 nodenetworks = GetNodeNetworks(admin, nodenetwork_ids)
510 assert set(nodenetwork_ids) == set([nodenetwork['nodenetwork_id'] for nodenetwork in nodenetworks])
511 print "=>", nodenetwork_ids
512
513 # Add slice attribute types
514 attribute_type_ids = []
515 for i in range(3):
516     def random_attribute_type():
517         return {
518             'name': randstr(100),
519             'description': randstr(254),
520             'min_role_id': random.sample(roles.values(), 1)[0],
521             }
522
523     # Add slice attribute type
524     attribute_type_fields = random_attribute_type()
525     print "AddSliceAttributeType",
526     attribute_type_id = AddSliceAttributeType(admin, attribute_type_fields)
527
528     # Should return a unique attribute_type_id
529     assert attribute_type_id not in attribute_type_ids
530     attribute_type_ids.append(attribute_type_id)
531     print "=>", attribute_type_id
532
533     # Check slice attribute type
534     print "GetSliceAttributeTypes(%d)" % attribute_type_id,
535     attribute_type = GetSliceAttributeTypes(admin, [attribute_type_id])[0]
536     for key in attribute_type_fields:
537         assert unicmp(attribute_type[key], attribute_type_fields[key])
538     print "=> OK"
539
540     # Update slice attribute type
541     attribute_type_fields = random_attribute_type()
542     print "UpdateSliceAttributeType(%d)" % attribute_type_id,
543     UpdateSliceAttributeType(admin, attribute_type_id, attribute_type_fields)
544     print "=> OK"
545
546     # Check slice attribute type again
547     attribute_type = GetSliceAttributeTypes(admin, [attribute_type_id])[0]
548     for key in attribute_type_fields:
549         assert unicmp(attribute_type[key], attribute_type_fields[key])
550
551 # Add slices and slice attributes
552 slice_ids = []
553 slice_attribute_ids = []
554 for site in sites:
555     for i in range(site['max_slices']):
556         def random_slice():
557             return {
558                 'name': site['login_base'] + "_" + randstr(11, letters).lower(),
559                 'url': "http://" + randhostname() + "/",
560                 'description': randstr(2048),
561                 }
562
563         # Add slice
564         slice_fields = random_slice()
565         print "AddSlice",
566         slice_id = AddSlice(admin, slice_fields)
567
568         # Should return a unique slice_id
569         assert slice_id not in slice_ids
570         slice_ids.append(slice_id)
571         print "=>", slice_id
572
573         # Check slice
574         print "GetSlices(%d)" % slice_id,
575         slice = GetSlices(admin, [slice_id])[0]
576         for key in slice_fields:
577             assert unicmp(slice[key], slice_fields[key])
578         print "=> OK"
579
580         # Update slice
581         slice_fields = random_slice()
582         # Cannot change slice name
583         del slice_fields['name']
584         print "UpdateSlice(%d)" % slice_id,
585         UpdateSlice(admin, slice_id, slice_fields)
586         slice = GetSlices(admin, [slice_id])[0]
587         for key in slice_fields:
588             assert unicmp(slice[key], slice_fields[key])
589         print "=> OK"
590
591         # Add slice to all nodes
592         print "AddSliceToNodes(%d, %s)" % (slice_id, str(node_ids)),
593         AddSliceToNodes(admin, slice_id, node_ids)
594         slice = GetSlices(admin, [slice_id])[0]
595         assert set(node_ids) == set(slice['node_ids'])
596         print "=> OK"
597
598         # Add users to slice
599         for person_id in person_ids:
600             print "AddPersonToSlice(%d, %d)" % (person_id, slice_id),
601             AddPersonToSlice(admin, person_id, slice_id)
602             print "=> OK" 
603         slice = GetSlices(admin, [slice_id])[0]
604         assert set(person_ids) == set(slice['person_ids'])
605
606         # Set slice/sliver attributes
607         for attribute_type_id in attribute_type_ids:
608             value = randstr(16, letters + '_' + digits)
609             # Make it a sliver attribute with 50% probability
610             node_id = random.sample(node_ids + [None] * len(node_ids), 1)[0]
611
612             # Add slice attribute
613             print "AddSliceAttribute(%d, %d)" % (slice_id, attribute_type_id),
614             if node_id is None:
615                 slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value)
616             else:
617                 slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value, node_id)
618
619             # Should return a unique slice_attribute_id
620             assert slice_attribute_id not in slice_attribute_ids
621             slice_attribute_ids.append(slice_attribute_id)
622             print "=>", slice_attribute_id
623
624             # Check slice attribute
625             print "GetSliceAttributes(%d)" % slice_attribute_id,
626             slice_attribute = GetSliceAttributes(admin, [slice_attribute_id])[0]
627             for key in 'attribute_type_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value':
628                 assert unicmp(slice_attribute[key], locals()[key])
629             print "=> OK"
630
631             # Update slice attribute
632             value = randstr(16, letters + '_' + digits)
633             print "UpdateSliceAttribute(%d)" % slice_attribute_id,
634             UpdateSliceAttribute(admin, slice_attribute_id, value)
635             slice_attribute = GetSliceAttributes(admin, [slice_attribute_id])[0]
636             for key in 'attribute_type_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value':
637                 assert unicmp(slice_attribute[key], locals()[key])
638             print "=> OK"
639
640 # Delete slices
641 for slice_id in slice_ids:
642     # Delete slice attributes
643     slice = GetSlices(admin, [slice_id])[0]
644     for slice_attribute_id in slice['slice_attribute_ids']:
645         print "DeleteSliceAttribute(%d, %d)" % (slice_id, slice_attribute_id),
646         DeleteSliceAttribute(admin, slice_attribute_id)
647         print "=> OK"
648     slice = GetSlices(admin, [slice_id])[0]
649     assert not slice['slice_attribute_ids']
650
651     # Delete users from slice
652     for person_id in person_ids:
653         print "DeletePersonFromSlice(%d, %d)" % (person_id, slice_id),
654         DeletePersonFromSlice(admin, person_id, slice_id)
655         print "=> OK"
656     slice = GetSlices(admin, [slice_id])[0]
657     assert not slice['person_ids']
658
659     # Delete nodes from slice
660     print "DeleteSliceFromNodes(%d, %s)" % (slice_id, node_ids),
661     DeleteSliceFromNodes(admin, slice_id, node_ids)
662     print "=> OK"
663     slice = GetSlices(admin, [slice_id])[0]
664     assert not slice['node_ids']
665
666     # Delete slice
667     print "DeleteSlice(%d)" % slice_id,
668     DeleteSlice(admin, slice_id)
669     assert not GetSlices(admin, [slice_id])
670
671     # Make sure it really deleted it
672     slices = GetSlices(admin, slice_ids)
673     assert slice_id not in [slice['slice_id'] for slice in slices]
674     print "=> OK"
675
676 print "GetSlices",
677 assert not GetSlices(admin, slice_ids)
678 print "=> []"
679
680 # Delete slice attribute types
681 for attribute_type_id in attribute_type_ids:
682     # Delete slice attribute type
683     print "DeleteSliceAttributeType(%d)" % attribute_type_id,
684     DeleteSliceAttributeType(admin, attribute_type_id)
685     assert not GetSliceAttributeTypes(admin, [attribute_type_id])
686
687     # Make sure it really deleted it
688     attribute_types = GetSliceAttributeTypes(admin, attribute_type_ids)
689     assert attribute_type_id not in [attribute_type['attribute_type_id'] for attribute_type in attribute_types]
690     print "=> OK"
691
692 print "GetSliceAttributeTypes",
693 assert not GetSliceAttributeTypes(admin, attribute_type_ids)
694 print "=> []"
695
696 # Delete node networks
697 for nodenetwork_id in nodenetwork_ids:
698     print "DeleteNodeNetwork(%d)" % nodenetwork_id,
699     DeleteNodeNetwork(admin, nodenetwork_id)
700     print "=>", "OK"
701
702 print "GetNodeNetworks",
703 assert not GetNodeNetworks(admin, nodenetwork_ids)
704 print "=> []"
705
706 # Delete nodes
707 for node_id in node_ids:
708     # Remove from node groups
709     for nodegroup_id in nodegroup_ids:
710         print "DeleteNodeFromNodeGroup(%d, %d)" % (nodegroup_id, node_id),
711         DeleteNodeFromNodeGroup(admin, nodegroup_id, node_id)
712         print "=> OK"
713     node = GetNodes(admin, [node_id])[0]
714     assert not node['nodegroup_ids']
715
716     # Delete node
717     print "DeleteNode(%d)" % node_id,
718     DeleteNode(admin, node_id)
719     assert not GetNodes(admin, [node_id])
720
721     # Make sure it really deleted it
722     nodes = GetNodes(admin, node_ids)
723     assert node_id not in [node['node_id'] for node in nodes]
724     print "=> OK"
725
726 print "GetNodes",
727 assert not GetNodes(admin, node_ids)
728 print "=> []"
729
730 nodegroups = GetNodeGroups(admin, nodegroup_ids)
731 for nodegroup in nodegroups:
732     assert not set(node_ids).intersection(nodegroup['node_ids'])
733
734 # Delete users
735 for person_id in person_ids:
736     # Remove from each site
737     for site_id in site_ids:
738         print "DeletePersonFromSite(%d, %d)" % (person_id, site_id),
739         DeletePersonFromSite(admin, person_id, site_id)
740         print "=> OK"
741     person = GetPersons(admin, [person_id])[0]
742     assert not person['site_ids']
743
744     # Revoke role
745     person = GetPersons(admin, [person_id])[0]
746     for role_id in person['role_ids']:
747         print "DeleteRoleFromPerson(%d, %d)" % (role_id, person_id),
748         DeleteRoleFromPerson(admin, role_id, person_id)
749         print "=> OK"
750     person = GetPersons(admin, [person_id])[0]
751     assert not person['role_ids']
752
753     # Disable account
754     UpdatePerson(admin, person_id, {'enabled': False})
755     person = GetPersons(admin, [person_id])[0]
756     assert not person['enabled']
757
758     # Delete account
759     print "DeletePerson(%d)" % person_id,
760     DeletePerson(admin, person_id)
761     assert not GetPersons(admin, [person_id])                         
762     print "=> OK"
763
764 print "GetPersons",
765 assert not GetPersons(admin, person_ids)
766 print "=> []"
767
768 # Delete node groups
769 for nodegroup_id in nodegroup_ids:
770     print "DeleteNodeGroup(%d)" % nodegroup_id,
771     DeleteNodeGroup(admin, nodegroup_id)
772     assert not GetNodeGroups(admin, [nodegroup_id])
773     print "=> OK"
774
775 print "GetNodeGroups",
776 assert not GetNodeGroups(admin, nodegroup_ids)
777 print "=> []"
778
779 # Delete site addresses
780 for address_id in address_ids:
781     # Remove address types
782     for address_type_id in address_type_ids:
783         print "DeleteAddressTypeFromAddress(%d, %d)" % (address_type_id, address_id),
784         DeleteAddressTypeFromAddress(admin, address_type_id, address_id)
785         print "=> OK"
786     address = GetAddresses(admin, [address_id])[0]
787     assert not address['address_type_ids']
788
789     print "DeleteAddress(%d)" % address_id,
790     DeleteAddress(admin, address_id)
791     assert not GetAddresses(admin, [address_id])
792     print "=> OK"
793
794 print "GetAddresss",
795 assert not GetAddresses(admin, address_ids)
796 print "=> []"
797
798 # Delete address types
799 for address_type_id in address_type_ids:
800     print "DeleteAddressType(%d)" % address_type_id,
801     DeleteAddressType(admin, address_type_id)
802     assert not GetAddressTypes(admin, [address_type_id])
803     print "=> OK"
804     
805 print "GetAddressTypes",
806 assert not GetAddressTypes(admin, address_type_ids)
807 print "=> []"
808
809 # Delete sites
810 for site_id in site_ids:
811     print "DeleteSite(%d)" % site_id,
812     DeleteSite(admin, site_id)
813     assert not GetSites(admin, [site_id])
814     print "=> OK"
815
816 print "GetSites",
817 assert not GetSites(admin, site_ids)
818 print "=> []"