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