blob: 78d18b90d6ff1d966b76cdacef3b6bd50af7ba0e [file] [log] [blame]
suibin-onlabbf69cfc2014-08-06 11:07:06 -07001#! /usr/bin/env python
2from time import time, sleep
3import time
4import json
5import requests
6import urllib2
7from urllib2 import URLError, HTTPError
8
suibin-onlab0a2a8862014-08-08 11:11:46 -07009'''
10 This script is for Intent Throughput testing. Use linear 7-switch topo. Intents are from S1P1 to/from S7/P1, with incrementing src/dst Mac addresses.
11'''
suibin-onlabbf69cfc2014-08-06 11:07:06 -070012
suibin-onlab0a2a8862014-08-08 11:11:46 -070013def setIntentJSN(node_id, intPerGroup, group_id, intent_id):
14 intents = [None for i in range(intPerGroup)]
15 oper = {}
16 index = 0
17 for i in range(intPerGroup / 2):
18 smac = str("%x" %(node_id * 0x100000000000 + 0x010000000000 + (group_id * 0x000001000000) +i + 1))
19 dmac = str("%x" %(node_id * 0x100000000000 + 0x070000000000 + (group_id * 0x000001000000) +i + 1))
20 srcMac = ':'.join(smac[i:i+2] for i in range(0, len(smac), 2))
21 dstMac = ':'.join(dmac[i:i+2] for i in range(0, len(dmac), 2))
22 srcSwitch = "00:00:00:00:00:00:00:01"
23 dstSwitch = "00:00:00:00:00:00:00:07"
24 srcPort = 1
25 dstPort = 1
suibin-onlabbf69cfc2014-08-06 11:07:06 -070026
suibin-onlab0a2a8862014-08-08 11:11:46 -070027 oper['intentId'] = intent_id
28 oper['intentType'] = 'SHORTEST_PATH' # XXX: Hardcode
29 oper['staticPath'] = False # XXX: Hardcoded
30 oper['srcSwitchDpid'] = srcSwitch
31 oper['srcSwitchPort'] = srcPort
32 oper['dstSwitchDpid'] = dstSwitch
33 oper['dstSwitchPort'] = dstPort
34 oper['matchSrcMac'] = srcMac
35 oper['matchDstMac'] = dstMac
36 intents[index] = oper
37 #print ("perGroup Intents-0 are: " + json.dumps(intents) + "\n\n\n" )
38 index += 1
39 intent_id += 1
suibin-onlabbf69cfc2014-08-06 11:07:06 -070040 oper = {}
suibin-onlab0a2a8862014-08-08 11:11:46 -070041 #print ("ID:" + str(id))
suibin-onlabbf69cfc2014-08-06 11:07:06 -070042
suibin-onlab0a2a8862014-08-08 11:11:46 -070043 oper['intentId'] = intent_id
44 oper['intentType'] = 'SHORTEST_PATH' # XXX: Hardcoded
45 oper['staticPath'] = False # XXX: Hardcoded
46 oper['srcSwitchDpid'] = dstSwitch
47 oper['srcSwitchPort'] = dstPort
48 oper['dstSwitchDpid'] = srcSwitch
49 oper['dstSwitchPort'] = srcPort
50 oper['matchSrcMac'] = dstMac
51 oper['matchDstMac'] = srcMac
52 intents[index] = oper
53 index += 1
54 intent_id += 1
55 oper = {}
56 #print ("ID: " + str(id))
57 #print ("perGroup Intents-1 are: " + json.dumps(intents) + "\n\n\n" )
58 #print ("contructed intents are: " + json.dumps(intents) + "\n\n\n")
59 return intents, intent_id
suibin-onlabbf69cfc2014-08-06 11:07:06 -070060
suibin-onlab0a2a8862014-08-08 11:11:46 -070061def post_json(url, data):
62 """Make a REST POST call and return the JSON result
suibin-onlabbf69cfc2014-08-06 11:07:06 -070063 url: the URL to call
64 data: the data to POST"""
suibin-onlab0a2a8862014-08-08 11:11:46 -070065 posturl = "http://%s/wm/onos/intent/high" %(url)
66 #print ("\nPost url is : " + posturl + "\n")
67 parsed_result = []
68 data_json = json.dumps(data)
69 try:
70 request = urllib2.Request(posturl, data_json)
71 request.add_header("Content-Type", "application/json")
72 response = urllib2.urlopen(request)
73 result = response.read()
74 response.close()
75 if len(result) != 0:
76 parsed_result = json.loads(result)
77 except HTTPError as exc:
78 print "ERROR:"
79 print " REST POST URL: %s" % posturl
80 # NOTE: exc.fp contains the object with the response payload
81 error_payload = json.loads(exc.fp.read())
82 print " REST Error Code: %s" % (error_payload['code'])
83 print " REST Error Summary: %s" % (error_payload['summary'])
84 print " REST Error Description: %s" % (error_payload['formattedDescription'])
85 print " HTTP Error Code: %s" % exc.code
86 print " HTTP Error Reason: %s" % exc.reason
87 except URLError as exc:
88 print "ERROR:"
89 print " REST POST URL: %s" % posturl
90 print " URL Error Reason: %s" % exc.reason
91 return parsed_result
suibin-onlabbf69cfc2014-08-06 11:07:06 -070092
suibin-onlab0a2a8862014-08-08 11:11:46 -070093def delete_json(self, url, intPerGroup, startID):
94 """Make a REST DELETE call and return the JSON result
suibin-onlabbf69cfc2014-08-06 11:07:06 -070095 url: the URL to call"""
suibin-onlab0a2a8862014-08-08 11:11:46 -070096 #url = "localhost:8080"
97 for i in range(intPerGroup):
98 posturl = "http://%s/wm/onos/intent/high/%s" %(url, str(i + startID))
suibin-onlabbf69cfc2014-08-06 11:07:06 -070099 parsed_result = []
100 try:
101 request = urllib2.Request(posturl)
102 request.get_method = lambda: 'DELETE'
103 response = urllib2.urlopen(request)
104 result = response.read()
105 response.close()
suibin-onlab0a2a8862014-08-08 11:11:46 -0700106 #if len(result) != 0:
107 # parsed_result = json.loads(result)
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700108 except HTTPError as exc:
109 print "ERROR:"
110 print " REST DELETE URL: %s" % posturl
111 # NOTE: exc.fp contains the object with the response payload
112 error_payload = json.loads(exc.fp.read())
113 print " REST Error Code: %s" % (error_payload['code'])
114 print " REST Error Summary: %s" % (error_payload['summary'])
115 print " REST Error Description: %s" % (error_payload['formattedDescription'])
116 print " HTTP Error Code: %s" % exc.code
117 print " HTTP Error Reason: %s" % exc.reason
118 except URLError as exc:
119 print "ERROR:"
120 print " REST DELETE URL: %s" % posturl
121 print " URL Error Reason: %s" % exc.reason
suibin-onlab0a2a8862014-08-08 11:11:46 -0700122 return parsed_result
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700123
suibin-onlab0a2a8862014-08-08 11:11:46 -0700124def delete_all_json(url):
125 """Make a REST DELETE call and return the JSON result
126 url: the URL to call"""
127 #url = "localhost:8080"
128 posturl = "http://%s/wm/onos/intent/high" %(url)
129 parsed_result = []
130 try:
131 request = urllib2.Request(posturl)
132 request.get_method = lambda: 'DELETE'
133 response = urllib2.urlopen(request)
134 result = response.read()
135 response.close()
136 if len(result) != 0:
137 parsed_result = json.loads(result)
138 except HTTPError as exc:
139 print "ERROR:"
140 print " REST DELETE URL: %s" % posturl
141 # NOTE: exc.fp contains the object with the response payload
142 error_payload = json.loads(exc.fp.read())
143 print " REST Error Code: %s" % (error_payload['code'])
144 print " REST Error Summary: %s" % (error_payload['summary'])
145 print " REST Error Description: %s" % (error_payload['formattedDescription'])
146 print " HTTP Error Code: %s" % exc.code
147 print " HTTP Error Reason: %s" % exc.reason
148 except URLError as exc:
149 print "ERROR:"
150 print " REST DELETE URL: %s" % posturl
151 print " URL Error Reason: %s" % exc.reason
152 return parsed_result
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700153
suibin-onlab0a2a8862014-08-08 11:11:46 -0700154def loadIntents(node_id, urllist, intPerGroup, addrate, duration):
155 urlindex = 0
156 group = 0
157 start_id = 0
158 sleeptimer = (1.000/addrate)
159 tstart = time.time()
160 while ( (time.time() - tstart) <= duration ):
161 if urlindex < len(urllist):
162 realurlind = urlindex
163 else:
164 realurlind = 0
165 urlindex = 0
166
167 u = str(urllist[realurlind])
168 gstart = time.time()
169 intents,start_id = setIntentJSN(node_id, intPerGroup, group, start_id)
170 #print (str(intents))
171 #print ("Starting intent id: " + str(start_id))
172 result = post_json(u, intents)
173 #print json.dumps(intents[group])
174 #print ("post result: " + str(result))
175 gelapse = time.time() - gstart
176 print ("Group: " + str(group) + " with " + str(intPerGroup) + " intents were added in " + str('%.3f' %gelapse) + " seconds.")
177 sleep(sleeptimer)
178 urlindex += 1
179 group += 1
180
181 telapse = time.time() - tstart
182 #print ( "Number of groups: " + str(group) + "; Totoal " + str(args.groups * args.intPerGroup) + " intents were added in " + str(telapse) + " seconds.")
183 return telapse, group
184
185def main():
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700186 import argparse
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700187
188 parser = argparse.ArgumentParser(description="less script")
suibin-onlab0a2a8862014-08-08 11:11:46 -0700189 parser.add_argument("-n", "--node_id", dest="node_id", default = 1, type=int, help="id of the node generating the intents, this is used to distinguish intents when multiple nodes are use to generate intents")
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700190 parser.add_argument("-u", "--urls", dest="urls", default="10.128.10.1", type=str, help="a string to show urls to post intents to separated by space, ex. '10.128.10.1:8080 10.128.10.2:80080' ")
191 parser.add_argument("-i", "--intentsPerGroup", dest="intPerGroup", default=100, type=int, help="number of intents in one restcall group")
suibin-onlab10e128a2014-08-07 09:59:16 -0700192 parser.add_argument("-a", "--addrate", dest="addrate", default=10, type=float, help="rate to add intents groups, groups per second")
suibin-onlab0a2a8862014-08-08 11:11:46 -0700193 parser.add_argument("-d", "--delrate", dest="delrate", default=100, type=float, help= "### Not Effective -for now intents are delete as bulk #### rate to delete intents, intents/second")
194 parser.add_argument("-l", "--length", dest="duration", default=300, type=int, help="duration/length of time the intents are posted")
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700195 parser.add_argument("-p", "--pause", dest="pause", default=0, type=int, help= "pausing time between add and delete of intents")
196 args = parser.parse_args()
197
suibin-onlab0a2a8862014-08-08 11:11:46 -0700198 node_id = args.node_id
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700199 urllist = args.urls.split()
suibin-onlab0a2a8862014-08-08 11:11:46 -0700200 intPerGroup = args.intPerGroup
201 addrate = args.addrate
202 delrate = args.delrate
203 duration = args.duration
204 pause = args.pause
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700205
suibin-onlab0a2a8862014-08-08 11:11:46 -0700206 print ("Intent posting urls are: " + str(urllist))
207 print ("Number of Intents per group: " + str(intPerGroup))
208 print ("Intent group add rate: " + str(addrate) )
209 print ("Intent delete rate:" + str(delrate) )
210 print ("Duration: " + str(duration) )
211 print ("Pause between add and delete: " + str(args.pause))
212
213 telapse, group = loadIntents(node_id, urllist, intPerGroup, addrate, duration)
214 print ("\n\n#####################")
215 print ( str(group) + " groups " + " of " + str(intPerGroup) + " Intents per group - Total " + str(group * intPerGroup) + " intents were added in " + str('%.3f' %telapse) + " seconds.")
216 print ( "Effective intents posting rate is: " + str( '%.1f' %( (group * intPerGroup)/telapse ) ) + " Intents/second." )
217 print ("#####################\n\n")
218 print ("Sleep for " + str(pause) + " seconds before deleting all intents...")
219 time.sleep(pause)
220 print ("Cleaning up intents in all nodes...")
221 for url in urllist:
222 delete_all_json(url)
suibin-onlabbf69cfc2014-08-06 11:07:06 -0700223
suibin-onlab0a2a8862014-08-08 11:11:46 -0700224if __name__ == '__main__':
225 main()