blob: da96551c215ad5f7ee6b28c3e9c2b120782982f4 [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"""
22SCPFintentRerouteLat
23 - Test Intent Reroute Latency
24 - Test Algorithm:
25 1. Start Null Provider reroute Topology
26 2. Using Push-test-intents to push batch size intents from switch 1 to switch 7
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070027 3. Cut the link between switch 3 and switch 4 ( the path will reroute to switch 8 )
YPZhangfebf7302016-05-24 16:45:56 -070028 4. Get the topology time stamp
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070029 5. Get Intent reroute( Installed ) time stamp from each nodes
YPZhangfebf7302016-05-24 16:45:56 -070030 6. Use the latest intent time stamp subtract topology time stamp
31 - This test will run 5 warm up by default, warm up iteration can be setup in Param file
32 - The intent batch size will default set to 1, 100, and 1000, also can be set in Param file
33 - The unit of the latency result is milliseconds
34"""
cameron@onlab.us78b89652015-07-08 15:21:03 -070035class SCPFintentRerouteLat:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070036
Devin Lim142b5342017-07-20 15:22:39 -070037 def __init__( self ):
cameron@onlab.us78b89652015-07-08 15:21:03 -070038 self.default = ''
39
YPZhangfebf7302016-05-24 16:45:56 -070040 def CASE0( self, main ):
Chiyu Chengec63bde2016-11-17 18:11:36 -080041 import imp
42 import os
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070043 """
YPZhangfebf7302016-05-24 16:45:56 -070044 - GIT
45 - BUILDING ONOS
46 Pull specific ONOS branch, then Build ONOS ono ONOS Bench.
47 This step is usually skipped. Because in a Jenkins driven automated
48 test env. We want Jenkins jobs to pull&build for flexibility to handle
49 different versions of ONOS.
50 - Construct tests variables
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070051 """
Devin Lim58046fa2017-07-05 16:55:00 -070052 try:
53 from tests.dependencies.ONOSSetup import ONOSSetup
54 main.testSetUp = ONOSSetup()
55 except ImportError:
56 main.log.error( "ONOSSetup not found. exiting the test" )
Devin Lim44075962017-08-11 10:56:37 -070057 main.cleanAndExit()
Devin Lim58046fa2017-07-05 16:55:00 -070058 main.testSetUp.envSetupDescription()
59 stepResult = main.FALSE
60 try:
Devin Lim58046fa2017-07-05 16:55:00 -070061 main.apps = main.params[ 'ENV' ][ 'cellApps' ]
62 main.BENCHUser = main.params[ 'BENCH' ][ 'user' ]
63 main.BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
64 main.MN1Ip = main.params[ 'MN' ][ 'ip1' ]
Devin Lim58046fa2017-07-05 16:55:00 -070065 main.cellName = main.params[ 'ENV' ][ 'cellName' ]
Devin Lim142b5342017-07-20 15:22:39 -070066 main.scale = ( main.params[ 'SCALE' ] ).split( "," )
Devin Lim58046fa2017-07-05 16:55:00 -070067 main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
68 main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
69 main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
70 main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
71 main.setMasterSleep = int( main.params[ 'SLEEP' ][ 'setmaster' ] )
72 main.verifyAttempts = int( main.params[ 'ATTEMPTS' ][ 'verify' ] )
73 main.maxInvalidRun = int( main.params[ 'ATTEMPTS' ][ 'maxInvalidRun' ] )
Devin Lime6fe3c42017-10-18 16:28:40 -070074 main.cfgRetry = int( main.params[ 'ATTEMPTS' ][ 'cfg' ] )
Devin Lim58046fa2017-07-05 16:55:00 -070075 main.sampleSize = int( main.params[ 'TEST' ][ 'sampleSize' ] )
Devin Lim142b5342017-07-20 15:22:39 -070076 main.intentManagerCfg = main.params[ 'CFG' ][ 'intentManager' ]
77 main.intentConfigRegiCfg = main.params[ 'CFG' ][ 'intentConfigRegi' ]
78 main.nullProviderCfg = main.params[ 'CFG' ][ 'nullProvider' ]
Devin Lim58046fa2017-07-05 16:55:00 -070079 main.warmUp = int( main.params[ 'TEST' ][ 'warmUp' ] )
80 main.ingress = main.params[ 'TEST' ][ 'ingress' ]
81 main.egress = main.params[ 'TEST' ][ 'egress' ]
82 main.debug = main.params[ 'TEST' ][ 'debug' ]
83 main.flowObj = main.params[ 'TEST' ][ 'flowObj' ]
84 main.deviceCount = int( main.params[ 'TEST' ][ 'deviceCount' ] )
85 main.end1 = main.params[ 'TEST' ][ 'end1' ]
86 main.end2 = main.params[ 'TEST' ][ 'end2' ]
87 main.searchTerm = main.params[ 'SEARCHTERM' ]
88 if main.flowObj == "True":
89 main.flowObj = True
90 main.dbFileName = main.params[ 'DATABASE' ][ 'dbFlowObj' ]
91 main.intentsList = ( main.params[ 'TEST' ][ 'FObjintents' ] ).split( "," )
92 else:
93 main.flowObj = False
94 main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
95 main.intentsList = ( main.params[ 'TEST' ][ 'intents' ] ).split( "," )
cameron@onlab.us78b89652015-07-08 15:21:03 -070096
Devin Lim142b5342017-07-20 15:22:39 -070097 stepResult = main.testSetUp.envSetup()
YPZhangfebf7302016-05-24 16:45:56 -070098
Devin Lim142b5342017-07-20 15:22:39 -070099 for i in range( 0, len( main.intentsList ) ):
Devin Lim58046fa2017-07-05 16:55:00 -0700100 main.intentsList[ i ] = int( main.intentsList[ i ] )
101 # Create DataBase file
102 main.log.info( "Create Database file " + main.dbFileName )
103 resultsDB = open( main.dbFileName, "w+" )
104 resultsDB.close()
105 file1 = main.params[ "DEPENDENCY" ][ "FILE1" ]
106 main.dependencyPath = os.path.dirname( os.getcwd() ) + main.params[ "DEPENDENCY" ][ "PATH" ]
107 main.intentRerouteLatFuncs = imp.load_source( file1, main.dependencyPath + file1 + ".py" )
YPZhangfebf7302016-05-24 16:45:56 -0700108
Devin Lim58046fa2017-07-05 16:55:00 -0700109 main.record = 0
110 except Exception as e:
111 main.testSetUp.envSetupException( e )
112 main.testSetUp.evnSetupConclusion( stepResult )
You Wang47b91832017-08-02 11:36:13 -0700113 main.commit = main.commit.split( " " )[ 1 ]
YPZhangfebf7302016-05-24 16:45:56 -0700114
115 def CASE1( self, main ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700116 """
YPZhangfebf7302016-05-24 16:45:56 -0700117 clean up test environment and set up
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700118 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700119 import time
120
YPZhangfebf7302016-05-24 16:45:56 -0700121 main.maxNumBatch = 0
You Wanga0f6ff62018-01-11 15:46:30 -0800122 main.testSetUp.ONOSSetUp( main.Cluster, True,
Devin Lim142b5342017-07-20 15:22:39 -0700123 cellName=main.cellName, killRemoveMax=False )
Devin Lime6fe3c42017-10-18 16:28:40 -0700124 configRetry = 0
125 main.cfgCheck = False
126 while configRetry < main.cfgRetry:
127 # configure apps
128 stepResult = main.TRUE
129 stepResult = stepResult and \
130 main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
131 "deviceCount",
132 value=main.deviceCount )
133
134 stepResult = stepResult and \
135 main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
136 "topoShape",
137 value="reroute" )
138 stepResult = stepResult and \
139 main.Cluster.active( 0 ).CLI.setCfg( main.nullProviderCfg,
140 "enabled",
141 value="true" )
142
143 stepResult = stepResult and \
144 main.Cluster.active( 0 ).CLI.setCfg( main.intentManagerCfg,
145 "skipReleaseResourcesOnWithdrawal",
146 value="true" )
147 if main.flowObj:
148 stepResult = stepResult and \
149 main.Cluster.active( 0 ).CLI.setCfg( main.intentConfigRegiCfg,
150 "useFlowObjectives",
151 value="true" )
Devin Lime6fe3c42017-10-18 16:28:40 -0700152 if stepResult:
153 main.cfgCheck = True
154 break
155 configRetry += 1
156 time.sleep( main.verifySleep )
157
Chiyu Chengec63bde2016-11-17 18:11:36 -0800158 time.sleep( main.startUpSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700159 for ctrl in main.Cluster.active():
160 ctrl.CLI.logSet( "DEBUG", "org.onosproject.metrics.topology" )
161 ctrl.CLI.logSet( "DEBUG", "org.onosproject.metrics.intent" )
YPZhangfebf7302016-05-24 16:45:56 -0700162 # Balance Master
Devin Lim142b5342017-07-20 15:22:39 -0700163 main.Cluster.active( 0 ).CLI.balanceMasters()
You Wang0b9039d2017-01-12 16:51:29 -0800164 time.sleep( main.setMasterSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700165 if main.Cluster.numCtrls:
166 main.Cluster.active( 0 ).CLI.deviceRole( main.end1[ 'name' ], main.Cluster.active( 0 ).ipAddress )
167 main.Cluster.active( 0 ).CLI.deviceRole( main.end2[ 'name' ], main.Cluster.active( 0 ).ipAddress )
YPZhang2b9b26d2016-06-20 16:18:29 -0700168 time.sleep( main.setMasterSleep )
Devin Lime6fe3c42017-10-18 16:28:40 -0700169 if not main.cfgCheck:
170 main.log.error( "Setting configuration to the ONOS failed. Skip the rest of the steps" )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700171
172 def CASE2( self, main ):
cameron@onlab.us78b89652015-07-08 15:21:03 -0700173 import time
174 import numpy
175 import datetime
YPZhangfebf7302016-05-24 16:45:56 -0700176 import json
177 # from scipy import stats
Devin Lime6fe3c42017-10-18 16:28:40 -0700178 testResult = main.TRUE
179 main.case( "Intent Reroute starts" )
180 main.step( "Checking intent reroute" )
181 if main.cfgCheck:
182 print( main.intentsList )
183 for batchSize in main.intentsList:
184 main.batchSize = batchSize
185 main.log.report( "Intent Batch size: " + str( batchSize ) + "\n " )
186 firstLocalLatencies = []
187 lastLocalLatencies = []
188 firstGlobalLatencies = []
189 lastGlobalLatencies = []
190 main.startLine = {}
191 main.validRun = 0
192 main.invalidRun = 0
193 while main.validRun <= main.warmUp + main.sampleSize and main.invalidRun <= main.maxInvalidRun:
194 if main.validRun >= main.warmUp:
195 main.log.info( "================================================" )
196 main.log.info( "Valid iteration: {} ".format( main.validRun - main.warmUp ) )
197 main.log.info( "Total iteration: {}".format( main.validRun + main.invalidRun ) )
198 main.log.info( "================================================" )
199 else:
200 main.log.info( "====================Warm Up=====================" )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700201
Devin Lime6fe3c42017-10-18 16:28:40 -0700202 # push intents
203 main.Cluster.active( 0 ).CLI.pushTestIntents( main.ingress,
204 main.egress,
205 main.batchSize,
206 offset=1,
207 options="-i",
208 timeout=main.timeout )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700209
Devin Lime6fe3c42017-10-18 16:28:40 -0700210 # check links, flows and intents
211 main.intentRerouteLatFuncs.sanityCheck( main,
212 main.deviceCount * 2,
213 batchSize * ( main.deviceCount - 1 ),
214 main.batchSize )
215 if not main.verify:
216 main.log.warn( "Sanity check failed, skipping this iteration..." )
217 continue
cameron@onlab.us78b89652015-07-08 15:21:03 -0700218
Devin Lime6fe3c42017-10-18 16:28:40 -0700219 # Insert one line in karaf.log before link down
220 main.Cluster.command( "log",
221 args=[ "\'Scale: {}, Batch:{}, Iteration: {}\'".format(
222 main.Cluster.numCtrls, batchSize, main.validRun + main.invalidRun ) ],
223 returnBool=True, specificDriver=2 )
224 # bring link down
225 main.Cluster.active( 0 ).CLI.link( main.end1[ 'port' ], main.end2[ 'port' ], "down",
226 timeout=main.timeout, showResponse=False )
You Wang6d301d42017-04-21 10:49:33 -0700227
Devin Lime6fe3c42017-10-18 16:28:40 -0700228 # check links, flows and intents
229 main.intentRerouteLatFuncs.sanityCheck( main,
230 ( main.deviceCount - 1 ) * 2,
231 batchSize * main.deviceCount,
232 main.batchSize )
233 if not main.verify:
234 main.log.warn( "Sanity check failed, skipping this iteration..." )
235 continue
You Wang6d301d42017-04-21 10:49:33 -0700236
Devin Lime6fe3c42017-10-18 16:28:40 -0700237 # Get timestamp of last LINK_REMOVED event as separator between iterations
238 skip = False
239 for i in range( main.Cluster.numCtrls ):
You Wang6d301d42017-04-21 10:49:33 -0700240 logNum = main.intentRerouteLatFuncs.getLogNum( main, i )
Devin Lim142b5342017-07-20 15:22:39 -0700241 timestamp = str( main.Cluster.active( i ).CLI.getTimeStampFromLog( "last",
242 "LINK_REMOVED",
243 "time = ", " ",
244 logNum=logNum ) )
Devin Lime6fe3c42017-10-18 16:28:40 -0700245 if timestamp == main.ERROR:
246 # Try again in case that the log number just increased
247 logNum = main.intentRerouteLatFuncs.getLogNum( main, i )
248 timestamp = str( main.Cluster.active( i ).CLI.getTimeStampFromLog( "last",
249 "LINK_REMOVED",
250 "time = ", " ",
251 logNum=logNum ) )
252 if timestamp == main.ERROR:
253 main.log.warn( "Cannot find the event we want in the log, skipping this iteration..." )
254 main.intentRerouteLatFuncs.bringBackTopology( main )
255 if main.validRun >= main.warmUp:
256 main.invalidRun += 1
257 else:
258 main.validRun += 1
259 skip = True
260 break
261 else:
262 main.startLine[ i ] = timestamp
263 main.log.info( "Timestamp of last LINK_REMOVED event on node {} is {}".format( i + 1,
264 main.startLine[ i ] ) )
265 if skip:
266 continue
267
268 # calculate values
269 topologyTimestamps = main.intentRerouteLatFuncs.getTopologyTimestamps( main )
270 intentTimestamps = main.intentRerouteLatFuncs.getIntentTimestamps( main )
271 if intentTimestamps == main.ERROR or topologyTimestamps == main.ERROR:
272 main.log.info( "Got invalid timestamp, skipping this iteration..." )
You Wang6d301d42017-04-21 10:49:33 -0700273 main.intentRerouteLatFuncs.bringBackTopology( main )
274 if main.validRun >= main.warmUp:
275 main.invalidRun += 1
276 else:
277 main.validRun += 1
Devin Lime6fe3c42017-10-18 16:28:40 -0700278 continue
You Wang6d301d42017-04-21 10:49:33 -0700279 else:
Devin Lime6fe3c42017-10-18 16:28:40 -0700280 main.log.info( "Got valid timestamps" )
You Wang6d301d42017-04-21 10:49:33 -0700281
Devin Lime6fe3c42017-10-18 16:28:40 -0700282 firstLocalLatnecy, lastLocalLatnecy, firstGlobalLatency, lastGlobalLatnecy \
283 = main.intentRerouteLatFuncs.calculateLatency( main, topologyTimestamps, intentTimestamps )
You Wangdd20dc62019-02-19 14:06:19 -0800284 maxLatency = float( main.params[ 'TEST' ][ 'maxLatency' ] )
285 if firstLocalLatnecy < 0 or lastLocalLatnecy < 0 or \
286 firstLocalLatnecy > maxLatency or lastLocalLatnecy > maxLatency:
287 main.log.info( "Got invalid latency, skipping this iteration..." )
Devin Lime6fe3c42017-10-18 16:28:40 -0700288 main.intentRerouteLatFuncs.bringBackTopology( main )
289 if main.validRun >= main.warmUp:
290 main.invalidRun += 1
291 else:
292 main.validRun += 1
293 continue
YPZhang8742d2e2016-06-16 15:31:58 -0700294 else:
Devin Lime6fe3c42017-10-18 16:28:40 -0700295 main.log.info( "Got valid latencies" )
Chiyu Chengec63bde2016-11-17 18:11:36 -0800296 main.validRun += 1
You Wang6d301d42017-04-21 10:49:33 -0700297
You Wang6d301d42017-04-21 10:49:33 -0700298 if main.validRun >= main.warmUp:
Devin Lime6fe3c42017-10-18 16:28:40 -0700299 firstLocalLatencies.append( firstLocalLatnecy )
300 lastLocalLatencies.append( lastLocalLatnecy )
301 firstGlobalLatencies.append( firstGlobalLatency )
302 lastGlobalLatencies.append( lastGlobalLatnecy )
YPZhangfebf7302016-05-24 16:45:56 -0700303
Devin Lime6fe3c42017-10-18 16:28:40 -0700304 # bring up link and withdraw intents
305 main.Cluster.active( 0 ).CLI.link( main.end1[ 'port' ],
306 main.end2[ 'port' ],
307 "up",
308 timeout=main.timeout )
309 main.Cluster.active( 0 ).CLI.pushTestIntents( main.ingress,
310 main.egress,
311 batchSize,
312 offset=1,
313 options="-w",
314 timeout=main.timeout )
315 main.Cluster.active( 0 ).CLI.purgeWithdrawnIntents()
You Wang6d301d42017-04-21 10:49:33 -0700316
Devin Lime6fe3c42017-10-18 16:28:40 -0700317 # check links, flows and intents
318 main.intentRerouteLatFuncs.sanityCheck( main, main.deviceCount * 2, 0, 0 )
319 if not main.verify:
320 main.log.warn( "Sanity check failed, skipping this iteration..." )
321 continue
322 result = ( main.TRUE if main.invalidRun <= main.maxInvalidRun else main.FALSE )
323 aveLocalLatency = numpy.average( lastLocalLatencies ) if lastLocalLatencies and result else 0
324 aveGlobalLatency = numpy.average( lastGlobalLatencies ) if lastGlobalLatencies and result else 0
325 stdLocalLatency = numpy.std( lastLocalLatencies ) if lastLocalLatencies and result else 0
326 stdGlobalLatency = numpy.std( lastGlobalLatencies ) if lastGlobalLatencies and result else 0
327 testResult = testResult and result
You Wang6d301d42017-04-21 10:49:33 -0700328
Devin Lime6fe3c42017-10-18 16:28:40 -0700329 main.log.report( "Scale: " + str( main.Cluster.numCtrls ) + " \tIntent batch: " + str( batchSize ) )
330 main.log.report( "Local latency average:................" + str( aveLocalLatency ) )
331 main.log.report( "Global latency average:................" + str( aveGlobalLatency ) )
332 main.log.report( "Local latency std:................" + str( stdLocalLatency ) )
333 main.log.report( "Global latency std:................" + str( stdGlobalLatency ) )
334 main.log.report( "________________________________________________________" )
YPZhangfebf7302016-05-24 16:45:56 -0700335
You Wang012300d2019-02-21 17:55:39 -0800336 # Check test results
337 index = len( main.intentsList ) * ( main.cycle - 1 ) + main.intentsList.index( batchSize )
338 # Check installation results
339 if main.flowObj:
340 threshold = float( main.params[ 'ALARM' ][ 'maxLatFlowObj' ].split( ',' )[ index ])
341 else:
342 threshold = float( main.params[ 'ALARM' ][ 'maxLat' ].split( ',' )[ index ])
343 if aveLocalLatency > threshold:
344 main.log.alarm( "{}-node install avg: {} ms > {} ms".format( main.Cluster.numCtrls,
345 aveLocalLatency, threshold ) )
346
Devin Lime6fe3c42017-10-18 16:28:40 -0700347 if not ( numpy.isnan( aveLocalLatency ) or numpy.isnan( aveGlobalLatency ) ):
348 # check if got NaN for result
349 resultsDB = open( main.dbFileName, "a" )
350 resultsDB.write( "'" + main.commit + "'," )
351 resultsDB.write( str( main.Cluster.numCtrls ) + "," )
352 resultsDB.write( str( batchSize ) + "," )
353 resultsDB.write( str( aveLocalLatency ) + "," )
354 resultsDB.write( str( stdLocalLatency ) + "\n" )
355 resultsDB.close()
356 else:
357 testResult = main.FALSE
358 utilities.assert_equals( expect=main.TRUE,
359 actual=testResult,
360 onpass="Installing and withdrawing intents reroute properly",
361 onfail="There was something wrong installing and withdrawing intents reroute" )