readding TopoPerfNextBM
diff --git a/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.params b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.params
new file mode 100644
index 0000000..7b6e83f
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.params
@@ -0,0 +1,96 @@
+<PARAMS>
+ <testcases>1,2,3,4,2,3,4,2,3,4,2,3</testcases>
+
+ <ENV>
+ <cellName>topo_perf_test</cellName>
+ <cellFeatures>"drivers,metrics,openflow"</cellFeatures>
+ </ENV>
+
+ <GIT>
+ #autoPull 'on' or 'off'
+ <autoPull>off</autoPull>
+ <checkout>master</checkout>
+ </GIT>
+
+ <CTRL>
+ <user>admin</user>
+ <ip1>10.128.174.1</ip1>
+ <port1>6633</port1>
+ <ip2>10.128.174.2</ip2>
+ <port2>6633</port2>
+ <ip3>10.128.174.3</ip3>
+ <port3>6633</port3>
+ <ip4>10.128.174.4</ip4>
+
+ <ip5>10.128.174.5</ip5>
+ <ip6>10.128.174.6</ip6>
+ <ip7>10.128.174.7</ip7>
+ </CTRL>
+
+ <MN>
+ <ip1>10.128.10.90</ip1>
+ <ip2>10.128.10.91</ip2>
+ </MN>
+
+ <BENCH>
+ <ip>10.128.174.10</ip>
+ </BENCH>
+
+ <TSHARK>
+ <ofpPortStatus>OF 1.3 146</ofpPortStatus>
+ <ofpRoleReply>OF 1.3 90 of_role_reply</ofpRoleReply>
+ <featureReply>OF 1.3 98 of_features_reply</featureReply>
+ <roleRequest>OF 1.3 90 of_role_request</roleRequest>
+ <tcpSynAck>TCP 74 6633</tcpSynAck>
+ <finAckSequence>FIN</finAckSequence>
+ </TSHARK>
+
+ <TEST>
+ #'on' or 'off' debug mode.
+ #If on, logging will be more verbose and
+ #tshark pcap will be enabled
+ #pcap file located at /tmp/'capture_name'
+ <debugMode>off</debugMode>
+ <onosLogFile>/opt/onos/log/karaf*</onosLogFile>
+ <mci>off</mci>
+
+ <topoConfigFile>
+ single_topo_event_accumulator.cfg
+ </topoConfigFile>
+ <topoConfigName>
+ org.onlab.onos.net.topology.impl.DefaultTopologyProvider.cfg
+ </topoConfigName>
+
+ #Number of times to iterate each case
+ <numIter>13</numIter>
+ <numSwitch>2</numSwitch>
+ #Number of iterations to ignore initially
+ <iterIgnore>2</iterIgnore>
+
+ <singleSwThreshold>0,1000</singleSwThreshold>
+ <portUpThreshold>0,1000</portUpThreshold>
+ <portDownThreshold>0,1000</portDownThreshold>
+ <linkUpThreshold>0,10000</linkUpThreshold>
+ <linkDownThreshold>0,10000</linkDownThreshold>
+ <swDisc100Threshold>0,10000</swDisc100Threshold>
+
+ <tabletFile>tablets_3node.json</tabletFile>
+ </TEST>
+
+ <DB>
+ <postToDB>on</postToDB>
+ <portEventResultPath>
+ /home/admin/ONLabTest/TestON/tests/TopoPerfNextBM/portEventResultDb.log
+ </portEventResultPath>
+ <switchEventResultPath>
+ /home/admin/ONLabTest/TestON/tests/TopoPerfNextBM/switchEventResultDb.log
+ </switchEventResultPath>
+ </DB>
+
+ <JSON>
+ <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
+ <hostTimestamp>topologyHostEventTimestamp</hostTimestamp>
+ <linkTimestamp>topologyLinkEventTimestamp</linkTimestamp>
+ <graphTimestamp>topologyGraphEventTimestamp</graphTimestamp>
+ </JSON>
+</PARAMS>
diff --git a/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.py b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.py
new file mode 100644
index 0000000..e2245ba
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.py
@@ -0,0 +1,1306 @@
+# 2015.03.12 10:22:05 PDT
+#Embedded file name: ../tests/TopoPerfNextBM/TopoPerfNextBM.py
+import time
+import sys
+import os
+import re
+
+class TopoPerfNextBM:
+
+ def __init__(self):
+ self.default = ''
+
+ def CASE1(self, main):
+ """
+ ONOS startup sequence
+ """
+ global clusterCount
+ global timeToPost
+ global runNum
+ global jenkinsBuildNumber
+
+ import time
+ import os
+
+ clusterCount = 1
+ timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
+ runNum = time.strftime('%d%H%M%S')
+ cellName = main.params['ENV']['cellName']
+ gitPull = main.params['GIT']['autoPull']
+ checkoutBranch = main.params['GIT']['checkout']
+
+ # Get jenkins build number from environment.
+ # This environment variable will only exist when
+ # triggered by a jenkins job
+ try:
+ jenkinsBuildNumber = str(os.environ['BUILD_NUMBER'])
+ main.log.report( 'Jenkins build number: ' +
+ jenkinsBuildNumber )
+ except KeyError:
+ # Jenkins build number is also used in posting to DB
+ # If this test is not triggered by jenkins, give
+ # it 0 instead, ensuring that
+ # the DB post will recognize it as a non-jenkins run
+ jenkinsBuildNumber = str(0)
+ main.log.info( 'Job is not run by jenkins. '+
+ 'Build number set to: ' + jenkinsBuildNumber)
+
+ global CLIs
+ CLIs = []
+ global nodes
+ nodes = []
+ global nodeIpList
+ nodeIpList = []
+ for i in range( 1, 8 ):
+ CLIs.append( getattr( main, 'ONOS' + str( i ) + 'cli' ) )
+ nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+ nodeIpList.append( main.params[ 'CTRL' ][ 'ip'+str(i) ] )
+
+ MN1Ip = main.params['MN']['ip1']
+ BENCHIp = main.params['BENCH']['ip']
+ cellFeatures = main.params['ENV']['cellFeatures']
+ topoCfgFile = main.params['TEST']['topoConfigFile']
+ topoCfgName = main.params['TEST']['topoConfigName']
+ portEventResultPath = main.params['DB']['portEventResultPath']
+ switchEventResultPath = main.params['DB']['switchEventResultPath']
+ mvnCleanInstall = main.params['TEST']['mci']
+
+ main.case('Setting up test environment')
+
+ # NOTE: Below is deprecated after new way to install features
+ #main.log.info('Copying topology event accumulator config' +
+ # ' to ONOS /package/etc')
+ #main.ONOSbench.handle.sendline('cp ~/' +
+ # topoCfgFile + ' ~/ONOS/tools/package/etc/' +
+ # topoCfgName)
+ #main.ONOSbench.handle.expect('\\$')
+
+ main.log.report('Setting up test environment')
+
+ main.step('Starting mininet topology ')
+ main.Mininet1.startNet()
+
+ main.step('Cleaning previously installed ONOS if any')
+ # Nodes 2 ~ 7
+ for i in range( 1, 7 ):
+ main.ONOSbench.onosUninstall(nodeIp=nodeIpList[i])
+
+ main.step('Clearing previous DB log file')
+
+ fPortLog = open(portEventResultPath, 'w')
+ fPortLog.write('')
+ fPortLog.close()
+ fSwitchLog = open(switchEventResultPath, 'w')
+ fSwitchLog.write('')
+ fSwitchLog.close()
+
+ main.step('Creating cell file')
+ cellFileResult = main.ONOSbench.createCellFile(
+ BENCHIp, cellName, MN1Ip, cellFeatures, nodeIpList[0])
+
+ main.step('Applying cell file to environment')
+ cellApplyResult = main.ONOSbench.setCell(cellName)
+ verifyCellResult = main.ONOSbench.verifyCell()
+
+ main.step('Git checkout and pull ' + checkoutBranch)
+ if gitPull == 'on':
+ checkoutResult = main.TRUE
+ pullResult = main.ONOSbench.gitPull()
+ else:
+ checkoutResult = main.TRUE
+ pullResult = main.TRUE
+ main.log.info('Skipped git checkout and pull')
+
+ main.log.report('Commit information - ')
+ main.ONOSbench.getVersion(report=True)
+ main.step('Using mvn clean & install')
+ if mvnCleanInstall == 'on':
+ mvnResult = main.ONOSbench.cleanInstall()
+ elif mvnCleanInstall == 'off':
+ main.log.info('mci turned off by settings')
+ mvnResult = main.TRUE
+ main.step('Set cell for ONOS cli env')
+ CLIs[0].setCell(cellName)
+
+ main.step('Creating ONOS package')
+ packageResult = main.ONOSbench.onosPackage()
+
+ main.step('Installing ONOS package')
+ install1Result = main.ONOSbench.onosInstall(node=nodeIpList[0])
+
+ time.sleep(10)
+
+ main.step('Start onos cli')
+ cli1 = CLIs[0].startOnosCli(nodeIpList[0])
+
+ main.step( 'activating essential applications' )
+ CLIs[0].activateApp( 'org.onosproject.metrics' )
+ CLIs[0].activateApp( 'org.onosproject.openflow' )
+
+ main.step( 'Configuring application parameters' )
+
+ configName = 'org.onosproject.net.topology.impl.DefaultTopologyProvider'
+ configParam = 'maxEvents 1'
+ main.ONOSbench.onosCfgSet( nodeIpList[0], configName, configParam )
+ configParam = 'maxBatchMs 0'
+ main.ONOSbench.onosCfgSet( nodeIpList[0], configName, configParam )
+ configParam = 'maxIdleMs 0'
+ main.ONOSbench.onosCfgSet( nodeIpList[0], configName, configParam )
+
+ utilities.assert_equals(expect=main.TRUE,
+ actual=cellFileResult and cellApplyResult and\
+ verifyCellResult and checkoutResult and\
+ pullResult and mvnResult and\
+ install1Result,
+ onpass='Test Environment setup successful',
+ onfail='Failed to setup test environment')
+
+ def CASE2(self, main):
+ """
+ Assign s3 to ONOS1 and measure latency
+
+ There are 4 levels of latency measurements to this test:
+ 1 ) End-to-end measurement: Complete end-to-end measurement
+ from TCP ( SYN/ACK ) handshake to Graph change
+ 2 ) OFP-to-graph measurement: 'ONOS processing' snippet of
+ measurement from OFP Vendor message to Graph change
+ 3 ) OFP-to-device measurement: 'ONOS processing without
+ graph change' snippet of measurement from OFP vendor
+ message to Device change timestamp
+ 4 ) T0-to-device measurement: Measurement that includes
+ the switch handshake to devices timestamp without
+ the graph view change. ( TCP handshake -> Device
+ change )
+ """
+ import time
+ import subprocess
+ import json
+ import requests
+ import os
+ import numpy
+
+ ONOSUser = main.params['CTRL']['user']
+ defaultSwPort = main.params['CTRL']['port1']
+ numIter = main.params['TEST']['numIter']
+ iterIgnore = int(main.params['TEST']['iterIgnore'])
+
+ deviceTimestampKey = main.params['JSON']['deviceTimestamp']
+ graphTimestampKey = main.params['JSON']['graphTimestamp']
+
+ debugMode = main.params['TEST']['debugMode']
+ onosLog = main.params['TEST']['onosLogFile']
+ resultPath = main.params['DB']['switchEventResultPath']
+ thresholdStr = main.params['TEST']['singleSwThreshold']
+ thresholdObj = thresholdStr.split(',')
+ thresholdMin = int(thresholdObj[0])
+ thresholdMax = int(thresholdObj[1])
+
+ # Look for 'role-request' messages,
+ # which replaces the 'vendor' messages previously seen
+ # on OVS 2.0.1
+ tsharkTcpString = main.params[ 'TSHARK' ][ 'tcpSynAck' ]
+ tsharkFeatureReply = main.params[ 'TSHARK' ][ 'featureReply' ]
+ tsharkRoleRequest = main.params[ 'TSHARK' ][ 'roleRequest' ]
+ tsharkOfString = main.params[ 'TSHARK' ][ 'ofpRoleReply' ]
+ tsharkFinAckSequence = main.params[ 'TSHARK' ][ 'finAckSequence' ]
+
+ tsharkOfOutput = '/tmp/tshark_of_topo.txt'
+ tsharkTcpOutput = '/tmp/tshark_tcp_topo.txt'
+ tsharkRoleOutput = '/tmp/tshark_role_request.txt'
+ tsharkFeatureOutput = '/tmp/tshark_feature_reply.txt'
+ tsharkFinAckOutput = '/tmp/tshark_fin_ack.txt'
+
+ # Switch connect measurement list
+ # TCP Syn/Ack -> Feature Reply latency collection for each node
+ tcpToFeatureLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ # Feature Reply -> Role Request latency collection for each node
+ featureToRoleRequestLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ # Role Request -> Role Reply latency collection for each node
+ roleRequestToRoleReplyLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ # Role Reply -> Device Update latency collection for each node
+ roleReplyToDeviceLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ # Device Update -> Graph Update latency collection for each node
+ deviceToGraphLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ endToEndLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+ # Switch disconnect measurement lists
+ # Mininet Fin / Ack -> Mininet Ack
+ finAckTransactionLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ # Mininet Ack -> Device Event
+ ackToDeviceLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ # Device event -> Graph event
+ deviceToGraphDiscLatNodeIter = numpy.zeros((clusterCount,
+ int(numIter)))
+ endToEndDiscLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+ assertion = main.TRUE
+ localTime = time.strftime('%x %X')
+ localTime = localTime.replace('/', '')
+ localTime = localTime.replace(' ', '_')
+ localTime = localTime.replace(':', '')
+
+ if debugMode == 'on':
+ main.ONOS1.tsharkPcap('eth0',
+ '/tmp/single_sw_lat_pcap_' + localTime)
+ main.log.info('Debug mode is on')
+ main.log.report('Latency of adding one switch to controller')
+ main.log.report('First ' + str(iterIgnore) +
+ ' iterations ignored' + ' for jvm warmup time')
+ main.log.report('Total iterations of test: ' + str(numIter))
+
+ for i in range(0, int(numIter)):
+ main.log.info('Starting tshark capture')
+ main.ONOS1.tsharkGrep(tsharkTcpString, tsharkTcpOutput)
+ main.ONOS1.tsharkGrep(tsharkOfString, tsharkOfOutput)
+ main.ONOS1.tsharkGrep(tsharkRoleRequest, tsharkRoleOutput)
+ main.ONOS1.tsharkGrep(tsharkFeatureReply, tsharkFeatureOutput)
+
+ time.sleep(10)
+
+ main.log.info('Assigning s3 to controller')
+ main.Mininet1.assignSwController(sw='3',
+ ip1=nodeIpList[0], port1=defaultSwPort)
+
+ jsonStr = []
+ for node in range (0, clusterCount):
+ metricsSwUp = CLIs[node].topologyEventsMetrics()
+ jsonStr.append(metricsSwUp)
+
+ main.log.info('Stopping all Tshark processes')
+ main.ONOS1.tsharkStop()
+
+ time.sleep(5)
+
+ main.log.info('Copying over tshark files')
+ os.system('scp ' + ONOSUser + '@' + nodeIpList[0] +
+ ':' + tsharkTcpOutput + ' /tmp/')
+ os.system('scp ' + ONOSUser + '@' + nodeIpList[0] +
+ ':' + tsharkRoleOutput + ' /tmp/')
+ os.system('scp ' + ONOSUser + '@' + nodeIpList[0] +
+ ':' + tsharkFeatureOutput + ' /tmp/')
+ os.system('scp ' + ONOSUser + '@' +
+ nodeIpList[0] + ':' + tsharkOfOutput + ' /tmp/')
+
+ # Get tcp syn / ack output
+ time.sleep(1)
+
+ tcpFile = open(tsharkTcpOutput, 'r')
+ tempText = tcpFile.readline()
+ tempText = tempText.split(' ')
+ main.log.info('Object read in from TCP capture: ' +
+ str(tempText))
+
+ if len(tempText) > 1:
+ t0Tcp = float(tempText[1]) * 1000.0
+ else:
+ main.log.error('Tshark output file for TCP' +
+ ' returned unexpected results')
+ t0Tcp = 0
+ assertion = main.FALSE
+ tcpFile.close()
+
+ # Get Role reply output
+ ofFile = open(tsharkOfOutput, 'r')
+ lineOfp = ''
+ while True:
+ tempText = ofFile.readline()
+ if tempText != '':
+ lineOfp = tempText
+ else:
+ break
+ obj = lineOfp.split(' ')
+ main.log.info('Object read in from OFP capture: ' +
+ str(lineOfp))
+ if len(obj) > 1:
+ t0Ofp = float(obj[1]) * 1000.0
+ else:
+ main.log.error('Tshark output file for OFP' +
+ ' returned unexpected results')
+ t0Ofp = 0
+ assertion = main.FALSE
+ ofFile.close()
+
+ # Get role request output
+ roleFile = open(tsharkRoleOutput, 'r')
+ tempText = roleFile.readline()
+ tempText = tempText.split(' ')
+ if len(tempText) > 1:
+ main.log.info('Object read in from role request capture:' +
+ str(tempText))
+ roleTimestamp = float(tempText[1]) * 1000.0
+ else:
+ main.log.error('Tshark output file for role request' +
+ ' returned unexpected results')
+ timeRoleRequest = 0
+ assertion = main.FALSE
+ roleFile.close()
+
+ # Get feature reply output
+ featureFile = open(tsharkFeatureOutput, 'r')
+ tempText = featureFile.readline()
+ tempText = tempText.split(' ')
+ if len(tempText) > 1:
+ main.log.info('Object read in from feature reply capture: '+
+ str(tempText))
+ if tempText[1] != ' ' and float(tempText[1]) > 1400000000.0:
+ temp = tempText[1]
+ elif tempText[2] != ' ' and float(tempText[2]) > 1400000000.0:
+ temp = tempText[2]
+ else:
+ temp = 0
+ featureTimestamp = float(temp) * 1000.0
+ else:
+ main.log.error('Tshark output file for feature reply' +
+ ' returned unexpected results')
+ timeFeatureReply = 0
+ assertion = main.FALSE
+ featureFile.close()
+
+ for node in range(0, clusterCount):
+ nodeNum = node+1
+ #metricsSwUp = CLIs[node].topologyEventsMetrics
+ #jsonStr = metricsSwUp()
+ jsonObj = json.loads(jsonStr[node])
+ if jsonObj:
+ graphTimestamp = jsonObj[graphTimestampKey]['value']
+ deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+ else:
+ main.log.error( "Unexpected JSON object" )
+ # If we could not obtain the JSON object,
+ # set the timestamps to 0, which will be
+ # excluded from the measurement later on
+ # (realized as invalid)
+ graphTimestamp = 0
+ deviceTimestamp = 0
+
+ endToEnd = int(graphTimestamp) - int(t0Tcp)
+
+ # Below are measurement breakdowns of the end-to-end
+ # measurement.
+ tcpToFeature = int(featureTimestamp) - int(t0Tcp)
+ featureToRole = int(roleTimestamp) - int(featureTimestamp)
+ roleToOfp = float(t0Ofp) - float(roleTimestamp)
+ ofpToDevice = float(deviceTimestamp) - float(t0Ofp)
+ # Timestamps gathered from ONOS are millisecond
+ # precision. They are returned as integers, thus no
+ # need to be more precise than 'int'. However,
+ # the processing seems to be mostly under 1 ms,
+ # thus this may be a problem point to handle any
+ # submillisecond output that we are unsure of.
+ # For now, this will be treated as 0 ms if less than 1 ms
+ deviceToGraph = int(graphTimestamp) - int(deviceTimestamp)
+
+ if endToEnd >= thresholdMin and\
+ endToEnd < thresholdMax and i >= iterIgnore:
+ endToEndLatNodeIter[node][i] = endToEnd
+ main.log.info("ONOS "+str(nodeNum)+ " end-to-end: "+
+ str(endToEnd) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+ " end-to-end "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(endToEnd))
+
+ if tcpToFeature >= thresholdMin and\
+ tcpToFeature < thresholdMax and i >= iterIgnore:
+ tcpToFeatureLatNodeIter[node][i] = tcpToFeature
+ main.log.info("ONOS "+str(nodeNum)+ " tcp-to-feature: "+
+ str(tcpToFeature) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+ " tcp-to-feature "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(tcpToFeature))
+
+ if featureToRole >= thresholdMin and\
+ featureToRole < thresholdMax and i >= iterIgnore:
+ featureToRoleRequestLatNodeIter[node][i] = featureToRole
+ main.log.info("ONOS "+str(nodeNum)+ " feature-to-role: "+
+ str(featureToRole) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+ " feature-to-role "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(featureToRole))
+
+ if roleToOfp >= thresholdMin and\
+ roleToOfp < thresholdMax and i >= iterIgnore:
+ roleRequestToRoleReplyLatNodeIter[node][i] = roleToOfp
+ main.log.info("ONOS "+str(nodeNum)+ " role-to-reply: "+
+ str(roleToOfp) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+ " role-to-reply "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(roleToOfp))
+
+ if ofpToDevice >= thresholdMin and\
+ ofpToDevice < thresholdMax and i >= iterIgnore:
+ roleReplyToDeviceLatNodeIter[node][i] = ofpToDevice
+ main.log.info("ONOS "+str(nodeNum)+ " reply-to-device: "+
+ str(ofpToDevice) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+ " reply-to-device "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(ofpToDevice))
+
+ if deviceToGraph >= thresholdMin and\
+ deviceToGraph < thresholdMax and i >= iterIgnore:
+ deviceToGraphLatNodeIter[node][i] = deviceToGraph
+ main.log.info("ONOS "+str(nodeNum)+ " device-to-graph: "+
+ str(deviceToGraph) + " ms")
+ else:
+ if deviceToGraph == 0:
+ deviceToGraphLatNodeIter[node][i] = 0
+ main.log.info("ONOS "+str(nodeNum) +
+ " device-to-graph measurement "+
+ "was set to 0 ms because of precision "+
+ "uncertainty. ")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " device-to-graph "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(deviceToGraph))
+
+ # ********************
+ time.sleep(5)
+
+ # Get device id to remove
+ deviceIdJsonStr = main.ONOS1cli.devices()
+
+ main.log.info( "Device obj obtained: " + str(deviceIdJsonStr) )
+ deviceId = json.loads(deviceIdJsonStr)
+
+ deviceList = []
+ for device in deviceId:
+ deviceList.append(device['id'])
+
+ # Measure switch down metrics
+ # TCP FIN/ACK -> TCP FIN
+ # TCP FIN -> Device Event
+ # Device Event -> Graph Event
+ # Capture switch down FIN / ACK packets
+
+ # The -A 1 grep option allows us to grab 1 extra line after the
+ # last tshark output grepped originally
+ main.ONOS1.tsharkGrep( tsharkFinAckSequence, tsharkFinAckOutput,
+ grepOptions = '-A 1' )
+
+ time.sleep( 5 )
+
+ removeJsonList = []
+
+ main.step('Remove switch from controller')
+ main.Mininet1.deleteSwController('s3')
+ firstDevice = deviceList[0]
+
+ # We need to get metrics before removing
+ # device from the store below.
+ for node in range(0, clusterCount):
+ metricsSwDown = CLIs[node].topologyEventsMetrics
+ jsonStr = metricsSwDown()
+ removeJsonList.append( json.loads(jsonStr) )
+
+ main.ONOS1.tsharkStop()
+
+ main.log.info( "Removing device " +str(firstDevice)+
+ " from ONOS" )
+
+ #if deviceId:
+ main.ONOS1cli.deviceRemove(firstDevice)
+
+ main.log.info('Copying over tshark files')
+ os.system('scp ' + ONOSUser + '@' + nodeIpList[0] +
+ ':' + tsharkFinAckOutput + ' /tmp/')
+
+ time.sleep( 10 )
+ finAckOutputList = []
+ with open(tsharkFinAckOutput, 'r') as f:
+ tempLine = f.readlines()
+ main.log.info('Object read in from FinAck capture: ' +
+ "\n".join(tempLine))
+
+ index = 1
+ for line in tempLine:
+ obj = line.split(' ')
+
+ # There are at least 3 objects in field (valid
+ # tshark output is lengthy)
+ if len(obj) > 2:
+ # If first index of object is like an epoch time
+ if obj[1] != ' ' and float(obj[1]) > 1400000000.0:
+ temp = obj[1]
+ elif obj[2] != ' 'and float(obj[2]) > 1400000000.0:
+ temp = obj[2]
+ elif obj[3] != ' 'and float(obj[3]) > 1400000000.0:
+ temp = obj[3]
+ else:
+ temp = 0
+ if index == 1:
+ tFinAck = float(temp) * 1000.0
+ elif index == 2:
+ continue
+ elif index == 3:
+ tAck = float(temp) * 1000.0
+ else:
+ tFinAck = 0
+ tAck = 0
+ else:
+ main.log.error('Tshark output file for OFP' +
+ ' returned unexpected results')
+ tFinAck = 0
+ tAck = 0
+ assertion = main.FALSE
+
+ index = index+1
+
+ # with open() as f takes care of closing file
+
+ time.sleep(5)
+
+ for node in range(0, clusterCount):
+ nodeNum = node+1
+ jsonObj = removeJsonList[node]
+ if jsonObj:
+ graphTimestamp = jsonObj[graphTimestampKey]['value']
+ deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+ main.log.info("Graph timestamp: "+str(graphTimestamp))
+ main.log.info("Device timestamp: "+str(deviceTimestamp))
+ else:
+ main.log.error( "Unexpected JSON object" )
+ # If we could not obtain the JSON object,
+ # set the timestamps to 0, which will be
+ # excluded from the measurement later on
+ # (realized as invalid)
+ graphTimestamp = 0
+ deviceTimestamp = 0
+
+ finAckTransaction = float(tAck) - float(tFinAck)
+ ackToDevice = float(deviceTimestamp) - float(tAck)
+ deviceToGraph = float(graphTimestamp) - float(deviceTimestamp)
+ endToEndDisc = int(graphTimestamp) - int(tFinAck)
+
+ if endToEndDisc >= thresholdMin and\
+ endToEndDisc < thresholdMax and i >= iterIgnore:
+ endToEndDiscLatNodeIter[node][i] = endToEndDisc
+ main.log.info("ONOS "+str(nodeNum) +
+ "end-to-end disconnection: "+
+ str(endToEndDisc) + " ms" )
+ else:
+ main.log.info("ONOS " + str(nodeNum) +
+ " end-to-end disconnection "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(endToEndDisc))
+
+ if finAckTransaction >= thresholdMin and\
+ finAckTransaction < thresholdMax and i >= iterIgnore:
+ finAckTransactionLatNodeIter[node][i] = finAckTransaction
+ main.log.info("ONOS "+str(nodeNum)+
+ " fin/ack transaction: "+
+ str(finAckTransaction) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " fin/ack transaction "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(finAckTransaction))
+
+ if ackToDevice >= thresholdMin and\
+ ackToDevice < thresholdMax and i >= iterIgnore:
+ ackToDeviceLatNodeIter[node][i] = ackToDevice
+ main.log.info("ONOS "+str(nodeNum)+
+ " ack-to-device: "+
+ str(ackToDevice) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " ack-to-device "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(ackToDevice))
+
+ if deviceToGraph >= thresholdMin and\
+ deviceToGraph < thresholdMax and i >= iterIgnore:
+ deviceToGraphDiscLatNodeIter[node][i] = deviceToGraph
+ main.log.info("ONOS "+str(nodeNum)+
+ " device-to-graph disconnect: "+
+ str(deviceToGraph) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " device-to-graph disconnect "+
+ "measurement ignored due to excess in "+
+ "threshold or premature iteration: ")
+ main.log.info(str(deviceToGraph))
+
+ endToEndAvg = 0
+ ofpToGraphAvg = 0
+ dbCmdList = []
+ for node in range(0, clusterCount):
+ # List of latency for each node
+ endToEndList = []
+ tcpToFeatureList = []
+ featureToRoleList = []
+ roleToOfpList = []
+ ofpToDeviceList = []
+ deviceToGraphList = []
+
+ finAckTransactionList = []
+ ackToDeviceList = []
+ deviceToGraphDiscList = []
+ endToEndDiscList = []
+
+ # LatNodeIter 2d arrays contain all iteration latency
+ # for each node of the current scale cluster size
+ # Switch connection measurements
+ # Set further acceptance criteria for measurements
+ # here if you would like to filter reporting results
+ for item in endToEndLatNodeIter[node]:
+ if item > 0.0:
+ endToEndList.append(item)
+
+ for item in tcpToFeatureLatNodeIter[node]:
+ if item > 0.0:
+ tcpToFeatureList.append(item)
+
+ for item in featureToRoleRequestLatNodeIter[node]:
+ if item > 0.0:
+ featureToRoleList.append(item)
+
+ for item in roleRequestToRoleReplyLatNodeIter[node]:
+ if item > 0.0:
+ roleToOfpList.append(item)
+
+ for item in roleReplyToDeviceLatNodeIter[node]:
+ if item >= 0.0:
+ ofpToDeviceList.append(item)
+
+ for item in featureToRoleRequestLatNodeIter[node]:
+ if item > 0.0:
+ featureToRoleList.append(item)
+
+ for item in deviceToGraphLatNodeIter[node]:
+ if item >= 0.0:
+ deviceToGraphList.append(item)
+
+ # Switch disconnect measurements
+ for item in endToEndDiscLatNodeIter[node]:
+ if item > 0.0:
+ endToEndDiscList.append(item)
+
+ for item in finAckTransactionLatNodeIter[node]:
+ if item > 0.0:
+ finAckTransactionList.append(item)
+
+ for item in ackToDeviceLatNodeIter[node]:
+ if item > 0.0:
+ ackToDeviceList.append(item)
+
+ for item in deviceToGraphDiscLatNodeIter[node]:
+ if item >= 0.0:
+ deviceToGraphDiscList.append(item)
+
+ endToEndAvg = round(numpy.mean(endToEndList), 2)
+ endToEndStdDev = round(numpy.std(endToEndList), 2)
+
+ tcpToFeatureAvg = round(numpy.mean(tcpToFeatureList), 2)
+ tcpToFeatureStdDev = round(numpy.std(tcpToFeatureList), 2)
+
+ featureToRoleAvg = round(numpy.mean(featureToRoleList), 2)
+ featureToRoleStdDev = round(numpy.std(featureToRoleList), 2)
+
+ roleToOfpAvg = round(numpy.mean(roleToOfpList), 2)
+ roleToOfpStdDev = round(numpy.std(roleToOfpList), 2)
+
+ ofpToDeviceAvg = round(numpy.mean(ofpToDeviceList), 2)
+ ofpToDeviceStdDev = round(numpy.std(ofpToDeviceList), 2)
+
+ deviceToGraphAvg = round(numpy.mean(deviceToGraphList), 2)
+ deviceToGraphStdDev = round(numpy.std(deviceToGraphList), 2)
+
+ endToEndDiscAvg = round(numpy.mean(endToEndDiscList), 2)
+ endToEndDiscStdDev = round(numpy.std(endToEndDiscList), 2)
+
+ finAckAvg = round(numpy.mean(finAckTransactionList), 2)
+ finAckStdDev = round(numpy.std(finAckTransactionList), 2)
+
+ ackToDeviceAvg = round(numpy.mean(ackToDeviceList), 2)
+ ackToDeviceStdDev = round(numpy.std(ackToDeviceList), 2)
+
+ deviceToGraphDiscAvg = round(numpy.mean(deviceToGraphDiscList), 2)
+ deviceToGraphDiscStdDev = round(numpy.std(deviceToGraphDiscList), 2)
+
+ main.log.report(' - Node ' + str(node + 1) + ' Summary - ')
+ main.log.report(' - Switch Connection Statistics - ')
+
+ main.log.report(' End-to-end Avg: ' + str(endToEndAvg) +
+ ' ms' + ' End-to-end Std dev: ' +
+ str(endToEndStdDev) + ' ms')
+
+ main.log.report(' Tcp-to-feature-reply Avg: ' +
+ str(tcpToFeatureAvg) + ' ms')
+ main.log.report(' Tcp-to-feature-reply Std dev: '+
+ str(tcpToFeatureStdDev) + ' ms')
+
+ main.log.report(' Feature-reply-to-role-request Avg: ' +
+ str(featureToRoleAvg) + ' ms')
+ main.log.report(' Feature-reply-to-role-request Std Dev: ' +
+ str(featureToRoleStdDev) + ' ms')
+
+ main.log.report(' Role-request-to-role-reply Avg: ' +
+ str(roleToOfpAvg) +' ms')
+ main.log.report(' Role-request-to-role-reply Std dev: ' +
+ str(roleToOfpStdDev) + ' ms')
+
+ main.log.report(' Role-reply-to-device Avg: ' +
+ str(ofpToDeviceAvg) +' ms')
+ main.log.report(' Role-reply-to-device Std dev: ' +
+ str(ofpToDeviceStdDev) + ' ms')
+
+ main.log.report(' Device-to-graph Avg: ' +
+ str(deviceToGraphAvg) + ' ms')
+ main.log.report( 'Device-to-graph Std dev: ' +
+ str(deviceToGraphStdDev) + ' ms')
+
+ main.log.report(' - Switch Disconnection Statistics - ')
+ main.log.report(' End-to-end switch disconnect Avg: ' +
+ str(endToEndDiscAvg) + ' ms')
+ main.log.report(' End-to-end switch disconnect Std dev: ' +
+ str(endToEndDiscStdDev) + ' ms')
+ main.log.report(' Fin/Ack-to-Ack Avg: ' + str(finAckAvg) + ' ms')
+ main.log.report(' Fin/Ack-to-Ack Std dev: ' +
+ str(finAckStdDev) + ' ms')
+
+ main.log.report(' Ack-to-device Avg: ' + str(ackToDeviceAvg) +
+ ' ms')
+ main.log.report(' Ack-to-device Std dev: ' + str(ackToDeviceStdDev) +
+ ' ms')
+
+ main.log.report(' Device-to-graph (disconnect) Avg: ' +
+ str(deviceToGraphDiscAvg) + ' ms')
+ main.log.report(' Device-to-graph (disconnect) Std dev: ' +
+ str(deviceToGraphDiscStdDev) + ' ms')
+
+ # For database schema, refer to Amazon web services
+ dbCmdList.append(
+ "INSERT INTO switch_latency_details VALUES('" +
+ timeToPost + "','switch_latency_results'," +
+ jenkinsBuildNumber + ',' + str(clusterCount) + ",'baremetal" +
+ str(node + 1) + "'," +
+ str(endToEndAvg) + ',' +
+ str(tcpToFeatureAvg) + ',' +
+ str(featureToRoleAvg) + ',' +
+ str(roleToOfpAvg) + ',' +
+ str(ofpToDeviceAvg) + ',' +
+ str(deviceToGraphAvg) + ',' +
+ str(endToEndDiscAvg) + ',' +
+ str(finAckAvg) + ',' +
+ str(ackToDeviceAvg) + ',' +
+ str(deviceToGraphDiscAvg) +
+ ');')
+
+ if debugMode == 'on':
+ main.ONOS1.cpLogsToDir('/opt/onos/log/karaf.log',
+ '/tmp/', copyFileName='sw_lat_karaf')
+ fResult = open(resultPath, 'a')
+ for line in dbCmdList:
+ if line:
+ fResult.write(line + '\n')
+ fResult.close()
+
+ assertion = main.TRUE
+
+ utilities.assert_equals(expect=main.TRUE, actual=assertion,
+ onpass='Switch latency test successful',
+ onfail='Switch latency test failed')
+
+ def CASE3(self, main):
+ """
+ Bring port up / down and measure latency.
+ Port enable / disable is simulated by ifconfig up / down
+
+ In ONOS-next, we must ensure that the port we are
+ manipulating is connected to another switch with a valid
+ connection. Otherwise, graph view will not be updated.
+ """
+ import time
+ import subprocess
+ import os
+ import requests
+ import json
+ import numpy
+ ONOS1Ip = main.params['CTRL']['ip1']
+ ONOS2Ip = main.params['CTRL']['ip2']
+ ONOS3Ip = main.params['CTRL']['ip3']
+ ONOSUser = main.params['CTRL']['user']
+ defaultSwPort = main.params['CTRL']['port1']
+ assertion = main.TRUE
+ numIter = main.params['TEST']['numIter']
+ iterIgnore = int(main.params['TEST']['iterIgnore'])
+
+ deviceTimestampKey = main.params['JSON']['deviceTimestamp']
+ graphTimestampKey = main.params['JSON']['graphTimestamp']
+ linkTimestampKey = main.params['JSON']['linkTimestamp']
+
+ tsharkPortUp = '/tmp/tshark_port_up.txt'
+ tsharkPortDown = '/tmp/tshark_port_down.txt'
+ tsharkPortStatus = main.params[ 'TSHARK' ][ 'ofpPortStatus' ]
+
+ debugMode = main.params['TEST']['debugMode']
+ postToDB = main.params['DB']['postToDB']
+ resultPath = main.params['DB']['portEventResultPath']
+ localTime = time.strftime('%x %X')
+ localTime = localTime.replace('/', '')
+ localTime = localTime.replace(' ', '_')
+ localTime = localTime.replace(':', '')
+
+ if debugMode == 'on':
+ main.ONOS1.tsharkPcap('eth0', '/tmp/port_lat_pcap_' + localTime)
+
+ upThresholdStr = main.params['TEST']['portUpThreshold']
+ downThresholdStr = main.params['TEST']['portDownThreshold']
+ upThresholdObj = upThresholdStr.split(',')
+ downThresholdObj = downThresholdStr.split(',')
+ upThresholdMin = int(upThresholdObj[0])
+ upThresholdMax = int(upThresholdObj[1])
+ downThresholdMin = int(downThresholdObj[0])
+ downThresholdMax = int(downThresholdObj[1])
+
+ interfaceConfig = 's1-eth1'
+ main.log.report('Port enable / disable latency')
+ main.log.report('Simulated by ifconfig up / down')
+ main.log.report('Total iterations of test: ' + str(numIter))
+ main.step('Assign switches s1 and s2 to controller 1')
+
+ main.Mininet1.assignSwController(sw='1',
+ ip1=ONOS1Ip, port1=defaultSwPort)
+ main.Mininet1.assignSwController(sw='2',
+ ip1=ONOS1Ip, port1=defaultSwPort)
+
+ time.sleep(15)
+
+ portUpEndToEndNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ portUpOfpToDevNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ portUpDevToLinkNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ portUpLinkToGraphNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+ portDownEndToEndNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ portDownOfpToDevNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ portDownDevToLinkNodeIter = numpy.zeros((clusterCount, int(numIter)))
+ portDownLinkToGraphNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+ for i in range(0, int(numIter)):
+ main.step('Starting wireshark capture for port status down')
+ main.ONOS1.tsharkGrep(tsharkPortStatus, tsharkPortDown)
+
+ time.sleep(5)
+
+ main.step('Disable port: ' + interfaceConfig)
+ main.Mininet1.handle.sendline('sh ifconfig ' +
+ interfaceConfig + ' down')
+ main.Mininet1.handle.expect('mininet>')
+
+ jsonStrPtDown = []
+ for node in range (0, clusterCount):
+ metricsPortDown = CLIs[node].topologyEventsMetrics()
+ jsonStrPtDown.append(metricsPortDown)
+
+ time.sleep(3)
+
+ main.ONOS1.tsharkStop()
+
+ os.system('scp ' + ONOSUser + '@' + ONOS1Ip + ':' +
+ tsharkPortDown + ' /tmp/')
+
+ fPortDown = open(tsharkPortDown, 'r')
+ fLine = fPortDown.readline()
+ objDown = fLine.split(' ')
+ if len(fLine) > 0:
+ timestampBeginPtDown = int(float(objDown[1]) * 1000)
+ # At times, tshark reports timestamp at the 3rd
+ # index of the array. If initial readings were
+ # unlike the epoch timestamp, then check the 3rd
+ # index and set that as a timestamp
+ if timestampBeginPtDown < 1400000000000:
+ timestampBeginPtDown = int(float(objDown[2]) * 1000)
+ # If there are any suspicion of invalid results
+ # check this reported value
+ main.log.info('Port down begin timestamp: ' +
+ str(timestampBeginPtDown))
+ else:
+ main.log.info('Tshark output file returned unexpected' +
+ ' results: ' + str(objDown))
+ timestampBeginPtDown = 0
+ fPortDown.close()
+
+ for node in range(0, clusterCount):
+ nodeNum = node+1
+ # metricsDown = CLIs[node].topologyEventsMetrics
+ #jsonStrPtDown[node] = metricsDown()
+ jsonObj = json.loads(jsonStrPtDown[node])
+
+ if jsonObj:
+ graphTimestamp = jsonObj[graphTimestampKey]['value']
+ deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+ linkTimestamp = jsonObj[linkTimestampKey]['value']
+ else:
+ main.log.error( "Unexpected json object" )
+ graphTimestamp = 0
+ deviceTimestamp = 0
+ linkTimestamp = 0
+
+ ptDownEndToEnd = int(graphTimestamp) - int(timestampBeginPtDown)
+ ptDownOfpToDevice = float(deviceTimestamp) - float(timestampBeginPtDown)
+ ptDownDeviceToLink = float(linkTimestamp) - float(deviceTimestamp)
+ ptDownLinkToGraph = float(graphTimestamp) - float(linkTimestamp)
+
+ if ptDownEndToEnd >= downThresholdMin and\
+ ptDownEndToEnd < downThresholdMax and i >= iterIgnore:
+ portDownEndToEndNodeIter[node][i] = ptDownEndToEnd
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down End-to-end: "+
+ str(ptDownEndToEnd) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down End-to-end ignored"+
+ " due to excess in threshold or premature iteration")
+
+ if ptDownOfpToDevice >= downThresholdMin and\
+ ptDownOfpToDevice < downThresholdMax and i >= iterIgnore:
+ portDownOfpToDevNodeIter[node][i] = ptDownOfpToDevice
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down Ofp-to-device: "+
+ str(ptDownOfpToDevice) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down Ofp-to-device ignored"+
+ " due to excess in threshold or premature iteration")
+
+ if ptDownDeviceToLink >= downThresholdMin and\
+ ptDownDeviceToLink < downThresholdMax and i >= iterIgnore:
+ portDownDevToLinkNodeIter[node][i] = ptDownDeviceToLink
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down Device-to-link "+
+ str(ptDownDeviceToLink) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down Device-to-link ignored"+
+ " due to excess in threshold or premature iteration")
+
+ if ptDownLinkToGraph >= downThresholdMin and\
+ ptDownLinkToGraph < downThresholdMax and i >= iterIgnore:
+ portDownLinkToGraphNodeIter[node][i] = ptDownLinkToGraph
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down Link-to-graph "+
+ str(ptDownLinkToGraph) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port down Link-to-graph ignored"+
+ " due to excess in threshold or premature iteration")
+
+ time.sleep(3)
+
+ main.step('Starting wireshark capture for port status up')
+ main.ONOS1.tsharkGrep(tsharkPortStatus, tsharkPortUp)
+
+ time.sleep(5)
+ main.step('Enable port and obtain timestamp')
+ main.Mininet1.handle.sendline('sh ifconfig ' + interfaceConfig + ' up')
+ main.Mininet1.handle.expect('mininet>')
+
+ jsonStrPtUp = []
+ for node in range (0, clusterCount):
+ metricsPortUp = CLIs[node].topologyEventsMetrics()
+ jsonStrPtUp.append(metricsPortUp)
+
+ time.sleep(5)
+ main.ONOS1.tsharkStop()
+
+ time.sleep(3)
+ os.system('scp ' + ONOSUser + '@' +
+ ONOS1Ip + ':' + tsharkPortUp + ' /tmp/')
+
+ fPortUp = open(tsharkPortUp, 'r')
+ fLine = fPortUp.readline()
+ objUp = fLine.split(' ')
+ if len(fLine) > 0:
+ timestampBeginPtUp = int(float(objUp[1]) * 1000)
+ if timestampBeginPtUp < 1400000000000:
+ timestampBeginPtUp = int(float(objUp[2]) * 1000)
+ main.log.info('Port up begin timestamp: ' + str(timestampBeginPtUp))
+ else:
+ main.log.info('Tshark output file returned unexpected' + ' results.')
+ timestampBeginPtUp = 0
+ fPortUp.close()
+
+ for node in range(0, clusterCount):
+ nodeNum = node+1
+ #metricsUp = CLIs[node].topologyEventsMetrics
+ #jsonStrUp = metricsUp()
+ jsonObj = json.loads(jsonStrPtUp[node])
+
+ if jsonObj:
+ graphTimestamp = jsonObj[graphTimestampKey]['value']
+ deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+ linkTimestamp = jsonObj[linkTimestampKey]['value']
+ else:
+ main.log.error( "Unexpected json object" )
+ graphTimestamp = 0
+ deviceTimestamp = 0
+ linkTimestamp = 0
+
+ ptUpEndToEnd = int(graphTimestamp) - int(timestampBeginPtUp)
+ ptUpOfpToDevice = float(deviceTimestamp) - float(timestampBeginPtUp)
+ ptUpDeviceToLink = float(linkTimestamp) - float(deviceTimestamp)
+ ptUpLinkToGraph = float(graphTimestamp) - float(linkTimestamp)
+
+ if ptUpEndToEnd >= upThresholdMin and\
+ ptUpEndToEnd < upThresholdMax and i > iterIgnore:
+ portUpEndToEndNodeIter[node][i] = ptUpEndToEnd
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up End-to-end: "+
+ str(ptUpEndToEnd) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up End-to-end ignored"+
+ " due to excess in threshold or premature iteration")
+
+ if ptUpOfpToDevice >= upThresholdMin and\
+ ptUpOfpToDevice < upThresholdMax and i > iterIgnore:
+ portUpOfpToDevNodeIter[node][i] = ptUpOfpToDevice
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up Ofp-to-device: "+
+ str(ptUpOfpToDevice) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up Ofp-to-device ignored"+
+ " due to excess in threshold or premature iteration")
+
+ if ptUpDeviceToLink >= upThresholdMin and\
+ ptUpDeviceToLink < upThresholdMax and i > iterIgnore:
+ portUpDevToLinkNodeIter[node][i] = ptUpDeviceToLink
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up Device-to-link: "+
+ str(ptUpDeviceToLink) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up Device-to-link ignored"+
+ " due to excess in threshold or premature iteration")
+
+ if ptUpLinkToGraph >= upThresholdMin and\
+ ptUpLinkToGraph < upThresholdMax and i > iterIgnore:
+ portUpLinkToGraphNodeIter[node][i] = ptUpLinkToGraph
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up Link-to-graph: "+
+ str(ptUpLinkToGraph) + " ms")
+ else:
+ main.log.info("ONOS "+str(nodeNum)+
+ " port up Link-to-graph ignored"+
+ " due to excess in threshold or premature iteration")
+
+ dbCmdList = []
+ for node in range(0, clusterCount):
+ portUpEndToEndList = []
+ portUpOfpToDevList = []
+ portUpDevToLinkList = []
+ portUpLinkToGraphList = []
+
+ portDownEndToEndList = []
+ portDownOfpToDevList = []
+ portDownDevToLinkList = []
+ portDownLinkToGraphList = []
+
+ portUpEndToEndAvg = 0
+ portUpOfpToDevAvg = 0
+ portUpDevToLinkAvg = 0
+ portUpLinkToGraphAvg = 0
+
+ portDownEndToEndAvg = 0
+ portDownOfpToDevAvg = 0
+ portDownDevToLinkAvg = 0
+ portDownLinkToGraphAvg = 0
+
+ # TODO: Update for more pythonic way to get list
+ # portUpDevList = [item for item in portUpDevNodeIter[node]
+ # if item > 0.0]
+ for item in portUpEndToEndNodeIter[node]:
+ if item > 0.0:
+ portUpEndToEndList.append(item)
+
+ for item in portUpOfpToDevNodeIter[node]:
+ if item > 0.0:
+ portUpOfpToDevList.append(item)
+
+ for item in portUpDevToLinkNodeIter[node]:
+ if item > 0.0:
+ portUpDevToLinkList.append(item)
+
+ for item in portUpLinkToGraphNodeIter[node]:
+ if item >= 0.0:
+ portUpLinkToGraphList.append(item)
+
+ for item in portDownEndToEndNodeIter[node]:
+ if item > 0.0:
+ portDownEndToEndList.append(item)
+
+ for item in portDownOfpToDevNodeIter[node]:
+ if item > 0.0:
+ portDownOfpToDevList.append(item)
+
+ for item in portDownDevToLinkNodeIter[node]:
+ if item >= 0.0:
+ portDownDevToLinkList.append(item)
+
+ for item in portDownLinkToGraphNodeIter[node]:
+ if item >= 0.0:
+ portDownLinkToGraphList.append(item)
+
+ portUpEndToEndAvg = round(numpy.mean(portUpEndToEndList), 2)
+ portUpOfpToDevAvg = round(numpy.mean(portUpOfpToDevList), 2)
+ portUpDevToLinkAvg = round(numpy.mean(portUpDevToLinkList), 2)
+ portUpLinkToGraphAvg = round(numpy.mean(portUpLinkToGraphList), 2)
+
+ portDownEndToEndAvg = round(numpy.mean(portDownEndToEndList), 2)
+ portDownOfpToDevAvg = round(numpy.mean(portDownOfpToDevList), 2)
+ portDownDevToLinkAvg = round(numpy.mean(portDownDevToLinkList), 2)
+ portDownLinkToGraphAvg = round(numpy.mean(portDownLinkToGraphList), 2)
+
+ portUpStdDev = round(numpy.std(portUpEndToEndList), 2)
+ portDownStdDev = round(numpy.std(portDownEndToEndList), 2)
+
+ main.log.report(' - Node ' + str(node + 1) + ' Summary - ')
+ main.log.report(' Port up End-to-end ' +
+ str(portUpEndToEndAvg) + ' ms')
+ main.log.report(' Port up Ofp-to-device ' +
+ str(portUpOfpToDevAvg) + ' ms')
+ main.log.report(' Port up Device-to-link ' +
+ str(portUpDevToLinkAvg) + ' ms')
+ main.log.report(' Port up Link-to-graph ' +
+ str(portUpLinkToGraphAvg) + ' ms')
+
+ main.log.report(' Port down End-to-end ' +
+ str(round(portDownEndToEndAvg, 2)) + ' ms')
+ main.log.report(' Port down Ofp-to-device ' +
+ str(portDownOfpToDevAvg) + ' ms')
+ main.log.report(' Port down Device-to-link ' +
+ str(portDownDevToLinkAvg) + ' ms')
+ main.log.report(' Port down Link-to-graph' +
+ str(portDownLinkToGraphAvg) + ' ms')
+
+ dbCmdList.append("INSERT INTO port_latency_details VALUES('" +
+ timeToPost + "','port_latency_results'," + jenkinsBuildNumber +
+ ',' + str(clusterCount) + ",'baremetal" + str(node + 1) +
+ "'," +
+ str(portUpEndToEndAvg) +',' +
+ str(portUpOfpToDevAvg) + ',' +
+ str(portUpDevToLinkAvg) + ',' +
+ str(portUpLinkToGraphAvg) + ',' +
+ str(portDownEndToEndAvg) + ',' +
+ str(portDownOfpToDevAvg) + ',' +
+ str(portDownDevToLinkAvg) + ',' +
+ str(portDownLinkToGraphAvg) +
+ ');')
+
+ fResult = open(resultPath, 'a')
+ for line in dbCmdList:
+ if line:
+ fResult.write(line + '\n')
+
+ fResult.close()
+
+ # Delete switches from controller to prepare for next
+ # set of tests
+ main.Mininet1.deleteSwController('s1')
+ main.Mininet1.deleteSwController('s2')
+ utilities.assert_equals(expect=main.TRUE,
+ actual=assertion,
+ onpass='Port discovery latency calculation successful',
+ onfail='Port discovery test failed')
+
+ def CASE4(self, main):
+ """
+ Increase number of nodes and initiate CLI
+
+ With the most recent implementation, we need a method to
+ ensure all ONOS nodes are killed, as well as redefine
+ the cell files to ensure all nodes that will be used
+ is in the cell file. Otherwise, exceptions will
+ prohibit test from running successfully.
+
+ 3/12/15
+
+ """
+ global clusterCount
+ import time
+ import os
+
+ clusterCount += 2
+
+ benchIp = main.params[ 'BENCH' ][ 'ip' ]
+ features = main.params[ 'ENV' ][ 'cellFeatures' ]
+ cellName = main.params[ 'ENV' ][ 'cellName' ]
+ mininetIp = main.params[ 'MN' ][ 'ip1' ]
+
+ main.log.report('Increasing cluster size to ' + str(clusterCount))
+
+ main.log.step( "Killing all ONOS processes before scale-out" )
+
+ for i in range( 1, 8 ):
+ main.ONOSbench.onosDie(
+ main.params[ 'CTRL' ][ 'ip'+str(i) ] )
+ main.ONOSbench.onosUninstall(
+ main.params[ 'CTRL' ][ 'ip'+str(i) ] )
+
+ main.step( "Creating scale-out cell file" )
+ cellIp = []
+ for node in range( 1, clusterCount + 1 ):
+ cellIp.append( main.params[ 'CTRL' ][ 'ip'+str(node) ] )
+
+ main.log.info( "Cell Ip list: " + str(cellIp) )
+ main.ONOSbench.createCellFile( benchIp, cellName, mininetIp,
+ str(features), *cellIp )
+
+ main.step( "Setting cell definition" )
+ main.ONOSbench.setCell(cellName)
+
+ main.step( "Packaging cell definition" )
+ main.ONOSbench.onosPackage()
+
+ for node in range( 1, clusterCount + 1 ):
+ main.ONOSbench.onosInstall(
+ node = main.params[ 'CTRL' ][ 'ip'+str(node) ])
+
+ time.sleep( 20 )
+
+ for node in range( 1, clusterCount + 1):
+ for i in range( 2 ):
+ isup = main.ONOSbench.isup(
+ main.params[ 'CTRL' ][ 'ip'+str(node) ] )
+ if isup:
+ main.log.info( "ONOS "+str(node) + " is up\n")
+ break
+ if not isup:
+ main.log.error( "ONOS "+str(node) + " did not start" )
+
+ for node in range( 0, clusterCount ):
+ CLIs[node].startOnosCli( cellIp[node] )
+
+ main.step( 'Setting configurations for metrics' )
+ configParam = 'maxEvents 1'
+ main.ONOSbench.onosCfgSet( nodeIpList[0], configName, configParam )
+ configParam = 'maxBatchMs 0'
+ main.ONOSbench.onosCfgSet( nodeIpList[0], configName, configParam )
+ configParam = 'maxIdleMs 0'
+ main.ONOSbench.onosCfgSet( nodeIpList[0], configName, configParam )
+
+ main.step( 'Activating essential applications' )
+ CLIs[0].activateApp( 'org.onosproject.metrics' )
+ CLIs[0].activateApp( 'org.onosproject.openflow' )
+
diff --git a/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.topo b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.topo
new file mode 100644
index 0000000..423d325
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.topo
@@ -0,0 +1,163 @@
+<TOPOLOGY>
+ <COMPONENT>
+
+ <ONOSbench>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOSbench>
+
+ <ONOS1cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>2</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1cli>
+
+ <ONOS2cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>3</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2cli>
+
+ <ONOS3cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>4</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3cli>
+
+ <ONOS4cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>5</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4cli>
+
+ <ONOS5cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>6</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5cli>
+
+ <ONOS6cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>7</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6cli>
+
+ <ONOS7cli>
+ <host>10.128.174.10</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosCliDriver</type>
+ <connect_order>8</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7cli>
+
+ <ONOS1>
+ <host>10.128.174.1</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>9</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS1>
+
+ <ONOS2>
+ <host>10.128.174.2</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>10</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS2>
+
+ <ONOS3>
+ <host>10.128.174.3</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>11</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS3>
+
+ <ONOS4>
+ <host>10.128.174.4</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>12</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS4>
+
+ <ONOS5>
+ <host>10.128.174.5</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>13</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS5>
+
+ <ONOS6>
+ <host>10.128.174.6</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>14</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS6>
+
+ <ONOS7>
+ <host>10.128.174.7</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>OnosDriver</type>
+ <connect_order>15</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </ONOS7>
+
+ <Mininet1>
+ <host>10.128.10.90</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>MininetCliDriver</type>
+ <connect_order>16</connect_order>
+ <COMPONENTS>
+ <arg1> --custom topo-perf-2sw.py </arg1>
+ <arg2> --topo mytopo</arg2>
+ <arg3> </arg3>
+ <controller> remote </controller>
+ </COMPONENTS>
+ </Mininet1>
+
+ <Mininet2>
+ <host>10.128.10.91</host>
+ <user>admin</user>
+ <password>onos_test</password>
+ <type>RemoteMininetDriver</type>
+ <connect_order>17</connect_order>
+ <COMPONENTS> </COMPONENTS>
+ </Mininet2>
+
+ </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/TopoPerfNextBM/__init__.py b/TestON/tests/TopoPerfNextBM/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/__init__.py
diff --git a/TestON/tests/TopoPerfNextBM/backup/TopoPerfNextBM.params b/TestON/tests/TopoPerfNextBM/backup/TopoPerfNextBM.params
new file mode 100644
index 0000000..d681433
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/backup/TopoPerfNextBM.params
@@ -0,0 +1,96 @@
+<PARAMS>
+ <testcases>1,2,3,4,2,3,4,2,3,4,2,3</testcases>
+
+ <ENV>
+ <cellName>topo_perf_test</cellName>
+ <cellFeatures>"org.onosproject.metrics,org.onosproject.openflow"</cellFeatures>
+ </ENV>
+
+ <GIT>
+ #autoPull 'on' or 'off'
+ <autoPull>off</autoPull>
+ <checkout>master</checkout>
+ </GIT>
+
+ <CTRL>
+ <user>sdn</user>
+ <ip1>10.128.174.1</ip1>
+ <port1>6633</port1>
+ <ip2>10.128.174.2</ip2>
+ <port2>6633</port2>
+ <ip3>10.128.174.3</ip3>
+ <port3>6633</port3>
+ <ip4>10.128.174.4</ip4>
+
+ <ip5>10.128.174.5</ip5>
+ <ip6>10.128.174.6</ip6>
+ <ip7>10.128.174.7</ip7>
+ </CTRL>
+
+ <MN>
+ <ip1>10.128.10.90</ip1>
+ <ip2>10.128.10.91</ip2>
+ </MN>
+
+ <BENCH>
+ <ip>10.128.174.10</ip>
+ </BENCH>
+
+ <TSHARK>
+ <ofpPortStatus>OF 1.3 146</ofpPortStatus>
+ <ofpRoleReply>OF 1.3 90 of_role_reply</ofpRoleReply>
+ <featureReply>OF 1.3 98 of_features_reply</featureReply>
+ <roleRequest>OF 1.3 90 of_role_request</roleRequest>
+ <tcpSynAck>TCP 74 6633</tcpSynAck>
+ <finAckSequence>FIN</finAckSequence>
+ </TSHARK>
+
+ <TEST>
+ #'on' or 'off' debug mode.
+ #If on, logging will be more verbose and
+ #tshark pcap will be enabled
+ #pcap file located at /tmp/'capture_name'
+ <debugMode>off</debugMode>
+ <onosLogFile>/opt/onos/log/karaf*</onosLogFile>
+ <mci>off</mci>
+
+ <topoConfigFile>
+ single_topo_event_accumulator.cfg
+ </topoConfigFile>
+ <topoConfigName>
+ org.onlab.onos.net.topology.impl.DefaultTopologyProvider.cfg
+ </topoConfigName>
+
+ #Number of times to iterate each case
+ <numIter>10</numIter>
+ <numSwitch>2</numSwitch>
+ #Number of iterations to ignore initially
+ <iterIgnore>2</iterIgnore>
+
+ <singleSwThreshold>0,1000</singleSwThreshold>
+ <portUpThreshold>0,1000</portUpThreshold>
+ <portDownThreshold>0,1000</portDownThreshold>
+ <linkUpThreshold>0,10000</linkUpThreshold>
+ <linkDownThreshold>0,10000</linkDownThreshold>
+ <swDisc100Threshold>0,10000</swDisc100Threshold>
+
+ <tabletFile>tablets_3node.json</tabletFile>
+ </TEST>
+
+ <DB>
+ <postToDB>on</postToDB>
+ <portEventResultPath>
+ /home/admin/ONLabTest/TestON/tests/TopoPerfNextBM/portEventResultDb.log
+ </portEventResultPath>
+ <switchEventResultPath>
+ /home/admin/ONLabTest/TestON/tests/TopoPerfNextBM/switchEventResultDb.log
+ </switchEventResultPath>
+ </DB>
+
+ <JSON>
+ <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
+ <hostTimestamp>topologyHostEventTimestamp</hostTimestamp>
+ <linkTimestamp>topologyLinkEventTimestamp</linkTimestamp>
+ <graphTimestamp>topologyGraphEventTimestamp</graphTimestamp>
+ </JSON>
+</PARAMS>
diff --git a/TestON/tests/TopoPerfNextBM/portEventResultDb.log b/TestON/tests/TopoPerfNextBM/portEventResultDb.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/portEventResultDb.log
diff --git a/TestON/tests/TopoPerfNextBM/switchEventResultDb.log b/TestON/tests/TopoPerfNextBM/switchEventResultDb.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/switchEventResultDb.log