blob: 2b114d1450df551946b421cda551fa8a3bc99c31 [file] [log] [blame]
Devin Lim61643762017-12-07 15:55:38 -08001#!groovy
2import groovy.time.*
Devin Lim81ab48b2018-02-09 14:24:57 -08003generalFuncs = evaluate readTrusted( 'TestON/JenkinsFile/GeneralFuncs.groovy' )
Jeremy Ronquillo14ecc172018-03-05 09:57:17 -08004
Devin Lim61643762017-12-07 15:55:38 -08005def initializeTrend( machine ){
6 table_name = "executed_test_tests"
7 result_name = "executed_test_results"
8 testMachine = "TestStation-" + machine + "s";
9 this.machine = machine
10 isSCPF = false
11 generalFuncs.initBasicVars();
12}
13def initialize( type, SCPFfuncs ){
14 init( type )
15 SCPFfunc = SCPFfuncs
16 isSCPF = true
17 machine = machineType[ type ]
18}
19def initialize( type ){
20 init( type )
21 SCPFfunc = null
22 table_name = "executed_test_tests"
23 result_name = "executed_test_results"
24 trend_generator_file = generalFuncs.rScriptLocation + "testCategoryTrend.R"
25 build_stats_generator_file = generalFuncs.rScriptLocation + "testCategoryBuildStats.R"
26 isSCPF = false
27}
28def init( type ){
29 machineType = [ "FUNC" : "VM",
30 "HA" : "VM",
31 "SR" : "VM",
32 "SCPF" : "BM",
33 "USECASE" : "BM" ]
34 testType = type;
35 testMachine = "TestStation-" + machineType[ type ] + "s";
36 generalFuncs.initBasicVars();
37}
38
39def printType(){
40 echo testType;
41 echo testMachine;
42}
43def getProperties(){
44 node( testMachine ){
45 return readProperties( file:'/var/jenkins/TestONOS.property' );
46 }
47}
48def getTestsToRun( testList ){
49 testList.tokenize("\n;, ")
50}
51def getCurrentTime(){
Devin Limd1fb8e92018-02-28 16:29:33 -080052 TimeZone.setDefault( TimeZone.getTimeZone('PST') )
Devin Lim61643762017-12-07 15:55:38 -080053 return new Date();
54}
55def getTotalTime( start, end ){
56 return TimeCategory.minus( end, start );
57}
58def printTestToRun( testList ){
59 for ( String test : testList ) {
60 println test;
61 }
62}
63def sendResultToSlack( start, isManualRun, branch ){
64 try{
65 if( isManualRun == "false" ){
66 end = getCurrentTime();
67 TimeDuration duration = TimeCategory.minus( end , start );
68 slackSend( color:"#5816EE",
69 message: testType + "-" + branch + " tests ended at: " + end.toString() + "\nTime took : " + duration )
70 }
71 }
72 catch( all ){}
73}
74def initAndRunTest( testName, testCategory ){
Devin Limf5bf9b52018-02-28 18:16:21 -080075 // after ifconfig : ''' + borrowCell( testName ) + '''
Devin Lim61643762017-12-07 15:55:38 -080076 return '''#!/bin/bash -l
77 set -i # interactive
78 set +e
79 shopt -s expand_aliases # expand alias in non-interactive mode
80 export PYTHONUNBUFFERED=1
81 ifconfig
Devin Lim61643762017-12-07 15:55:38 -080082 echo "ONOS Branch is: $ONOSBranch"
83 echo "TestON Branch is: $TestONBranch"
84 echo "Test date: "
85 date
86 cd ~
87 export PATH=$PATH:onos/tools/test/bin
88 timeout 240 stc shutdown | head -100
89 timeout 240 stc teardown | head -100
90 timeout 240 stc shutdown | head -100
91 cd ~/OnosSystemTest/TestON/bin
92 git log |head
93 ./cleanup.sh -f
94 ''' + "./cli.py run " + ( !isSCPF ? testName : testCategory[ testName ][ 'test' ] ) + '''
95 ./cleanup.sh -f
96 # cleanup config changes
97 cd ~/onos/tools/package/config
98 git clean -df'''
99}
100def copyLogs( testName ){
101 result = ""
102 if( testType == "SR" ){
103 result = '''
104 sudo rm /var/jenkins/workspace/SR-log-${WikiPrefix}/*
105 sudo cp *karaf.log.* /var/jenkins/workspace/SR-log-${WikiPrefix}/
106 sudo cp *Flows* /var/jenkins/workspace/SR-log-${WikiPrefix}/
107 sudo cp *Groups* /var/jenkins/workspace/SR-log-${WikiPrefix}/
108 '''
109 }
110 return result
111}
112def cleanAndCopyFiles( testName ){
113 return '''#!/bin/bash -i
114 set +e
115 echo "ONOS Branch is: ${ONOSBranch}"
116 echo "TestON Branch is: ${TestONBranch}"
117 echo "Job name is: "''' + testName + '''
118 echo "Workspace is: ${WORKSPACE}/"
119 echo "Wiki page to post is: ${WikiPrefix}-"
120 # remove any leftover files from previous tests
121 sudo rm ${WORKSPACE}/*Wiki.txt
122 sudo rm ${WORKSPACE}/*Summary.txt
123 sudo rm ${WORKSPACE}/*Result.txt
124 sudo rm ${WORKSPACE}/*.csv
125 #copy files to workspace
126 cd `ls -t ~/OnosSystemTest/TestON/logs/*/ | head -1 | sed 's/://'`
127 ''' + copyLogs( testName ) + '''
128 sudo cp *.txt ${WORKSPACE}/
129 sudo cp *.csv ${WORKSPACE}/
130 cd ${WORKSPACE}/
131 for i in *.csv
132 do mv "$i" "$WikiPrefix"-"$i"
133 done
134 ls -al
135 cd '''
136}
137def fetchLogs( testName ){
138 return '''#!/bin/bash
139 set +e
140 cd ~/OnosSystemTest/TestON/logs
141 echo "Job Name is: " + ''' + testName + '''
142 TestONlogDir=$(ls -t | grep ${TEST_NAME}_ |head -1)
143 echo "########################################################################################"
144 echo "##### copying ONOS logs from all nodes to TestON/logs directory: ${TestONlogDir}"
145 echo "########################################################################################"
146 cd $TestONlogDir
147 if [ $? -eq 1 ]
148 then
149 echo "Job name does not match any test suite name to move log!"
150 else
151 pwd
152 for i in $OC{1..7}; do onos-fetch-logs $i || echo log does not exist; done
153 fi
154 cd'''
155}
156def isPostingResult( manual, postresult ){
157 return manual == "false" || postresult == "true"
158}
159def postResult( prop, graphOnly ){
160 if( graphOnly || isPostingResult( prop[ "manualRun" ], prop[ "postResult" ] ) ){
161 def post = build job: "postjob-" + ( graphOnly ? machine : machineType[ testType ] ), propagate: false
162 }
163}
164def postLogs( testName, prefix ){
165 resultURL = ""
166 if( testType == "SR" ){
167 def post = build job: "SR-log-" + prefix, propagate: false
168 resultURL = post.getAbsoluteUrl()
169 }
170 return resultURL
171}
172def getSlackChannel(){
173 return "#" + ( testType == "SR" ? "sr-failures" : "jenkins-related" )
174}
175def analyzeResult( prop, workSpace, testName, otherTestName, resultURL, wikiLink, isSCPF ){
176 node( testMachine ){
177 resultContents = readFile workSpace + "/" + testName + "Result.txt"
178 resultContents = resultContents.split("\n")
179 if( resultContents[ 0 ] == "1" ){
180 print "All passed"
181 }else{
182 print "Failed"
183 if( prop[ "manualRun" ] == "false" ){
184 slackSend( channel:getSlackChannel(), color:"FF0000", message: "[" + prop[ "ONOSBranch" ] + "]"
185 + otherTestName + " : Failed!\n" + resultContents[ 1 ] + "\n"
186 + "[TestON log] : \n"
Devin Limd1fb8e92018-02-28 16:29:33 -0800187 + "https://jenkins.onosproject.org/blue/organizations/jenkins/${env.JOB_NAME}/detail/${env.JOB_NAME}/${env.BUILD_NUMBER}/pipeline"
Devin Lim61643762017-12-07 15:55:38 -0800188 + ( isSCPF ? "" : ( "\n[Result on Wiki] : \n" + "https://wiki.onosproject.org/display/ONOS/" + wikiLink.replaceAll( "\\s","+" ) ) )
189 + ( resultURL != "" ? ( "\n[Karaf log] : \n" + resultURL + "artifact/" ) : "" ),
190 teamDomain: 'onosproject' )
191 }
192 Failed
193 }
194 }
195}
Devin Lime89761a2018-03-16 17:52:57 -0700196def publishToConfluence( isManualRun, isPostResult, wikiLink, file ){
197 if( isPostingResult( isManualRun, isPostResult ) ){
Devin Lim61643762017-12-07 15:55:38 -0800198 publishConfluence siteName: 'wiki.onosproject.org', pageName: wikiLink, spaceName: 'ONOS',
Devin Lim1253ae82018-02-26 11:13:36 -0800199 attachArchivedArtifacts: true, buildIfUnstable: true,
Devin Lim61643762017-12-07 15:55:38 -0800200 editorList: [
201 confluenceWritePage( confluenceFile( file ) )
202 ]
203 }
204
205}
206def runTest( testName, toBeRun, prop, pureTestName, graphOnly, testCategory, graph_generator_file, graph_saved_directory ) {
207 return {
208 catchError{
209 stage( testName ) {
210 if ( toBeRun ){
211 workSpace = "/var/jenkins/workspace/" + testName
212 def fileContents = ""
213 node( testMachine ){
214 withEnv( [ 'ONOSBranch=' + prop[ "ONOSBranch" ],
215 'ONOSJVMHeap=' + prop[ "ONOSJVMHeap" ],
216 'TestONBranch=' + prop[ "TestONBranch" ],
217 'ONOSTag=' + prop[ "ONOSTag" ],
218 'WikiPrefix=' + prop[ "WikiPrefix" ],
219 'WORKSPACE=' + workSpace ] ){
220 if( ! graphOnly ){
221 sh initAndRunTest( testName, testCategory )
222 // For the Wiki page
223 sh cleanAndCopyFiles( pureTestName )
224 }
225 databaseAndGraph( prop, testName, graphOnly, graph_generator_file, graph_saved_directory )
226 if( ! graphOnly ){
227 sh fetchLogs( pureTestName )
228 if( !isSCPF )
Devin Lime89761a2018-03-16 17:52:57 -0700229 publishToConfluence( prop[ "manualRun" ], prop[ "postResult" ],
230 testCategory[ testName ][ 'wiki_link' ],
231 workSpace + "/" + testCategory[ testName ][ 'wiki_file' ] )
Devin Lim61643762017-12-07 15:55:38 -0800232 }
233 }
234
235
236 }
237 postResult( prop, graphOnly )
238 if( ! graphOnly ){
239 resultURL = postLogs( testName, prop[ "WikiPrefix" ] )
240 analyzeResult( prop, workSpace, pureTestName, testName, resultURL, isSCPF ? "" : testCategory[ testName ][ 'wiki_link' ], isSCPF )
241 }
242 }
243 }
244 }
245 }
246}
247def borrowCell( testName ){
248 result = ""
249 if( testType == "SR" ){
250 result = '''
251 cd
252 source ~/borrow.cell
253 '''
254 }
255 return result
256}
257def databaseAndGraph( prop, testName, graphOnly, graph_generator_file, graph_saved_directory ){
258 if( graphOnly || isPostingResult( prop[ "manualRun" ], prop[ "postResult" ] ) ){
259 // Post Results
260 withCredentials( [
261 string( credentialsId: 'db_pass', variable: 'pass' ),
262 string( credentialsId: 'db_user', variable: 'user' ),
263 string( credentialsId: 'db_host', variable: 'host' ),
264 string( credentialsId: 'db_port', variable: 'port' ) ] ) {
265 def database_command = generalFuncs.database_command_create( pass, host, port, user ) + ( !isSCPF ? sqlCommand( testName ) : SCPFfunc.sqlCommand( testName ) )
266 sh '''#!/bin/bash
267 export DATE=\$(date +%F_%T)
268 cd ~
269 pwd ''' + ( graphOnly ? "" : ( !isSCPF ? databasePart( prop[ "WikiPrefix" ], testName, database_command ) :
270 SCPFfunc.databasePart( testName, database_command ) ) ) + '''
271 ''' + ( !isSCPF ? graphGenerating( host, port, user, pass, testName, prop, graph_saved_directory, graph_generator_file ) : SCPFfunc.getGraphGeneratingCommand( host, port, user, pass, testName, prop ) )
272 }
273 }
274}
275def generateCategoryStatsGraph( manualRun, postresult, stat_file, pie_file, type, branch, testListPart, save_path, pieTestListPart ){
276
277 if( isPostingResult( manualRun, postresult ) ){
278 node( testMachine ){
279
280 withCredentials( [
281 string( credentialsId: 'db_pass', variable: 'pass' ),
282 string( credentialsId: 'db_user', variable: 'user' ),
283 string( credentialsId: 'db_host', variable: 'host' ),
284 string( credentialsId: 'db_port', variable: 'port' ) ] ) {
285 sh '''#!/bin/bash
286 ''' + generalFuncs.basicGraphPart( generalFuncs.rScriptLocation + stat_file, host, port, user, pass, type, branch ) + " \"" + testListPart + "\" latest " + save_path + '''
287 ''' + getOverallPieGraph( generalFuncs.rScriptLocation + pie_file, host, port, user, pass, branch, type, pieTestListPart, 'y', save_path ) + '''
288 ''' + getOverallPieGraph( generalFuncs.rScriptLocation + pie_file, host, port, user, pass, branch, type, pieTestListPart, 'n', save_path )
289 }
290 }
291 postResult( [], true )
292 }
293}
294def makeTestList( list, commaNeeded ){
295 return generalFuncs.getTestList( list ) + ( commaNeeded ? "," : "" )
296}
297def createStatsList( testCategory, list, semiNeeded ){
298 return testCategory + "-" + generalFuncs.getTestList( list ) + ( semiNeeded ? ";" : "" )
299}
300def generateOverallGraph( prop, testCategory, graph_saved_directory ){
301
302 if( isPostingResult( prop[ "manualRun" ], prop[ "postResult" ] ) ){
303 node( testMachine ){
304
305 withCredentials( [
306 string( credentialsId: 'db_pass', variable: 'pass' ),
307 string( credentialsId: 'db_user', variable: 'user' ),
308 string( credentialsId: 'db_host', variable: 'host' ),
309 string( credentialsId: 'db_port', variable: 'port' ) ] ) {
310 testList = generalFuncs.getTestList( testCategory )
311 sh '''#!/bin/bash
312 ''' + generalFuncs.basicGraphPart( trend_generator_file, host, port, user, pass, testType, prop[ "ONOSBranch" ] ) + " " + testList + " 20 " + graph_saved_directory
313 }
314 }
315 postResult( prop, false )
316 }
317}
318def getOverallPieGraph( file, host, port, user, pass, branch, type, testList, yOrN, path ){
319 return generalFuncs.basicGraphPart( file, host, port, user, pass, type, branch ) + " \"" + testList + "\" latest " + yOrN + " " + path
320}
321def sqlCommand( testName ){
322 return "\"INSERT INTO " + table_name + " VALUES('\$DATE','" + result_name + "','" + testName + "',\$BUILD_NUMBER, '\$ONOSBranch', \$line);\" "
323}
324def graphGenerating( host, port, user, pass, testName, prop, graph_saved_directory, graph_generator_file ){
325 return generalFuncs.basicGraphPart( graph_generator_file, host, port, user, pass, testName, prop[ "ONOSBranch" ] ) + " 20 " + graph_saved_directory
326}
327def databasePart( wikiPrefix, testName, database_command ){
328 return '''
329 sed 1d ''' + workSpace + "/" + wikiPrefix + "-" + testName + '''.csv | while read line
330 do
331 echo \$line
332 echo ''' + database_command + '''
333 done '''
334}
Jeremy Ronquillo14ecc172018-03-05 09:57:17 -0800335def generateStatGraph( onos_branch, AllTheTests, stat_graph_generator_file, pie_graph_generator_file, graph_saved_directory ){
336 testListPart = createStatsList( "FUNC", AllTheTests[ "FUNC" ], true ) +
337 createStatsList( "HA", AllTheTests[ "HA" ], true ) +
338 createStatsList( "USECASE", AllTheTests[ "USECASE" ], false )
339 pieTestList = makeTestList( AllTheTests[ "FUNC" ], true ) +
340 makeTestList( AllTheTests[ "HA" ], true ) +
341 makeTestList( AllTheTests[ "USECASE" ], false )
342 generateCategoryStatsGraph( "false", "true", stat_graph_generator_file, pie_graph_generator_file, "ALL", onos_branch, testListPart, graph_saved_directory, pieTestList )
343}
Jeremy Ronquillof78a6ca2018-03-12 09:20:57 -0700344def branchWithPrefix( branch ){
345 return ( ( branch != "master" ) ? "onos-" : "" ) + branch
346}
Devin Lim1253ae82018-02-26 11:13:36 -0800347return this;