1 #!/usr/bin/env ./Shell.py
5 # Mark Huang <mlhuang@cs.princeton.edu>
6 # Copyright (C) 2006 The Trustees of Princeton University
8 # $Id: Test.py,v 1.11 2006/10/23 20:35:49 mlhuang Exp $
11 from pprint import pprint
12 from string import letters, digits, punctuation
17 from random import Random
20 def randfloat(min = 0.0, max = 1.0):
21 return float(min) + (random.random() * (float(max) - float(min)))
23 def randint(min = 0, max = 1):
24 return int(randfloat(min, max + 1))
26 # See "2.2 Characters" in the XML specification:
28 # #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
30 # [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF]
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))
41 def randstr(length, pool = valid_xml_chars, encoding = "utf-8"):
42 sample = random.sample(pool, min(length, len(pool)))
45 bytes = len(s.encode(encoding))
49 sample += random.sample(pool, min(length - bytes, len(pool)))
50 random.shuffle(sample)
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)
66 def unicmp(a, b, encoding = "utf-8"):
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.
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)
80 admin = {'AuthMethod': "capability",
81 'Username': config.PLC_API_MAINTENANCE_USER,
82 'AuthString': config.PLC_API_MAINTENANCE_PASSWORD,
85 user = {'AuthMethod': "password",
88 pi = {'AuthMethod': "password",
91 tech = {'AuthMethod': "password",
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,
107 site_fields = random_site()
109 site_id = AddSite(admin, site_fields)
111 # Should return a unique site_id
112 assert site_id not in site_ids
113 site_ids.append(site_id)
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])
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)
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])
139 sites = GetSites(admin, site_ids)
140 assert set(site_ids) == set([site['site_id'] for site in sites])
144 address_type_ids = []
146 def random_address_type():
149 'description': randstr(254),
152 print "AddAddressType",
153 address_type_fields = random_address_type()
154 address_type_id = AddAddressType(admin, address_type_fields)
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
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])
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)
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])
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
186 for site_id in site_ids:
188 def random_address():
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),
199 print "AddSiteAddress",
200 address_fields = random_address()
201 address_id = AddSiteAddress(admin, site_id, address_fields)
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
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])
216 address_fields = random_address()
217 print "UpdateAddress(%d)" % address_id,
218 UpdateAddress(admin, address_id, address_fields)
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])
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)
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
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))
248 for auth in user, pi, tech:
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(),
258 # Accounts are disabled by default
260 'password': randstr(254),
263 auth['Username'] = person_fields['email']
264 auth['AuthString'] = person_fields['password']
269 person_fields = random_person()
271 person_id = AddPerson(admin, person_fields)
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
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])
287 person_fields = random_person()
288 print "UpdatePerson(%d)" % person_id,
289 UpdatePerson(admin, person_id, person_fields)
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])
298 # Check that account is really disabled
300 assert not AuthCheck(auth)
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']
313 UpdatePerson(admin, person_id, {'enabled': True})
315 # Check authentication
316 print "AuthCheck(%s)" % auth['Username'],
317 assert AuthCheck(auth)
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)
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'])
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]
339 persons = GetPersons(admin, person_ids)
340 assert set(person_ids) == set([person['person_id'] for person in persons])
341 print "=>", person_ids
346 def random_nodegroup():
349 'description': randstr(200),
353 print "AddNodeGroup",
354 nodegroup_fields = random_nodegroup()
355 nodegroup_id = AddNodeGroup(admin, nodegroup_fields)
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
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])
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)
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])
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
386 print "GetBootStates",
387 boot_states = GetBootStates(admin)
388 print "=>", boot_states
392 for site_id in site_ids:
396 'hostname': randhostname(),
397 'boot_state': random.sample(boot_states, 1)[0],
398 'model': randstr(255),
399 'version': randstr(64),
403 node_fields = random_node()
405 node_id = AddNode(admin, site_id, node_fields)
407 # Should return a unique node_id
408 assert node_id not in node_ids
409 node_ids.append(node_id)
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])
420 node_fields = random_node()
421 print "UpdateNode(%d)" % node_id,
422 UpdateNode(admin, node_id, node_fields)
426 node = GetNodes(admin, [node_id])[0]
427 for key in node_fields:
428 assert unicmp(node[key], node_fields[key])
431 for nodegroup_id in nodegroup_ids:
432 print "AddNodeToNodeGroup(%d, %d)" % (nodegroup_id, node_id),
433 AddNodeToNodeGroup(admin, nodegroup_id, node_id)
437 nodes = GetNodes(admin, node_ids)
438 assert set(node_ids) == set([node['node_id'] for node in nodes])
441 print "GetNodeGroups",
442 nodegroups = GetNodeGroups(admin, nodegroup_ids)
443 for nodegroup in nodegroups:
444 assert set(nodegroup['node_ids']) == set(node_ids)
447 print "GetNetworkMethods",
448 network_methods = GetNetworkMethods(admin)
449 print "=>", network_methods
451 print "GetNetworkTypes",
452 network_types = GetNetworkTypes(admin)
453 print "=>", network_types
457 for node_id in node_ids:
458 def random_nodenetwork(method, type):
459 nodenetwork_fields = {
462 'bwlimit': randint(500000, 10000000),
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)
473 for field in 'ip', 'netmask', 'network', 'broadcast', 'gateway', 'dns1':
474 nodenetwork_fields[field] = socket.inet_ntoa(struct.pack('>L', locals()[field]))
476 return nodenetwork_fields
478 for method in network_methods:
479 for type in network_types:
481 print "AddNodeNetwork",
482 nodenetwork_fields = random_nodenetwork(method, type)
483 nodenetwork_id = AddNodeNetwork(admin, node_id, nodenetwork_fields)
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
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])
497 # Update node network
498 nodenetwork_fields = random_nodenetwork(method, type)
499 print "UpdateNodeNetwork(%d)" % nodenetwork_id,
500 UpdateNodeNetwork(admin, nodenetwork_id, nodenetwork_fields)
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])
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
513 # Add slice attribute types
514 attribute_type_ids = []
516 def random_attribute_type():
518 'name': randstr(100),
519 'description': randstr(254),
520 'min_role_id': random.sample(roles.values(), 1)[0],
523 # Add slice attribute type
524 attribute_type_fields = random_attribute_type()
525 print "AddSliceAttributeType",
526 attribute_type_id = AddSliceAttributeType(admin, attribute_type_fields)
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
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])
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)
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])
551 # Add slices and slice attributes
553 slice_attribute_ids = []
555 for i in range(site['max_slices']):
558 'name': site['login_base'] + "_" + randstr(11, letters).lower(),
559 'url': "http://" + randhostname() + "/",
560 'description': randstr(2048),
564 slice_fields = random_slice()
566 slice_id = AddSlice(admin, slice_fields)
568 # Should return a unique slice_id
569 assert slice_id not in slice_ids
570 slice_ids.append(slice_id)
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])
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])
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'])
599 for person_id in person_ids:
600 print "AddPersonToSlice(%d, %d)" % (person_id, slice_id),
601 AddPersonToSlice(admin, person_id, slice_id)
603 slice = GetSlices(admin, [slice_id])[0]
604 assert set(person_ids) == set(slice['person_ids'])
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]
612 # Add slice attribute
613 print "AddSliceAttribute(%d, %d)" % (slice_id, attribute_type_id),
615 slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value)
617 slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value, node_id)
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
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])
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])
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)
648 slice = GetSlices(admin, [slice_id])[0]
649 assert not slice['slice_attribute_ids']
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)
656 slice = GetSlices(admin, [slice_id])[0]
657 assert not slice['person_ids']
659 # Delete nodes from slice
660 print "DeleteSliceFromNodes(%d, %s)" % (slice_id, node_ids),
661 DeleteSliceFromNodes(admin, slice_id, node_ids)
663 slice = GetSlices(admin, [slice_id])[0]
664 assert not slice['node_ids']
667 print "DeleteSlice(%d)" % slice_id,
668 DeleteSlice(admin, slice_id)
669 assert not GetSlices(admin, [slice_id])
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]
677 assert not GetSlices(admin, slice_ids)
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])
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]
692 print "GetSliceAttributeTypes",
693 assert not GetSliceAttributeTypes(admin, attribute_type_ids)
696 # Delete node networks
697 for nodenetwork_id in nodenetwork_ids:
698 print "DeleteNodeNetwork(%d)" % nodenetwork_id,
699 DeleteNodeNetwork(admin, nodenetwork_id)
702 print "GetNodeNetworks",
703 assert not GetNodeNetworks(admin, nodenetwork_ids)
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)
713 node = GetNodes(admin, [node_id])[0]
714 assert not node['nodegroup_ids']
717 print "DeleteNode(%d)" % node_id,
718 DeleteNode(admin, node_id)
719 assert not GetNodes(admin, [node_id])
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]
727 assert not GetNodes(admin, node_ids)
730 nodegroups = GetNodeGroups(admin, nodegroup_ids)
731 for nodegroup in nodegroups:
732 assert not set(node_ids).intersection(nodegroup['node_ids'])
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)
741 person = GetPersons(admin, [person_id])[0]
742 assert not person['site_ids']
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)
750 person = GetPersons(admin, [person_id])[0]
751 assert not person['role_ids']
754 UpdatePerson(admin, person_id, {'enabled': False})
755 person = GetPersons(admin, [person_id])[0]
756 assert not person['enabled']
759 print "DeletePerson(%d)" % person_id,
760 DeletePerson(admin, person_id)
761 assert not GetPersons(admin, [person_id])
765 assert not GetPersons(admin, person_ids)
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])
775 print "GetNodeGroups",
776 assert not GetNodeGroups(admin, nodegroup_ids)
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)
786 address = GetAddresses(admin, [address_id])[0]
787 assert not address['address_type_ids']
789 print "DeleteAddress(%d)" % address_id,
790 DeleteAddress(admin, address_id)
791 assert not GetAddresses(admin, [address_id])
795 assert not GetAddresses(admin, address_ids)
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])
805 print "GetAddressTypes",
806 assert not GetAddressTypes(admin, address_type_ids)
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])
817 assert not GetSites(admin, site_ids)