blob: 7a8a2945e9e3dbfd69b24be11c278ed17b881363 [file] [log] [blame]
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07001"""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002Copyright 2015 Open Networking Foundation ( ONF )
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07003
4Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
5the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
6or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070011 ( at your option ) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070012
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20"""
YPZhangfebf7302016-05-24 16:45:56 -070021# SCPFintentRerouteLat
22"""
23SCPFintentRerouteLat
24 - Test Intent Reroute Latency
25 - Test Algorithm:
26 1. Start Null Provider reroute Topology
27 2. Using Push-test-intents to push batch size intents from switch 1 to switch 7
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070028 3. Cut the link between switch 3 and switch 4 ( the path will reroute to switch 8 )
YPZhangfebf7302016-05-24 16:45:56 -070029 4. Get the topology time stamp
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070030 5. Get Intent reroute( Installed ) time stamp from each nodes
YPZhangfebf7302016-05-24 16:45:56 -070031 6. Use the latest intent time stamp subtract topology time stamp
32 - This test will run 5 warm up by default, warm up iteration can be setup in Param file
33 - The intent batch size will default set to 1, 100, and 1000, also can be set in Param file
34 - The unit of the latency result is milliseconds
35"""
cameron@onlab.us78b89652015-07-08 15:21:03 -070036class SCPFintentRerouteLat:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070037
Devin Lim142b5342017-07-20 15:22:39 -070038 def __init__( self ):
cameron@onlab.us78b89652015-07-08 15:21:03 -070039 self.default = ''
40
YPZhangfebf7302016-05-24 16:45:56 -070041 def CASE0( self, main ):
Chiyu Chengec63bde2016-11-17 18:11:36 -080042 import imp
43 import os
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070044 """
YPZhangfebf7302016-05-24 16:45:56 -070045 - GIT
46 - BUILDING ONOS
47 Pull specific ONOS branch, then Build ONOS ono ONOS Bench.
48 This step is usually skipped. Because in a Jenkins driven automated
49 test env. We want Jenkins jobs to pull&build for flexibility to handle
50 different versions of ONOS.
51 - Construct tests variables
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070052 """
Devin Lim58046fa2017-07-05 16:55:00 -070053 try:
54 from tests.dependencies.ONOSSetup import ONOSSetup
55 main.testSetUp = ONOSSetup()
56 except ImportError:
57 main.log.error( "ONOSSetup not found. exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -070058 main.cleanAndExit()
Devin Lim58046fa2017-07-05 16:55:00 -070059 main.testSetUp.envSetupDescription()
60 stepResult = main.FALSE
61 try:
Devin Lim58046fa2017-07-05 16:55:00 -070062 main.apps = main.params[ 'ENV' ][ 'cellApps' ]
63 main.BENCHUser = main.params[ 'BENCH' ][ 'user' ]
64 main.BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
65 main.MN1Ip = main.params[ 'MN' ][ 'ip1' ]
Devin Lim58046fa2017-07-05 16:55:00 -070066 main.cellName = main.params[ 'ENV' ][ 'cellName' ]
Devin Lim142b5342017-07-20 15:22:39 -070067 main.scale = ( main.params[ 'SCALE' ] ).split( "," )
Devin Lim58046fa2017-07-05 16:55:00 -070068 main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
69 main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
70 main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
71 main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
72 main.setMasterSleep = int( main.params[ 'SLEEP' ][ 'setmaster' ] )
73 main.verifyAttempts = int( main.params[ 'ATTEMPTS' ][ 'verify' ] )
74 main.maxInvalidRun = int( main.params[ 'ATTEMPTS' ][ 'maxInvalidRun' ] )
Devin Lime6fe3c42017-10-18 16:28:40 -070075 main.cfgRetry = int( main.params[ 'ATTEMPTS' ][ 'cfg' ] )
Devin Lim58046fa2017-07-05 16:55:00 -070076 main.sampleSize = int( main.params[ 'TEST' ][ 'sampleSize' ] )
Devin Lim142b5342017-07-20 15:22:39 -070077 main.intentManagerCfg = main.params[ 'CFG' ][ 'intentManager' ]
78 main.intentConfigRegiCfg = main.params[ 'CFG' ][ 'intentConfigRegi' ]
79 main.nullProviderCfg = main.params[ 'CFG' ][ 'nullProvider' ]
Devin Lim58046fa2017-07-05 16:55:00 -070080 main.warmUp = int( main.params[ 'TEST' ][ 'warmUp' ] )
81 main.ingress = main.params[ 'TEST' ][ 'ingress' ]
82 main.egress = main.params[ 'TEST' ][ 'egress' ]
83 main.debug = main.params[ 'TEST' ][ 'debug' ]
84 main.flowObj = main.params[ 'TEST' ][ 'flowObj' ]
85 main.deviceCount = int( main.params[ 'TEST' ][ 'deviceCount' ] )
86 main.end1 = main.params[ 'TEST' ][ 'end1' ]
87 main.end2 = main.params[ 'TEST' ][ 'end2' ]
88 main.searchTerm = main.params[ 'SEARCHTERM' ]
89 if main.flowObj == "True":
90 main.flowObj = True
91 main.dbFileName = main.params[ 'DATABASE' ][ 'dbFlowObj' ]
92 main.intentsList = ( main.params[ 'TEST' ][ 'FObjintents' ] ).split( "," )
93 else:
94 main.flowObj = False
95 main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
96 main.intentsList = ( main.params[ 'TEST' ][ 'intents' ] ).split( "," )
cameron@onlab.us78b89652015-07-08 15:21:03 -070097
Devin Lim142b5342017-07-20 15:22:39 -070098 stepResult = main.testSetUp.envSetup()
YPZhangfebf7302016-05-24 16:45:56 -070099
Devin Lim142b5342017-07-20 15:22:39 -0700100 for i in range( 0, len( main.intentsList ) ):
Devin Lim58046fa2017-07-05 16:55:00 -0700101 main.intentsList[ i ] = int( main.intentsList[ i ] )
102 # Create DataBase file
103 main.log.info( "Create Database file " + main.dbFileName )
104 resultsDB = open( main.dbFileName, "w+" )
105 resultsDB.close()
106 file1 = main.params[ "DEPENDENCY" ][ "FILE1" ]
107 main.dependencyPath = os.path.dirname( os.getcwd() ) + main.params[ "DEPENDENCY" ][ "PATH" ]
108 main.intentRerouteLatFuncs = imp.load_source( file1, main.dependencyPath + file1 + ".py" )
YPZhangfebf7302016-05-24 16:45:56 -0700109
Devin Lim58046fa2017-07-05 16:55:00 -0700110 main.record = 0
111 except Exception as e:
112 main.testSetUp.envSetupException( e )
113 main.testSetUp.evnSetupConclusion( stepResult )
You Wang47b91832017-08-02 11:36:13 -0700114 main.commit = main.commit.split( " " )[ 1 ]
YPZhangfebf7302016-05-24 16:45:56 -0700115
116 def CASE1( self, main ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700117 """
YPZhangfebf7302016-05-24 16:45:56 -0700118 clean up test environment and set up
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700119 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700120 import time
121
YPZhangfebf7302016-05-24 16:45:56 -0700122 main.maxNumBatch = 0
You Wanga0f6ff62018-01-11 15:46:30 -0800123 main.testSetUp.ONOSSetUp( main.Cluster, True,
Devin Lim142b5342017-07-20 15:22:39 -0700124 cellName=main.cellName, killRemoveMax=False )
Devin Lime6fe3c42017-10-18 16:28:40 -0700125 configRetry = 0
126 main.cfgCheck = False
127 while configRetry < main.cfgRetry:
128 # configure apps
129 stepResult = main.TRUE
130 stepResult = stepResult and \
131 main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
132 "deviceCount",
133 value=main.deviceCount )
134
135 stepResult = stepResult and \
136 main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
137 "topoShape",
138 value="reroute" )
139 stepResult = stepResult and \
140 main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
141 "enabled",
142 value="true" )
143
144 stepResult = stepResult and \
145 main.Cluster.active( 0 ).CLI.setCfg( main.intentManagerCfg,
146 "skipReleaseResourcesOnWithdrawal",
147 value="true" )
148 if main.flowObj:
149 stepResult = stepResult and \
150 main.Cluster.active( 0 ).CLI.setCfg( main.intentConfigRegiCfg,
151 "useFlowObjectives",
152 value="true" )
Devin Lime6fe3c42017-10-18 16:28:40 -0700153 if stepResult:
154 main.cfgCheck = True
155 break
156 configRetry += 1
157 time.sleep( main.verifySleep )
158
Chiyu Chengec63bde2016-11-17 18:11:36 -0800159 time.sleep( main.startUpSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700160 for ctrl in main.Cluster.active():
161 ctrl.CLI.logSet( "DEBUG", "org.onosproject.metrics.topology" )
162 ctrl.CLI.logSet( "DEBUG", "org.onosproject.metrics.intent" )
YPZhangfebf7302016-05-24 16:45:56 -0700163 # Balance Master
Devin Lim142b5342017-07-20 15:22:39 -0700164 main.Cluster.active( 0 ).CLI.balanceMasters()
You Wang0b9039d2017-01-12 16:51:29 -0800165 time.sleep( main.setMasterSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700166 if main.Cluster.numCtrls:
167 main.Cluster.active( 0 ).CLI.deviceRole( main.end1[ 'name' ], main.Cluster.active( 0 ).ipAddress )
168 main.Cluster.active( 0 ).CLI.deviceRole( main.end2[ 'name' ], main.Cluster.active( 0 ).ipAddress )
YPZhang2b9b26d2016-06-20 16:18:29 -0700169 time.sleep( main.setMasterSleep )
Devin Lime6fe3c42017-10-18 16:28:40 -0700170 if not main.cfgCheck:
171 main.log.error( "Setting configuration to the ONOS failed. Skip the rest of the steps" )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700172
173 def CASE2( self, main ):
cameron@onlab.us78b89652015-07-08 15:21:03 -0700174 import time
175 import numpy
176 import datetime
YPZhangfebf7302016-05-24 16:45:56 -0700177 import json
178 # from scipy import stats
Devin Lime6fe3c42017-10-18 16:28:40 -0700179 testResult = main.TRUE
180 main.case( "Intent Reroute starts" )
181 main.step( "Checking intent reroute" )
182 if main.cfgCheck:
183 print( main.intentsList )
184 for batchSize in main.intentsList:
185 main.batchSize = batchSize
186 main.log.report( "Intent Batch size: " + str( batchSize ) + "\n " )
187 firstLocalLatencies = []
188 lastLocalLatencies = []
189 firstGlobalLatencies = []
190 lastGlobalLatencies = []
191 main.startLine = {}
192 main.validRun = 0
193 main.invalidRun = 0
194 while main.validRun <= main.warmUp + main.sampleSize and main.invalidRun <= main.maxInvalidRun:
195 if main.validRun >= main.warmUp:
196 main.log.info( "================================================" )
197 main.log.info( "Valid iteration: {} ".format( main.validRun - main.warmUp ) )
198 main.log.info( "Total iteration: {}".format( main.validRun + main.invalidRun ) )
199 main.log.info( "================================================" )
200 else:
201 main.log.info( "====================Warm Up=====================" )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700202
Devin Lime6fe3c42017-10-18 16:28:40 -0700203 # push intents
204 main.Cluster.active( 0 ).CLI.pushTestIntents( main.ingress,
205 main.egress,
206 main.batchSize,
207 offset=1,
208 options="-i",
209 timeout=main.timeout )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700210
Devin Lime6fe3c42017-10-18 16:28:40 -0700211 # check links, flows and intents
212 main.intentRerouteLatFuncs.sanityCheck( main,
213 main.deviceCount * 2,
214 batchSize * ( main.deviceCount - 1 ),
215 main.batchSize )
216 if not main.verify:
217 main.log.warn( "Sanity check failed, skipping this iteration..." )
218 continue
cameron@onlab.us78b89652015-07-08 15:21:03 -0700219
Devin Lime6fe3c42017-10-18 16:28:40 -0700220 # Insert one line in karaf.log before link down
221 main.Cluster.command( "log",
222 args=[ "\'Scale: {}, Batch:{}, Iteration: {}\'".format(
223 main.Cluster.numCtrls, batchSize, main.validRun + main.invalidRun ) ],
224 returnBool=True, specificDriver=2 )
225 # bring link down
226 main.Cluster.active( 0 ).CLI.link( main.end1[ 'port' ], main.end2[ 'port' ], "down",
227 timeout=main.timeout, showResponse=False )
You Wang6d301d42017-04-21 10:49:33 -0700228
Devin Lime6fe3c42017-10-18 16:28:40 -0700229 # check links, flows and intents
230 main.intentRerouteLatFuncs.sanityCheck( main,
231 ( main.deviceCount - 1 ) * 2,
232 batchSize * main.deviceCount,
233 main.batchSize )
234 if not main.verify:
235 main.log.warn( "Sanity check failed, skipping this iteration..." )
236 continue
You Wang6d301d42017-04-21 10:49:33 -0700237
Devin Lime6fe3c42017-10-18 16:28:40 -0700238 # Get timestamp of last LINK_REMOVED event as separator between iterations
239 skip = False
240 for i in range( main.Cluster.numCtrls ):
You Wang6d301d42017-04-21 10:49:33 -0700241 logNum = main.intentRerouteLatFuncs.getLogNum( main, i )
Devin Lim142b5342017-07-20 15:22:39 -0700242 timestamp = str( main.Cluster.active( i ).CLI.getTimeStampFromLog( "last",
243 "LINK_REMOVED",
244 "time = ", " ",
245 logNum=logNum ) )
Devin Lime6fe3c42017-10-18 16:28:40 -0700246 if timestamp == main.ERROR:
247 # Try again in case that the log number just increased
248 logNum = main.intentRerouteLatFuncs.getLogNum( main, i )
249 timestamp = str( main.Cluster.active( i ).CLI.getTimeStampFromLog( "last",
250 "LINK_REMOVED",
251 "time = ", " ",
252 logNum=logNum ) )
253 if timestamp == main.ERROR:
254 main.log.warn( "Cannot find the event we want in the log, skipping this iteration..." )
255 main.intentRerouteLatFuncs.bringBackTopology( main )
256 if main.validRun >= main.warmUp:
257 main.invalidRun += 1
258 else:
259 main.validRun += 1
260 skip = True
261 break
262 else:
263 main.startLine[ i ] = timestamp
264 main.log.info( "Timestamp of last LINK_REMOVED event on node {} is {}".format( i + 1,
265 main.startLine[ i ] ) )
266 if skip:
267 continue
268
269 # calculate values
270 topologyTimestamps = main.intentRerouteLatFuncs.getTopologyTimestamps( main )
271 intentTimestamps = main.intentRerouteLatFuncs.getIntentTimestamps( main )
272 if intentTimestamps == main.ERROR or topologyTimestamps == main.ERROR:
273 main.log.info( "Got invalid timestamp, skipping this iteration..." )
You Wang6d301d42017-04-21 10:49:33 -0700274 main.intentRerouteLatFuncs.bringBackTopology( main )
275 if main.validRun >= main.warmUp:
276 main.invalidRun += 1
277 else:
278 main.validRun += 1
Devin Lime6fe3c42017-10-18 16:28:40 -0700279 continue
You Wang6d301d42017-04-21 10:49:33 -0700280 else:
Devin Lime6fe3c42017-10-18 16:28:40 -0700281 main.log.info( "Got valid timestamps" )
You Wang6d301d42017-04-21 10:49:33 -0700282
Devin Lime6fe3c42017-10-18 16:28:40 -0700283 firstLocalLatnecy, lastLocalLatnecy, firstGlobalLatency, lastGlobalLatnecy \
284 = main.intentRerouteLatFuncs.calculateLatency( main, topologyTimestamps, intentTimestamps )
285 if firstLocalLatnecy < 0:
286 main.log.info( "Got negative latency, skipping this iteration..." )
287 main.intentRerouteLatFuncs.bringBackTopology( main )
288 if main.validRun >= main.warmUp:
289 main.invalidRun += 1
290 else:
291 main.validRun += 1
292 continue
YPZhang8742d2e2016-06-16 15:31:58 -0700293 else:
Devin Lime6fe3c42017-10-18 16:28:40 -0700294 main.log.info( "Got valid latencies" )
Chiyu Chengec63bde2016-11-17 18:11:36 -0800295 main.validRun += 1
You Wang6d301d42017-04-21 10:49:33 -0700296
You Wang6d301d42017-04-21 10:49:33 -0700297 if main.validRun >= main.warmUp:
Devin Lime6fe3c42017-10-18 16:28:40 -0700298 firstLocalLatencies.append( firstLocalLatnecy )
299 lastLocalLatencies.append( lastLocalLatnecy )
300 firstGlobalLatencies.append( firstGlobalLatency )
301 lastGlobalLatencies.append( lastGlobalLatnecy )
YPZhangfebf7302016-05-24 16:45:56 -0700302
Devin Lime6fe3c42017-10-18 16:28:40 -0700303 # bring up link and withdraw intents
304 main.Cluster.active( 0 ).CLI.link( main.end1[ 'port' ],
305 main.end2[ 'port' ],
306 "up",
307 timeout=main.timeout )
308 main.Cluster.active( 0 ).CLI.pushTestIntents( main.ingress,
309 main.egress,
310 batchSize,
311 offset=1,
312 options="-w",
313 timeout=main.timeout )
314 main.Cluster.active( 0 ).CLI.purgeWithdrawnIntents()
You Wang6d301d42017-04-21 10:49:33 -0700315
Devin Lime6fe3c42017-10-18 16:28:40 -0700316 # check links, flows and intents
317 main.intentRerouteLatFuncs.sanityCheck( main, main.deviceCount * 2, 0, 0 )
318 if not main.verify:
319 main.log.warn( "Sanity check failed, skipping this iteration..." )
320 continue
321 result = ( main.TRUE if main.invalidRun <= main.maxInvalidRun else main.FALSE )
322 aveLocalLatency = numpy.average( lastLocalLatencies ) if lastLocalLatencies and result else 0
323 aveGlobalLatency = numpy.average( lastGlobalLatencies ) if lastGlobalLatencies and result else 0
324 stdLocalLatency = numpy.std( lastLocalLatencies ) if lastLocalLatencies and result else 0
325 stdGlobalLatency = numpy.std( lastGlobalLatencies ) if lastGlobalLatencies and result else 0
326 testResult = testResult and result
You Wang6d301d42017-04-21 10:49:33 -0700327
Devin Lime6fe3c42017-10-18 16:28:40 -0700328 main.log.report( "Scale: " + str( main.Cluster.numCtrls ) + " \tIntent batch: " + str( batchSize ) )
329 main.log.report( "Local latency average:................" + str( aveLocalLatency ) )
330 main.log.report( "Global latency average:................" + str( aveGlobalLatency ) )
331 main.log.report( "Local latency std:................" + str( stdLocalLatency ) )
332 main.log.report( "Global latency std:................" + str( stdGlobalLatency ) )
333 main.log.report( "________________________________________________________" )
YPZhangfebf7302016-05-24 16:45:56 -0700334
Devin Lime6fe3c42017-10-18 16:28:40 -0700335 if not ( numpy.isnan( aveLocalLatency ) or numpy.isnan( aveGlobalLatency ) ):
336 # check if got NaN for result
337 resultsDB = open( main.dbFileName, "a" )
338 resultsDB.write( "'" + main.commit + "'," )
339 resultsDB.write( str( main.Cluster.numCtrls ) + "," )
340 resultsDB.write( str( batchSize ) + "," )
341 resultsDB.write( str( aveLocalLatency ) + "," )
342 resultsDB.write( str( stdLocalLatency ) + "\n" )
343 resultsDB.close()
344 else:
345 testResult = main.FALSE
346 utilities.assert_equals( expect=main.TRUE,
347 actual=testResult,
348 onpass="Installing and withdrawing intents reroute properly",
349 onfail="There was something wrong installing and withdrawing intents reroute" )