Merge "[ONOS-7937] Automatically check switchLat results"
diff --git a/TestON/JenkinsFile/dependencies/JenkinsCommonFuncs.groovy b/TestON/JenkinsFile/dependencies/JenkinsCommonFuncs.groovy
index d309f44..43e883c 100644
--- a/TestON/JenkinsFile/dependencies/JenkinsCommonFuncs.groovy
+++ b/TestON/JenkinsFile/dependencies/JenkinsCommonFuncs.groovy
@@ -163,9 +163,12 @@
if ( isManualRun == "false" ){
end = getCurrentTime()
TimeDuration duration = TimeCategory.minus( end, start )
+ // FIXME: for now we disable notifications of normal test results
+ /*
slackSend( color: "#5816EE",
message: testType + "-" + branch + " tests ended at: " + end.toString() +
"\nTime took : " + duration )
+ */
}
}
catch ( all ){
@@ -309,11 +312,13 @@
// get name of the slack channel.
// if the test is SR, it will return sr-failures
- return "#" + ( testType == "SR" ? "sr-failures" : "jenkins-related" )
+ // FIXME: For now we move all notifications to #jenkins-related
+ // return "#" + ( testType == "SR" ? "sr-failures" : "jenkins-related" )
+ return "#jenkins-related"
}
def analyzeResult( prop, workSpace, pureTestName, testName, resultURL, wikiLink, isSCPF ){
- // analyzing the result of the test and send to slack if the test was failed.
+ // analyzing the result of the test and send to slack if any abnormal result is logged.
// prop : property dictionary
// workSpace : workSpace where the result file is saved
// pureTestName : TestON name of the test
@@ -323,18 +328,15 @@
// isSCPF : Check if it is SCPF. If so, it won't post the wiki link.
node( testMachine ) {
- def resultContents = readFile( workSpace + "/" + pureTestName + "Result.txt" )
- resultContents = resultContents.split( "\n" )
- if ( resultContents[ 0 ] == "1" ){
- print "All passed"
- }
- else {
- print "Failed"
+ def alarmFile = workSpace + "/" + pureTestName + "Alarm.txt"
+ if ( fileExists( alarmFile ) ) {
+ print "Abnormal test result logged"
+ def alarmContents = readFile( alarmFile )
if ( prop[ "manualRun" ] == "false" ){
slackSend( channel: getSlackChannel(),
color: "FF0000",
- message: "[" + prop[ "ONOSBranch" ] + "]" + testName + " : Failed!\n" +
- resultContents[ 1 ] + "\n" +
+ message: "[" + prop[ "ONOSBranch" ] + "]" + testName + " : triggered alarms:\n" +
+ alarmContents + "\n" +
"[TestON log] : \n" +
"https://jenkins.onosproject.org/blue/organizations/jenkins/${ env.JOB_NAME }/detail/${ env.JOB_NAME }/${ env.BUILD_NUMBER }/pipeline" +
( isSCPF ? "" : ( "\n[Result on Wiki] : \n" +
@@ -346,6 +348,9 @@
}
Failed
}
+ else {
+ print "Test results are normal"
+ }
}
}
diff --git a/TestON/core/logger.py b/TestON/core/logger.py
index 551bacc..0fdc49a 100644
--- a/TestON/core/logger.py
+++ b/TestON/core/logger.py
@@ -124,6 +124,7 @@
main.SummaryFileName = main.logdir + "/" + main.TEST + "Summary.txt"
main.JenkinsCSV = main.logdir + "/" + main.TEST + ".csv"
main.resultFile = main.logdir + "/" + main.TEST + "Result.txt"
+ main.alarmFileName = main.logdir + "/" + main.TEST + "Alarm.txt"
main.TOTAL_TC_SUCCESS = 0
@@ -214,6 +215,17 @@
main.log.step = step
+ def alarm( msg ):
+ '''
+ Format of the alarm type log defined here.
+ '''
+ main.log._log( 6, msg, "OpenFlowAutoMattion", "OFAutoMation" )
+ main.alarmFile = open( main.alarmFileName, "a+" )
+ main.alarmFile.write( msg + "\n" )
+ main.alarmFile.close()
+
+ main.log.alarm = alarm
+
main.LogFileHandler = logging.FileHandler( main.LogFileName )
self._printHeader( main )
diff --git a/TestON/core/teston.py b/TestON/core/teston.py
index 978c206..1edc721 100644
--- a/TestON/core/teston.py
+++ b/TestON/core/teston.py
@@ -803,6 +803,7 @@
self.testCaseResult[ str( self.CurrentTestCaseNumber ) ] = self.FALSE
self.organizeResult( self.CurrentTestCaseNumber, self.FALSE )
self.logger.updateCaseResults( self )
+ self.log.alarm( "Test exited unexpectedly" )
self.cleanup()
self.exit()
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
index 8680b5c..699baa9 100644
--- a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
@@ -1,13 +1,13 @@
<PARAMS>
- <testcases>0,1,2,1,2,1,2,1,2</testcases>
+ <testcases>0,1,2,1,2,1,2</testcases>
<GRAPH>
<nodeCluster>BM</nodeCluster>
<builds>20</builds>
</GRAPH>
- <SCALE>1,3,5,7</SCALE>
- <max>7</max>
+ <SCALE>1,3,5</SCALE>
+ <max>5</max>
<ENV>
<cellName>topo_perf_test</cellName>
@@ -61,9 +61,11 @@
<ACK>openflow\ \[ACK\]</ACK>
</down>
</TSHARK>
+
<CFG>
<defaultTopo>org.onosproject.net.topology.impl.DefaultTopologyProvider</defaultTopo>
</CFG>
+
<TEST>
#'on' or 'off' debug mode.
#If on, logging will be more verbose and
@@ -117,7 +119,7 @@
<singleSwThreshold>0,1000</singleSwThreshold>
<tabletFile>tablets_3node.json</tabletFile>
- </TEST>
+ </TEST>
<SLEEP>
<startup>5</startup>
@@ -136,4 +138,11 @@
<linkTimestamp>topologyLinkEventTimestamp</linkTimestamp>
<graphTimestamp>topologyGraphEventTimestamp</graphTimestamp>
</JSON>
+
+ <ALARM>
+ <maxSwitchUpAve>60,60,68</maxSwitchUpAve>
+ <maxSwitchUpStd>10,10,10</maxSwitchUpStd>
+ <maxSwitchDownAve>5,5,8</maxSwitchDownAve>
+ <maxSwitchDownStd>2,2,2</maxSwitchDownStd>
+ </ALARM>
</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
index 8048d4f..f27b4f2 100644
--- a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
@@ -230,51 +230,40 @@
main.log.report( "=====node{} Summary:=====".format( str( i ) ) )
main.log.report( "=============Switch up=======" )
-
- main.log.report(
- "End to End average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'E_E' ] ) ) )
- main.log.report(
- "End to End Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'E_E' ] ) ) )
-
- main.log.report(
- "TCP to Feature average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'T_F' ] ) ) )
- main.log.report(
- "TCP to Feature Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'T_F' ] ) ) )
-
- main.log.report(
- "Feature to Device average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'F_D' ] ) ) )
- main.log.report(
- "Feature to Device Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'F_D' ] ) ) )
-
- main.log.report(
- "Device to Graph average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'D_G' ] ) ) )
- main.log.report(
- "Device to Graph Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'D_G' ] ) ) )
+ main.log.report( "End to End average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'E_E' ] ) ) )
+ main.log.report( "End to End Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'E_E' ] ) ) )
+ main.log.report( "TCP to Feature average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'T_F' ] ) ) )
+ main.log.report( "TCP to Feature Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'T_F' ] ) ) )
+ main.log.report( "Feature to Device average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'F_D' ] ) ) )
+ main.log.report( "Feature to Device Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'F_D' ] ) ) )
+ main.log.report( "Device to Graph average: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Ave' ][ 'D_G' ] ) ) )
+ main.log.report( "Device to Graph Std: {}".format( str( resultDict[ "up" ][ 'node' + str( i ) ][ 'Std' ][ 'D_G' ] ) ) )
main.log.report( "=============Switch down=======" )
+ main.log.report( "End to End average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'E_E' ] ) ) )
+ main.log.report( "End to End Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'E_E' ] ) ) )
+ main.log.report( "Fin_ACK to ACK average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'FA_A' ] ) ) )
+ main.log.report( "Fin_ACK to ACK Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'FA_A' ] ) ) )
+ main.log.report( "ACK to Device average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'A_D' ] ) ) )
+ main.log.report( "ACK to Device Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'A_D' ] ) ) )
+ main.log.report( "Device to Graph average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'D_G' ] ) ) )
+ main.log.report( "Device to Graph Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'D_G' ] ) ) )
- main.log.report(
- "End to End average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'E_E' ] ) ) )
- main.log.report(
- "End to End Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'E_E' ] ) ) )
-
- main.log.report(
- "Fin_ACK to ACK average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'FA_A' ] ) ) )
- main.log.report(
- "Fin_ACK to ACK Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'FA_A' ] ) ) )
-
- main.log.report(
- "ACK to Device average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'A_D' ] ) ) )
- main.log.report(
- "ACK to Device Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'A_D' ] ) ) )
-
- main.log.report(
- "Device to Graph average: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Ave' ][ 'D_G' ] ) ) )
- main.log.report(
- "Device to Graph Std: {}".format( str( resultDict[ "down" ][ 'node' + str( i ) ][ 'Std' ][ 'D_G' ] ) ) )
+ # Check if any result is abnormal
+ result = resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Ave' ][ 'E_E' ]
+ if result > float( main.params[ 'ALARM' ][ 'maxSwitchUpAve' ].split( ',' )[ main.cycle - 1 ] ):
+ main.log.alarm( "Average of switch up latency is {} with cluster size {}".format( result, main.Cluster.numCtrls ) )
+ result = resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Std' ][ 'E_E' ]
+ if result > float( main.params[ 'ALARM' ][ 'maxSwitchUpStd' ].split( ',' )[ main.cycle - 1 ] ):
+ main.log.alarm( "Std of switch up latency is {} with cluster size {}".format( result, main.Cluster.numCtrls ) )
+ result = resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Ave' ][ 'E_E' ]
+ if result > float( main.params[ 'ALARM' ][ 'maxSwitchDownAve' ].split( ',' )[ main.cycle - 1 ] ):
+ main.log.alarm( "Average of switch down latency is {} with cluster size {}".format( result, main.Cluster.numCtrls ) )
+ result = resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Std' ][ 'E_E' ]
+ if result > float( main.params[ 'ALARM' ][ 'maxSwitchDownStd' ].split( ',' )[ main.cycle - 1 ] ):
+ main.log.alarm( "Std of switch down latency is {} with cluster size {}".format( result, main.Cluster.numCtrls ) )
with open( main.dbFileName, "a" ) as dbFile:
- # TODO: Save STD to Database
# Scale number
temp = str( main.Cluster.numCtrls )
temp += ",'baremetal1'"