X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=system%2Fplcsh_stress_test.py;h=fea09afabcececb09755e42eb1632f1c728a2fc4;hb=a9e5d3afadff87fa868bd6c2e6c2dd31ae80f816;hp=d3c0f695da28e36eeac63c9e10e78d8e4179e846;hpb=36361a21a686c14025ffecb80553525427b24a7a;p=tests.git diff --git a/system/plcsh_stress_test.py b/system/plcsh_stress_test.py index d3c0f69..fea09af 100755 --- a/system/plcsh_stress_test.py +++ b/system/plcsh_stress_test.py @@ -5,7 +5,11 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id$ + +# NOTE on porting to python3 +# +# this file gets fed to plcsh on the tested myplc, so +# it needs to remain python2 for now # from pprint import pprint @@ -79,7 +83,7 @@ def randhostname(namelengths): hostname = 'a' + randstr(namelengths['hostname1'], letters + digits + '-') + '1.' + \ 'b' + randstr(namelengths['hostname1'], letters + digits + '-') + '2.' + \ 'c' + randstr(namelengths['hostname2'], letters) - return hostname + return hostname.lower() def randpath(length): parts = [] @@ -97,16 +101,21 @@ def randkey(namelengths,bits = 2048): base64.b64encode(''.join(randstr(bits / 8).encode("utf-8"))), randemail(namelengths)]) +def random_peer(): + return { + 'peername': randstr(24,letters + ' ' + digits), + 'peer_url': "https://" + randhostname ({'hostname1':8,'hostname2':3}) + ":443/PLCAPI/", + 'key' : randstr(1024,letters+digits), + 'cacert' : randstr(1024,letters+digits), + 'shortname' : randstr(1,letters) + 'LAB', + 'hrn_root' : 'planetlab.' + randstr (3,letters), + } + def random_site(namelengths): - try: - sitename=randstr(namelengths['sitename'],namelengths['sitename_contents']) - except: - sitename=randstr(namelengths['sitename']) - try: - abbreviated_name=randstr(namelengths['abbreviated_name'],namelengths['abbreviated_name_contents']) - except: - abbreviated_name=randstr(namelengths['abbreviated_name']) + sitename=randstr(namelengths['sitename'],namelengths['sitename_contents']) + abbreviated_name=randstr(namelengths['abbreviated_name'],namelengths['abbreviated_name_contents']) + print 'nl[a] in random_site',namelengths['abbreviated_name'],'actual',len(abbreviated_name) return { 'name': sitename, 'abbreviated_name': abbreviated_name, @@ -150,14 +159,17 @@ def random_key(key_types,namelengths): } def random_tag_type (role_ids): - return {'tagname': randstr(12), - 'category':randstr(8), - 'min_role_id': random.sample(role_ids, 1)[0], - 'description' : randstr(128), + return {'tagname': randstr(12,letters+digits), + 'category':randstr(4,letters+digits)+'/'+randstr(6,letters+digits), + 'description' : randstr(128,letters+digits+whitespace+punctuation), } def random_nodegroup(): - return {'groupname' : randstr(50) } + return {'groupname' : randstr(30, letters+digits+whitespace) } + +def random_roles(role_ids): + nb_roles=len(role_ids) + return random.sample(role_ids,random.choice(range(1,nb_roles+1))) tag_fields=['arch'] def random_node(node_types,boot_states,namelengths): @@ -171,7 +183,7 @@ def random_node(node_types,boot_states,namelengths): 'arch':randstr(10), } -def random_interface(method, type): +def random_interface(method, type,namelengths): interface_fields = { 'method': method, 'type': type, @@ -188,6 +200,8 @@ def random_interface(method, type): for field in 'ip', 'netmask', 'network', 'broadcast', 'gateway', 'dns1': interface_fields[field] = socket.inet_ntoa(struct.pack('>L', locals()[field])) + if randint(0,1): + interface_fields['hostname']=randhostname(namelengths); return interface_fields @@ -262,12 +276,48 @@ class Test: 'attributes_per_slice': 2, } + sizes_large = { + 'sites': 200, + 'address_types': 4, + 'addresses_per_site': 2, + 'persons_per_site': 5, + 'keys_per_person': 2, + 'slice_tags': 4, + 'nodegroups': 20, + 'nodes_per_site': 2, + 'interfaces_per_node': 2, + 'ilinks':100, + 'pcus_per_site': 1, + 'conf_files': 50, + 'slices_per_site': 10, + 'attributes_per_slice': 4, + } + + sizes_xlarge = { + 'sites': 1000, + 'address_types': 4, + 'addresses_per_site': 2, + 'persons_per_site': 5, + 'keys_per_person': 2, + 'slice_tags': 4, + 'nodegroups': 20, + 'nodes_per_site': 2, + 'interfaces_per_node': 2, + 'ilinks':100, + 'pcus_per_site': 1, + 'conf_files': 50, + 'slices_per_site': 10, + 'attributes_per_slice': 4, + } + namelengths_default = { 'hostname1': 61, 'hostname2':5, 'login_base':20, 'sitename':254, + 'sitename_contents':letters+digits, 'abbreviated_name':50, + 'abbreviated_name_contents':letters+digits+whitespace+punctuation, 'model':255, 'first_name':128, 'last_name':128, @@ -275,11 +325,11 @@ class Test: } namelengths_short = { - 'hostname1': 12, + 'hostname1': 8, 'hostname2':3, 'login_base':8, 'sitename':64, - 'sitename_contents':letters+digits+whitespace+punctuation, + 'sitename_contents':letters+digits, 'abbreviated_name':24, 'abbreviated_name_contents':letters+digits+whitespace+punctuation, 'model':40, @@ -288,11 +338,12 @@ class Test: 'email':24, } - def __init__(self, api, check = True, verbose = True, preserve = False): + def __init__(self, api, check, verbose, preserve, federating): self.api = api self.check = check self.verbose = verbose self.preserve = preserve + self.federating = federating self.site_ids = [] self.address_type_ids = [] @@ -335,10 +386,12 @@ class Test: print 'Cardinals before test (n,s,p,sl)',cardinals_before self.Add(**kwds) - self.Update() - if self.preserve: - print 'Preserving - delete skipped' + # if federating : we're done + + if self.federating or self.preserve: + print 'Preserving - update & delete skipped' else: + self.Update() self.Delete() cardinals_after=self.Cardinals() @@ -357,20 +410,32 @@ class Test: sizes = self.sizes_default.copy() sizes.update(kwds) - self.AddSites(sizes['sites']) - self.AddAddressTypes(sizes['address_types']) - self.AddAddresses(sizes['addresses_per_site']) - self.AddPersons(sizes['persons_per_site']) - self.AddKeys(sizes['keys_per_person']) - self.AddTagTypes(sizes['slice_tags'],sizes['nodegroups'],sizes['ilinks']) - self.AddNodeGroups(sizes['nodegroups']) - self.AddNodes(sizes['nodes_per_site']) - self.AddInterfaces(sizes['interfaces_per_node']) - self.AddIlinks (sizes['ilinks']) - self.AddPCUs(sizes['pcus_per_site']) - self.AddConfFiles(sizes['conf_files']) - self.AddSlices(sizes['slices_per_site']) - self.AddSliceTags(sizes['attributes_per_slice']) + if not self.federating: + self.AddSites(sizes['sites']) + self.AddAddressTypes(sizes['address_types']) + self.AddAddresses(sizes['addresses_per_site']) + self.AddPersons(sizes['persons_per_site']) + self.AddKeys(sizes['keys_per_person']) + self.AddTagTypes(sizes['slice_tags'],sizes['nodegroups'],sizes['ilinks']) + self.AddNodeGroups(sizes['nodegroups']) + self.AddNodes(sizes['nodes_per_site']) + self.AddInterfaces(sizes['interfaces_per_node']) + self.AddIlinks (sizes['ilinks']) + self.AddPCUs(sizes['pcus_per_site']) + self.AddConfFiles(sizes['conf_files']) + self.AddSlices(sizes['slices_per_site']) + self.AddSliceTags(sizes['attributes_per_slice']) + + else: + self.RecordStatus() + self.AddSites(sizes['sites']) + self.AddPersons(sizes['persons_per_site']) + self.AddKeys(sizes['keys_per_person']) + self.AddNodes(sizes['nodes_per_site']) + self.AddSlices(sizes['slices_per_site']) + # create peer and add newly created entities + self.AddPeer() + def Update(self): self.UpdateSites() @@ -404,6 +469,33 @@ class Test: self.DeleteAddressTypes() self.DeleteSites() + # record current (old) objects + def RecordStatus (self): + self.old_site_ids = [ s['site_id'] for s in self.api.GetSites({},['site_id']) ] + self.old_person_ids = [ s['person_id'] for s in self.api.GetPersons({},['person_id']) ] + self.old_key_ids = [ s['key_id'] for s in self.api.GetKeys({},['key_id']) ] + self.old_node_ids = [ s['node_id'] for s in self.api.GetNodes({},['node_id']) ] + self.old_slice_ids = [ s['slice_id'] for s in self.api.GetSlices({},['slice_id']) ] + + def AddPeer (self): + peer_id=self.api.AddPeer (random_peer()) + peer = GetPeers([peer_id])[0] + if self.verbose: + print "Added peer",peer_id + + # add new sites (the ones not in self.site_ids) in the peer + # cheating a bit + for site in self.api.GetSites ({'~site_id':self.old_site_ids}): + peer.add_site(site,site['site_id']) + for person in self.api.GetPersons ({'~person_id':self.old_person_ids}): + peer.add_person(person,person['person_id']) + for key in self.api.GetKeys ({'~key_id':self.old_key_ids}): + peer.add_key(key,key['key_id']) + for node in self.api.GetNodes ({'~node_id':self.old_node_ids}): + peer.add_node(node,node['node_id']) + for slice in self.api.GetSlices ({'~slice_id':self.old_slice_ids}): + peer.add_slice(slice,slice['slice_id']) + def AddSites(self, n = 10): """ Add a number of random sites. @@ -996,8 +1088,7 @@ class Test: raise Exception, "Unexpected field %s in node after GetNodes()"%field assert set(nodegroup_ids) == set(node['nodegroup_ids']) - print 'WARNING: skipping updatenode with tags as this is not implemented yet' - # again when fetching 'arch' explicitly + # again but we are now fetching 'arch' explicitly node2 = self.api.GetNodes([node_id],node_fields.keys())[0] for field in node_fields: if node2[field] != node_fields[field]: @@ -1014,7 +1105,7 @@ class Test: for node_id in self.node_ids: # Remove from node groups node = self.api.GetNodes([node_id])[0] - for node_tag in GetNodeTags ( {'node_id': node_id} ): + for node_tag in self.api.GetNodeTags ( {'node_id': node_id} ): self.api.UpdateNodeTag(node_tag['node_tag_id'],'') if self.check: @@ -1053,7 +1144,7 @@ class Test: type = random.sample(network_types, 1)[0] # Add interface - interface_fields = random_interface(method, type) + interface_fields = random_interface(method, type,self.namelengths) interface_id = self.api.AddInterface(node_id, interface_fields) # Should return a unique interface_id @@ -1087,7 +1178,7 @@ class Test: type = random.sample(network_types, 1)[0] # Update interface - interface_fields = random_interface(method, type) + interface_fields = random_interface(method, type,self.namelengths) self.api.UpdateInterface(interface_id, interface_fields) if self.check: @@ -1369,6 +1460,10 @@ class Test: self.nodegroup_type_ids + \ self.ilink_type_ids + tt_role_ids=random_roles(role_ids) + for tt_role_id in tt_role_ids: + self.api.AddRoleToTagType(tt_role_id,tag_type_id) + if i < n_sa: self.slice_type_ids.append(tag_type_id) elif i < n_sa+n_ng : @@ -1380,8 +1475,10 @@ class Test: tag_type = self.api.GetTagTypes([tag_type_id])[0] for field in tag_type_fields: assert tag_type[field] == tag_type_fields[field] + for tt_role_id in tt_role_ids: + assert tt_role_id in tag_type['role_ids'] if self.verbose: - print "Updated slice attribute type", tag_type_id + print "Created tag type", tag_type_id def UpdateTagTypes(self): """ @@ -1404,7 +1501,7 @@ class Test: for field in tag_type_fields: assert tag_type[field] == tag_type_fields[field] if self.verbose: - print "Updated slice attribute type", tag_type_id + print "Updated tag type", tag_type_id def DeleteTagTypes(self): """ @@ -1418,7 +1515,7 @@ class Test: assert not self.api.GetTagTypes([tag_type_id]) if self.verbose: - print "Deleted slice attribute type", tag_type_id + print "Deleted tag type", tag_type_id if self.check: assert not self.api.GetTagTypes(self.slice_type_ids+self.nodegroup_type_ids+self.ilink_type_ids) @@ -1605,6 +1702,17 @@ class Test: self.slice_tag_ids = [] + # convenience for cleaning up + # not exactly accurate -- use on test plcs only + def WipeSitesFromLength(self): + for site in self.api.GetSites(): + abbrev=site['abbreviated_name'] +# print 'matching',len(abbrev),'against',self.namelengths['abbreviated_name'] + if len(abbrev)==self.namelengths['abbreviated_name']: +# if len(abbrev)==17: + print 'wiping site %d (%s)'%(site['site_id'],site['name']) + self.api.DeleteSite(site['site_id']) + def main(): parser = OptionParser() parser.add_option("-c", "--check", action = "store_true", default = False, @@ -1615,25 +1723,41 @@ def main(): help = "Do not delete created objects") parser.add_option("-t", "--tiny", action = "store_true", default = False, help = "Run a tiny test (default: %default)") + parser.add_option("-l", "--large", action = "store_true", default = False, + help = "Run a large test (default: %default)") + parser.add_option("-x", "--xlarge", action = "store_true", default = False, + help = "Run an XL test (default: %default)") parser.add_option("-s", "--short-names", action="store_true", dest="short_names", default = False, help = "Generate smaller names for checking UI rendering") + parser.add_option ("-f", "--foreign", action="store_true", dest="federating", default = False, + help = "Create a fake peer and add items in it (no update, no delete)") + parser.add_option ("-w", "--wipe", action="store_true", dest="wipe", default = False, + help = "Wipe sites whose abbrev matches what the tests created") (options, args) = parser.parse_args() test = Test(api = Shell(), check = options.check, verbose = not options.quiet, - preserve = options.preserve) - - if options.tiny: - sizes = Test.sizes_tiny - else: - sizes = Test.sizes_default + preserve = options.preserve, + federating = options.federating) if options.short_names: test.namelengths = Test.namelengths_short else: test.namelengths = Test.namelengths_default + if options.wipe: + test.WipeSitesFromLength() + return + + if options.tiny: + sizes = Test.sizes_tiny + elif options.large: + sizes = Test.sizes_large + elif options.xlarge: + sizes = Test.sizes_xlarge + else: + sizes = Test.sizes_default test.Run(**sizes) if __name__ == "__main__":