blob: 2fb6b3d6fe8240e48ea5db8bde652d9d72a1da0c [file] [log] [blame]
suibin zhang17308622016-04-14 15:45:30 -07001class SCPFbatchFlowResp:
2 '''
3 Testing end-to-end ONOS response time from POST of batched flows to when ONOS returns
4 response confirmation of all flows ADDED; subsequently testing the response time from when REST DELETE to
5 ONOS confirmation of all flows REMOVED.
6 '''
7
8 def __init__( self ):
9 self.default = ''
10
11 def CASE1( self, main ):
12 import time
13 import os
14 import imp
15
16 """
17 - Construct tests variables
18 - GIT ( optional )
19 - Checkout ONOS master branch
20 - Pull latest ONOS code
21 - Building ONOS ( optional )
22 - Install ONOS package
23 - Build ONOS package
24 """
25
26 main.case( "Constructing test variables and building ONOS package" )
27 main.step( "Constructing test variables" )
28
29 # Test variables
30 main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
31 main.cellName = main.params[ 'CASE1' ][ 'cellName' ]
32 main.apps = main.params[ 'CASE1' ][ 'cellApps' ]
33 gitBranch = main.params[ 'CASE1' ][ 'gitBranch' ]
34 gitPull = main.params[ 'CASE1' ][ 'gitPull' ]
35 main.maxNodes = int( main.params['GLOBAL'][ 'maxNodes' ] )
36 main.startUpSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'startup' ] )
37 main.startMNSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'startMN' ] )
38 main.addFlowSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'addFlow' ] )
39 main.delFlowSleep = float( main.params['GLOBAL'][ 'SLEEP' ][ 'delFlow' ] )
40 main.chkFlowSleep = float( main.params['GLOBAL']['SLEEP']['chkFlow'])
41 main.cfgSleep = float( main.params['GLOBAL']['SLEEP']['cfg'])
42 main.numSw = int( main.params['GLOBAL']['numSw'])
43 main.numThreads = int( main.params['GLOBAL']['numThreads'] )
44 main.cellData = {} # for creating cell file
45 main.CLIs = []
46 main.ONOSip = []
YPZhang28909bc2016-06-20 13:29:11 -070047
suibin zhang17308622016-04-14 15:45:30 -070048 main.ONOSip = main.ONOSbench.getOnosIps()
49 main.commit = main.ONOSbench.getVersion()
YPZhang28909bc2016-06-20 13:29:11 -070050 main.commit = main.commit.split(" ")[1]
51
suibin zhang17308622016-04-14 15:45:30 -070052 main.cluster = main.params['GLOBAL']['cluster']
53
54 # Assigning ONOS cli handles to a list
55 for i in range( 1, main.maxNodes + 1 ):
56 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
57
58
59 if main.CLIs:
60 stepResult = main.TRUE
61 else:
62 main.log.error( "Did not properly created list of ONOS CLI handle" )
63 stepResult = main.FALSE
64
65 utilities.assert_equals( expect=main.TRUE,
66 actual=stepResult,
67 onpass="Successfully construct " +
68 "test variables ",
69 onfail="Failed to construct test variables" )
70
71 if gitPull == 'True':
72 main.step( "Building ONOS in " + gitBranch + " branch" )
73 onosBuildResult = main.startUp.onosBuild( main, gitBranch )
74 stepResult = onosBuildResult
75 utilities.assert_equals( expect=main.TRUE,
76 actual=stepResult,
77 onpass="Successfully compiled " +
78 "latest ONOS",
79 onfail="Failed to compile " +
80 "latest ONOS" )
81 else:
82 main.log.warn( "Did not pull new code so skipping mvn " +
83 "clean install" )
84
85 def CASE2( self, main ):
86 """
87 - Set up cell
88 - Create cell file
89 - Set cell file
90 - Verify cell file
91 - Kill ONOS process
92 - Uninstall ONOS cluster
93 - Verify ONOS start up
94 - Install ONOS cluster
95 - Connect to cli
96 """
97
98 main.numCtrls = int( main.maxNodes )
99
100 main.case( "Starting up " + str( main.numCtrls ) +
101 " node(s) ONOS cluster" )
102
103 main.log.info( "Safety check, killing all ONOS processes" +
104 " before initiating environment setup" )
105
106 tempOnosIp = []
107 for i in range( main.numCtrls ):
108 tempOnosIp.append( main.ONOSip[i] )
109
110 if main.params['CASE2']['incPackaging'] == "true":
111 main.step("Create onos cell file with: " + main.apps)
112 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "temp",
113 main.Mininet1.ip_address, main.apps, tempOnosIp )
114
115 main.step( "Apply cell to environment" )
116 cellResult = main.ONOSbench.setCell( "temp" )
117 verifyResult = main.ONOSbench.verifyCell()
118 stepResult = cellResult and verifyResult
119 utilities.assert_equals( expect=main.TRUE,
120 actual=stepResult,
121 onpass="Successfully applied cell to " + \
122 "environment",
123 onfail="Failed to apply cell to environment " )
124
125
126 main.step( "Creating ONOS package" )
Jon Hallbd60ea02016-08-23 10:03:59 -0700127 packageResult = main.ONOSbench.buckBuild()
suibin zhang17308622016-04-14 15:45:30 -0700128 stepResult = packageResult
129 utilities.assert_equals( expect=main.TRUE,
130 actual=stepResult,
131 onpass="Successfully created ONOS package",
132 onfail="Failed to create ONOS package" )
133 time.sleep( main.startUpSleep )
134
135 main.step( "Uninstalling ONOS package" )
136 onosUninstallResult = main.TRUE
137 for i in range( main.numCtrls ):
138 onosUninstallResult = onosUninstallResult and \
139 main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
140 stepResult = onosUninstallResult
141 utilities.assert_equals( expect=main.TRUE,
142 actual=stepResult,
143 onpass="Successfully uninstalled ONOS package",
144 onfail="Failed to uninstall ONOS package" )
145 time.sleep( main.startUpSleep )
146
147 else:
148 main.log.info("onos Packaging Skipped!")
149
150 main.step( "Installing ONOS package" )
151 onosInstallResult = main.TRUE
152 for i in range( main.numCtrls ):
153 onosInstallResult = onosInstallResult and \
154 main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
155 stepResult = onosInstallResult
156 utilities.assert_equals( expect=main.TRUE,
157 actual=stepResult,
158 onpass="Successfully installed ONOS package",
159 onfail="Failed to install ONOS package" )
160 time.sleep( main.startUpSleep )
161
You Wang52590212017-05-04 17:35:20 -0700162 main.step( "Set up ONOS secure SSH" )
163 secureSshResult = main.TRUE
164 for i in range( main.numCtrls ):
165 secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
166 utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
167 onpass="Test step PASS",
168 onfail="Test step FAIL" )
169
170 time.sleep( main.startUpSleep )
suibin zhang17308622016-04-14 15:45:30 -0700171 main.step( "Starting ONOS service" )
172 stopResult = main.TRUE
173 startResult = main.TRUE
174 onosIsUp = main.TRUE
175
176 for i in range( main.numCtrls ):
177 onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
178 if onosIsUp == main.TRUE:
179 main.log.report( "ONOS instance is up and ready" )
180 else:
181 main.log.report( "ONOS instance may not be up, stop and " +
182 "start ONOS again " )
183 for i in range( main.numCtrls ):
184 stopResult = stopResult and \
185 main.ONOSbench.onosStop( main.ONOSip[ i ] )
186 for i in range( main.numCtrls ):
187 startResult = startResult and \
188 main.ONOSbench.onosStart( main.ONOSip[ i ] )
189 stepResult = onosIsUp and stopResult and startResult
190 utilities.assert_equals( expect=main.TRUE,
191 actual=stepResult,
192 onpass="ONOS service is ready",
193 onfail="ONOS service did not start properly" )
194
195 main.step( "Start ONOS cli" )
196 cliResult = main.TRUE
197 for i in range( i, main.numCtrls ):
198 cliResult = cliResult and \
You Wang52590212017-05-04 17:35:20 -0700199 main.ONOScli1.startOnosCli( main.ONOSip[ i ] )
suibin zhang17308622016-04-14 15:45:30 -0700200 stepResult = cliResult
201 utilities.assert_equals( expect=main.TRUE,
202 actual=stepResult,
203 onpass="Successfully start ONOS cli",
204 onfail="Failed to start ONOS cli" )
205
206
207
208 def CASE10( self, main ):
209 '''
210 Start Mininet
211 '''
212 import time
213
214 main.case( "Enable openflow-base on onos and start Mininet." )
215
216 main.step("Activate openflow-base App")
217 app = main.params['CASE10']['app']
YPZhang5d0552f2016-05-18 13:02:52 -0700218 stepResult = main.ONOScli1.activateApp( app )
suibin zhang17308622016-04-14 15:45:30 -0700219 time.sleep(main.cfgSleep)
220 main.log.info(stepResult)
221 utilities.assert_equals( expect=main.TRUE,
222 actual=stepResult,
223 onpass="Successfully activate " + app,
224 onfail="Failed to activate app " + app )
225
226 time.sleep(main.cfgSleep)
227
228
YPZhang5d0552f2016-05-18 13:02:52 -0700229 main.step( "Configure AdaptiveFlowSampling ")
230 stepResult = main.ONOScli1.setCfg( component = "org.onosproject.provider.of.flow.impl.OpenFlowRuleProvider",
231 propName = "adaptiveFlowSampling ", value = main.params['CASE10']['adaptiveFlowenabled'])
suibin zhang17308622016-04-14 15:45:30 -0700232 utilities.assert_equals( expect=main.TRUE,
233 actual=stepResult,
234 onpass="App Configuration Succeeded! ",
235 onfail="App Configuration Failed!" )
236 time.sleep(main.cfgSleep)
237
238 main.step( "Setup Mininet Linear Topology with " + str(main.numSw) + " switches" )
239 argStr = main.params['CASE10']['mnArgs'].format(main.numSw)
240 stepResult = main.Mininet1.startNet( args = argStr )
241
242 utilities.assert_equals( expect=main.TRUE,
243 actual=stepResult,
244 onpass="Successfully loaded topology",
245 onfail="Failed to load topology" )
246
247 time.sleep( main.startMNSleep )
248
249 main.step( "Assign switches to controller" )
250 for i in range(1, main.numSw + 1):
251 main.Mininet1.assignSwController( "s" + str(i), main.ONOSip[0] )
252
253 utilities.assert_equals( expect=main.TRUE,
254 actual=stepResult,
255 onpass="Successfully assigned switch to controller",
256 onfail="Failed to assign switch to controller" )
257
258 main.deviceIdPrefix = "of:"
259
260 time.sleep( main.startMNSleep )
261
262 def CASE11( self, main ):
263 '''
264 Start Null Provider
265 '''
266 import time
267
268 main.case( "Setup Null Provider for linear Topology" )
269
270 main.step("Activate Null Provider App")
271 stepResult = main.ONOSbench.onosCli( ONOSIp = main.ONOSip[0],
272 cmdstr = "app activate org.onosproject.null" )
273 utilities.assert_equals( expect=main.TRUE,
274 actual=stepResult,
275 onpass="Successfully activated org.onosproject.null",
276 onfail="Failed to activate org.onosproject.null" )
277 time.sleep( main.cfgSleep)
278
279 main.step( "Setup Null Provider Linear Topology with " + str(main.numSw) + " devices." )
280 r1 = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(main.numSw))
281 r2 = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "topoShape " + main.params['CASE11']['nullTopo'] )
282 r3 = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "enabled " + main.params['CASE11']['nullStart'])
283 stepResult = r1 & r2 & r3
284 utilities.assert_equals( expect=main.TRUE,
285 actual=stepResult,
286 onpass="App Configuration Succeeded! ",
287 onfail="App Configuration Failed!" )
288 time.sleep( main.cfgSleep )
289
290 main.log.info("Check to make sure null providers are configured correctly.")
291 main.ONOSbench.handle.sendline("onos $OC1 summary")
292 stepResult = main.ONOSbench.handle.expect(":~")
293 main.log.info("ONOS Summary: " + main.ONOSbench.handle.before)
294
295 main.deviceIdPrefix = "null:"
296
297 time.sleep( main.startMNSleep )
298
299
300
301 def CASE1000( self, main ):
302 '''
303 create JSON object with batched flows
304 '''
305 import numpy
306 import time
307 from pprint import pprint
308
309 main.case( "Create a json object for the batched flows" )
310
311 main.step( "Parse batch creation information" )
312 main.batchSize = int(main.params['CASE1000']['batchSize'])
313 main.log.info("Number of flows in a batch is:" + str(main.batchSize))
314
315 main.flowJsonBatchList = []
316 startSw = 1
317
318 main.step("Creating a full list of batches")
319 for index in range(1, int(main.params['CASE1000']['batches']) + 1):
320 if startSw <= main.numSw:
321 ind = startSw
322 else:
323 startSw = 1
324 ind = startSw
325
326 main.log.info("Creating batch: " + str(index))
327 flowJsonBatch = main.ONOSrest.createFlowBatch( numSw = main.numSw,
328 swIndex = ind,
329 batchSize = main.batchSize,
330 batchIndex = index,
331 deviceIdpreFix=main.deviceIdPrefix,
332 ingressPort = 2,
333 egressPort = 3)
334 main.flowJsonBatchList.append(flowJsonBatch)
335
336 startSw += 1
337 main.log.info( "Number of items created in the batch list is: " + str(len(main.flowJsonBatchList)))
338
339 def CASE2100(self, main):
340 '''
341 Posting flow batches using threads
342 '''
343 main.case("Using REST API /flows/{} to post flow batch - multi-threads")
344 main.step("Using REST API /flows/{} to post flow batch - multi-threads")
345
346 from Queue import Queue
347 from threading import Thread
348 import time
349 import json
350
351 main.threadID = 0
352 main.addedBatchList = []
353 q = Queue()
354 tAllAdded = 0
You Wang7b5b2262016-11-10 13:54:56 -0800355 main.postFailed = False
suibin zhang17308622016-04-14 15:45:30 -0700356
357 def postWorker(id):
358 while True:
359 item = q.get()
360 #print json.dumps(item)
361 status,response = main.ONOSrest.sendFlowBatch(batch = item)
You Wang7b5b2262016-11-10 13:54:56 -0800362 if status == main.TRUE:
363 main.log.info("Thread {} is working on posting. ".format(id))
364 #print json.dumps(response)
365 main.addedBatchList.append(response[1])
366 else:
367 main.log.error( "Thread {} failed to post.".format(id) )
368 main.postFailed = True
suibin zhang17308622016-04-14 15:45:30 -0700369 q.task_done()
370
371 for i in range( int( main.params['CASE2100']['numThreads'])):
372 threadID = "ThreadID-" + str(i)
373 t = Thread(target = postWorker, name = threadID, args=(threadID,) )
374 t.daemon = True
375 t.start()
376
377 tStartPost = time.time()
378 for item in main.flowJsonBatchList:
379 q.put(item)
380
381 q.join()
382 tLastPostEnd = time.time()
You Wang7b5b2262016-11-10 13:54:56 -0800383 if main.postFailed:
384 main.log.error( "Flow batch posting failed, exit test" )
385 main.cleanup()
386 main.exit()
suibin zhang17308622016-04-14 15:45:30 -0700387
388 main.step("Check to ensure all flows are in added state.")
389 #pprint(main.addedBatchList)
390 resp = main.FALSE
391 while resp != main.TRUE and ( tAllAdded - tLastPostEnd < int (main.params['CASE2100']['chkFlowTO']) ):
Jin Gana6869b92016-07-22 15:02:52 -0700392 if main.params['CASE2100']['RESTchkFlow'] == 'main.TRUE':
suibin zhang17308622016-04-14 15:45:30 -0700393 resp = main.ONOSrest.checkFlowsState()
394 else:
395 handle = main.CLIs[0].flows(state = " |grep PEND|wc -l", jsonFormat=False)
396 main.log.info("handle returns PENDING flows: " + handle)
397 if handle == "0":
398 resp = main.TRUE
399
400 time.sleep( main.chkFlowSleep )
401 tAllAdded = time.time()
402
403 if tAllAdded - tLastPostEnd >= int (main.params['CASE2100']['chkFlowTO']):
404 main.log.warn("ONOS Flows still in pending state after: {} seconds.".format(tAllAdded - tLastPostEnd))
405
406 main.numFlows = int(main.params['CASE1000']['batches']) *\
407 int(main.params['CASE1000']['batchSize'])
408 main.log.info("Total number of flows: " + str (main.numFlows) )
409 main.elapsePOST = tLastPostEnd-tStartPost
410 main.log.info("Total POST elapse time: " + str( main.elapsePOST ) )
411 main.log.info("Rate of ADD Controller response: " + str(main.numFlows / ( main.elapsePOST )))
412
413 main.POSTtoCONFRM = tAllAdded - tLastPostEnd
414 main.log.info("Elapse time from end of last REST POST to Flows in ADDED state: " +\
415 str( main.POSTtoCONFRM ))
416 main.log.info("Rate of Confirmed Batch Flow ADD is (flows/sec): " +
417 str( main.numFlows / main.POSTtoCONFRM ))
418 main.log.info("Number of flow Batches in the addedBatchList is: " +
419 str( len(main.addedBatchList)))
420
421 def CASE3100(self, main):
422 '''
423 DELETE flow batches using threads
424 '''
425 main.case("Using REST API /flows/{} to delete flow batch - multi-threads")
426 main.step("Using REST API /flows/{} to delete flow batch - multi-threads")
427
428 from Queue import Queue
429 from threading import Thread
430 import time
431 import json
432
433 main.threadID = 0
434 q = Queue()
435 tAllRemoved = 0
436
437 main.log.info("Number of flow batches at start of remove: " + str( len( main.addedBatchList)))
438 def removeWorker(id):
439 while True:
440 item = q.get()
441 response = main.ONOSrest.removeFlowBatch(batch = json.loads(item) )
442 main.log.info("Thread {} is working on deleting. ".format(id))
443 q.task_done()
444
445 for i in range( int( main.params['CASE2100']['numThreads'])):
446 threadID = "ThreadID-" + str(i)
447 t = Thread(target = removeWorker, name = threadID, args=(threadID,) )
448 t.daemon = True
449 t.start()
450
451 tStartDelete = time.time()
452 for item in main.addedBatchList:
453 q.put(item)
454
455 q.join()
456 tLastDeleteEnd = time.time()
457 main.log.info("Number of flow batches at end of remove: " + str( len( main.addedBatchList)))
458
459 main.step("Check to ensure all flows are in added state.")
460 #pprint(main.addedBatchList)
461 resp = main.FALSE
462 while resp != main.TRUE and ( tAllRemoved - tLastDeleteEnd < int (main.params['CASE3100']['chkFlowTO']) ):
Jin Gana6869b92016-07-22 15:02:52 -0700463 if main.params['CASE3100']['RESTchkFlow'] == 'main.TRUE':
suibin zhang17308622016-04-14 15:45:30 -0700464 resp = main.ONOSrest.checkFlowsState()
465 else:
466 handle = main.CLIs[0].flows(state = " |grep PEND|wc -l", jsonFormat=False)
467 main.log.info("handle returns PENDING flows: " + handle)
468 if handle == "0":
469 resp = main.TRUE
470 time.sleep( main.chkFlowSleep )
471 tAllRemoved = time.time()
472
473 if tLastDeleteEnd - tLastDeleteEnd >= int (main.params['CASE2100']['chkFlowTO']):
474 main.log.warn("ONOS Flows still in pending state after: {} seconds.".format(tAllRemoved - tLastDeleteEnd))
475
476 main.numFlows = int(main.params['CASE1000']['batches']) *\
477 int(main.params['CASE1000']['batchSize'])
478 main.log.info("Total number of flows: " + str (main.numFlows) )
479 main.elapseDELETE = tLastDeleteEnd-tStartDelete
480 main.log.info("Total DELETE elapse time: " + str( main.elapseDELETE ))
481 main.log.info("Rate of DELETE Controller response: " + str(main.numFlows / ( main.elapseDELETE )))
482
483 main.DELtoCONFRM = tAllRemoved - tLastDeleteEnd
484 main.log.info("Elapse time from end of last REST DELETE to Flows in REMOVED state: " +\
485 str( main.DELtoCONFRM ))
486 main.log.info("Rate of Confirmed Batch Flow REMOVED is (flows/sec): " + str( main.numFlows / main.DELtoCONFRM))
487
488 def CASE100(self,main):
489 from pprint import pprint
490
491 main.case( "Check to ensure onos flows." )
492
493 resp = main.ONOSrest.checkFlowsState()
494 #pprint(resp)
495
496 def CASE210(self,main):
497 main.case("Log test results to a data file")
498 main.step("Write test resulted data to a data file")
499 main.scale = main.maxNodes
500
501 try:
502 dbFileName="/tmp/SCPFbatchFlowRespData"
503 dbfile = open(dbFileName, "w+")
504 temp = "'" + main.commit + "',"
YPZhang28909bc2016-06-20 13:29:11 -0700505 temp += "'1gig',"
suibin zhang17308622016-04-14 15:45:30 -0700506 temp += "'" + str( main.scale ) + "',"
507 temp += "'" + main.cluster + "',"
508 temp += "'" + str( main.elapsePOST ) + "',"
509 temp += "'" + str( main.POSTtoCONFRM ) + "',"
YPZhang28909bc2016-06-20 13:29:11 -0700510 temp += "'" + str( main.numFlows / main.POSTtoCONFRM ) + "',"
suibin zhang17308622016-04-14 15:45:30 -0700511 temp += "'" + str ( main.elapseDELETE ) + "',"
YPZhang28909bc2016-06-20 13:29:11 -0700512 temp += "'" + str ( main.DELtoCONFRM ) + "',"
513 temp += "'" + str( main.numFlows / main.DELtoCONFRM ) + "',"
514 temp += "'" + str( main.numSw ) + "'\n"
suibin zhang17308622016-04-14 15:45:30 -0700515 dbfile.write( temp )
516 dbfile.close()
517 stepResult = main.TRUE
518 except IOError:
519 main.log.warn("Error opening " + dbFileName + " to write results.")
520 stepResult = main.FALSE
521
522 utilities.assert_equals( expect=main.TRUE,
523 actual=stepResult,
524 onpass="Succeeded to write results to datafile",
525 onfail="Failed to write results to datafile " )
526
527 def CASE110( self, main ):
528 '''
529 Report errors/warnings/exceptions
530 '''
531 main.log.info("Error report: \n" )
532 main.ONOSbench.logReport( main.ONOSip[ 0 ],
533 [ "INFO",
534 "FOLLOWER",
535 "WARN",
536 "flow",
537 "ERROR",
538 "Except" ],
539 "s" )
540 #main.stop()
541