source: Jenkinsfile@ 952ee7a

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 952ee7a was 952ee7a, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

more testing

  • Property mode set to 100644
File size: 15.5 KB
RevLine 
[a63ad80]1#!groovy
2
[7a230fd]3import groovy.transform.Field
4
[8ecb590]5// For skipping stages
6import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
7
[29f4fe62]8//===========================================================================================================
[9beae23]9// Main loop of the compilation
[29f4fe62]10//===========================================================================================================
[56a9ce6]11
[4f9e706]12
[aa8e8301]13// Globals
[952ee7a]14BuildDir = null
15SrcDir = null
[aa8e8301]16Settings = null
17StageName = ''
[5b8413b4]18
[4f9e706]19currentBuild.result = "SUCCESS"
20
[aa8e8301]21// Local variables
22def err = null
23def log_needed = false
[0ef06b6]24
[952ee7a]25echo "Testing"
26
[aa8e8301]27try {
28 //Wrap build to add timestamp to command line
29 wrap([$class: 'TimestamperBuildWrapper']) {
[23a14d86]30
[952ee7a]31 echo "Testing 2"
[aa8e8301]32 Settings = prepare_build()
[7aebc62]33
[aa8e8301]34 node(Settings.Architecture.node) {
35 BuildDir = pwd tmp: true
36 SrcDir = pwd tmp: false
[0dc3ac3]37
[aa8e8301]38 clean()
[fde808df]39
[aa8e8301]40 checkout()
[95fdb0a]41
[aa8e8301]42 build()
[95fdb0a]43
[aa8e8301]44 test()
[95fdb0a]45
[aa8e8301]46 benchmark()
[7359098]47
[aa8e8301]48 build_doc()
[9beae23]49
[aa8e8301]50 publish()
[9beae23]51 }
[738cf8f]52 }
[aa8e8301]53}
[738cf8f]54
[aa8e8301]55//If an exception is caught we need to change the status and remember to
56//attach the build log to the email
57catch (Exception caughtError) {
58 //rethrow error later
59 err = caughtError
[738cf8f]60
[aa8e8301]61 echo err.toString()
[e966ec0]62
[aa8e8301]63 //An error has occured, the build log is relevent
64 log_needed = true
[9beae23]65
[aa8e8301]66 //Store the result of the build log
67 currentBuild.result = "${StageName} FAILURE".trim()
68}
[738cf8f]69
[aa8e8301]70finally {
71 //Send email with final results if this is not a full build
72 email(log_needed)
[9beae23]73
[aa8e8301]74 echo 'Build Completed'
[734891d]75
[aa8e8301]76 /* Must re-throw exception to propagate error */
77 if (err) {
78 throw err
[738cf8f]79 }
80}
[aa8e8301]81
[29f4fe62]82//===========================================================================================================
[9beae23]83// Main compilation routines
[29f4fe62]84//===========================================================================================================
[0dc3ac3]85def clean() {
[6c55a3d]86 build_stage('Cleanup', true) {
[0dc3ac3]87 // clean the build by wipping the build directory
[5b8413b4]88 dir(BuildDir) {
[d4cd491]89 deleteDir()
[ece8a80]90 }
[620dd2b]91 }
[95fdb0a]92}
[29f4fe62]93
[0dc3ac3]94//Compilation script is done here but environnement set-up and error handling is done in main loop
95def checkout() {
[6c55a3d]96 build_stage('Checkout', true) {
[0dc3ac3]97 //checkout the source code and clean the repo
[a336d46]98 final scmVars = checkout scm
99 Settings.GitNewRef = scmVars.GIT_COMMIT
100 Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
[d3a4564a]101
[a336d46]102 echo GitLogMessage()
[0dc3ac3]103 }
104}
105
[95fdb0a]106def build() {
[e507c11]107 debug = true
108 release = Settings.RunAllTests || Settings.RunBenchmark
109 build_stage('Build : configure', true) {
[50f2cfc]110 // Build outside of the src tree to ease cleaning
[5b8413b4]111 dir (BuildDir) {
[50f2cfc]112 //Configure the conpilation (Output is not relevant)
113 //Use the current directory as the installation target so nothing escapes the sandbox
114 //Also specify the compiler by hand
[3fc5f010]115 targets=""
[d4510ea]116 if( Settings.RunAllTests || Settings.RunBenchmark ) {
[6bde81d]117 targets="--with-target-hosts='host:debug,host:nodebug'"
[3fc5f010]118 } else {
[6bde81d]119 targets="--with-target-hosts='host:debug'"
[3fc5f010]120 }
121
[93fe3154]122 sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
[f253e4a]123
124 // Configure libcfa
[e70e54e]125 sh 'make -j 8 --no-print-directory configure-libcfa'
[e507c11]126 }
127 }
128
129 build_stage('Build : cfa-cpp', true) {
130 // Build outside of the src tree to ease cleaning
131 dir (BuildDir) {
132 // Build driver
133 sh 'make -j 8 --no-print-directory -C driver'
134
135 // Build translator
136 sh 'make -j 8 --no-print-directory -C src'
137 }
138 }
[1752d0e]139
[e507c11]140 build_stage('Build : libcfa(debug)', debug) {
141 // Build outside of the src tree to ease cleaning
142 dir (BuildDir) {
143 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-debug"
144 }
145 }
146
147 build_stage('Build : libcfa(nodebug)', release) {
148 // Build outside of the src tree to ease cleaning
149 dir (BuildDir) {
150 sh "make -j 8 --no-print-directory -C libcfa/${Settings.Architecture.name}-nodebug"
[50f2cfc]151 }
[620dd2b]152 }
[95fdb0a]153}
[24eecab]154
[95fdb0a]155def test() {
[4c1b9ea8]156 try {
157 build_stage('Test: short', !Settings.RunAllTests) {
158 dir (BuildDir) {
[3e93c00]159 //Run the tests from the tests directory
[4c51aca]160 sh "make --no-print-directory -C tests archiveerrors=${BuildDir}/tests/crashes/short"
[3e93c00]161 }
[4c1b9ea8]162 }
163
164 build_stage('Test: full', Settings.RunAllTests) {
165 dir (BuildDir) {
166 //Run the tests from the tests directory
[4c51aca]167 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
168 sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
[143e6f3]169 }
[9beae23]170 }
[620dd2b]171 }
[4c1b9ea8]172 catch (Exception err) {
173 echo "Archiving core dumps"
[c95fdc9]174 dir (BuildDir) {
175 archiveArtifacts artifacts: "tests/crashes/**/*", fingerprint: true
176 }
[4c1b9ea8]177 throw err
178 }
[95fdb0a]179}
180
181def benchmark() {
[6c55a3d]182 build_stage('Benchmark', Settings.RunBenchmark) {
[5b8413b4]183 dir (BuildDir) {
[0dc3ac3]184 //Append bench results
[c6f1f3e]185 sh "make --no-print-directory -C benchmark jenkins arch=${Settings.Architecture.name}"
[0dc3ac3]186 }
[620dd2b]187 }
[9beae23]188}
[efd60d67]189
[95fdb0a]190def build_doc() {
[6c55a3d]191 build_stage('Documentation', Settings.BuildDocumentation) {
[9beae23]192 dir ('doc/user') {
193 make_doc()
194 }
195
196 dir ('doc/refrat') {
197 make_doc()
198 }
[620dd2b]199 }
[9beae23]200}
201
[95fdb0a]202def publish() {
[6c55a3d]203 build_stage('Publish', true) {
[95fdb0a]204
[1b3eef8]205 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
[95fdb0a]206
[3221a2b]207 def groupCompile = new PlotGroup('Compilation', 'duration (s) - lower is better', true)
208 def groupConcurrency = new PlotGroup('Concurrency', 'duration (n) - lower is better', false)
[a2a0065]209
[3898392]210 //Then publish the results
[3221a2b]211 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile' , groupCompile , false, 'Compilation')
212 do_plot(Settings.RunBenchmark && Settings.Publish, 'compile.diff' , groupCompile , true , 'Compilation (relative)')
213 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch' , groupConcurrency, false, 'Context Switching')
214 do_plot(Settings.RunBenchmark && Settings.Publish, 'ctxswitch.diff', groupConcurrency, true , 'Context Switching (relative)')
215 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex' , groupConcurrency, false, 'Mutual Exclusion')
216 do_plot(Settings.RunBenchmark && Settings.Publish, 'mutex.diff' , groupConcurrency, true , 'Mutual Exclusion (relative)')
217 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal' , groupConcurrency, false, 'Internal and External Scheduling')
218 do_plot(Settings.RunBenchmark && Settings.Publish, 'signal.diff' , groupConcurrency, true , 'Internal and External Scheduling (relative)')
[620dd2b]219 }
[95fdb0a]220}
221
[29f4fe62]222//===========================================================================================================
223//Routine responsible of sending the email notification once the build is completed
224//===========================================================================================================
[6b6c26e]225@NonCPS
226def SplitLines(String text) {
227 def list = []
228
229 text.eachLine {
230 list += it
231 }
232
233 return list
234}
235
[a336d46]236def GitLogMessage() {
237 if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
[e8a22a7]238
[fce01e7]239 def oldRef = Settings.GitOldRef
240 def newRef = Settings.GitNewRef
[6badd87]241
[fdb6ac6]242 def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim()
[6b6c26e]243 def revList = SplitLines( revText )
[6e31c43]244
[fdb6ac6]245 def gitUpdate = ""
246 revList.each { rev ->
[249091f]247 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
[fce01e7]248 gitUpdate = gitUpdate + " via ${rev} (${type})"
249 }
250
251 def rev = oldRef
[249091f]252 def type = sh(returnStdout: true, script: "git cat-file -t ${rev}").trim()
253 gitUpdate = gitUpdate + " from ${rev} (${type})"
[fce01e7]254
[249091f]255 def gitLog = sh(returnStdout: true, script: "git rev-list --format=short ${oldRef}...${newRef}").trim()
[fce01e7]256
[249091f]257 def gitDiff = sh(returnStdout: true, script: "git diff --stat --color ${newRef} ${oldRef}").trim()
[fce01e7]258 gitDiff = gitDiff.replace('[32m', '<span style="color: #00AA00;">')
259 gitDiff = gitDiff.replace('[31m', '<span style="color: #AA0000;">')
260 gitDiff = gitDiff.replace('[m', '</span>')
[7a927ed0]261
[a336d46]262 return """
[13c98a4]263<pre>
[848fb00]264The branch ${env.BRANCH_NAME} has been updated.
[7a927ed0]265${gitUpdate}
[13c98a4]266</pre>
267
268<p>Check console output at ${env.BUILD_URL} to view the results.</p>
[7b1a604]269
[13c98a4]270<p>- Status --------------------------------------------------------------</p>
[7b1a604]271
[13c98a4]272<p>BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}</p>
[7b1a604]273
[13c98a4]274<p>- Log -----------------------------------------------------------------</p>
[e8a22a7]275
[13c98a4]276<pre>
[7a927ed0]277${gitLog}
[13c98a4]278</pre>
279
280<p>-----------------------------------------------------------------------</p>
281<pre>
[7b1a604]282Summary of changes:
[7a927ed0]283${gitDiff}
[13c98a4]284</pre>
[7b1a604]285"""
[a336d46]286}
287
288//Standard build email notification
[13c98a4]289def email(boolean log) {
[a336d46]290 //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
291 //Configurations for email format
292 echo 'Notifying users of result'
293
294 def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
295 def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
[13c98a4]296 def email_body = """<p>This is an automated email from the Jenkins build machine. It was
[a336d46]297generated because of a git hooks/post-receive script following
[986e260]298a ref change which was pushed to the C\u2200 repository.</p>
[a336d46]299""" + GitLogMessage()
[e8a22a7]300
[13c98a4]301 def email_to = !Settings.IsSandbox ? "cforall@lists.uwaterloo.ca" : "tdelisle@uwaterloo.ca"
[e8a22a7]302
[13c98a4]303 if( Settings && !Settings.Silent ) {
[094a42c]304 //send email notification
305 emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
306 } else {
307 echo "Would send email to: ${email_to}"
308 echo "With title: ${email_subject}"
309 echo "Content: \n${email_body}"
310 }
[e8a22a7]311}
[5b8413b4]312
313//===========================================================================================================
314// Helper classes/variables/routines
315//===========================================================================================================
316//Description of a compiler (Must be serializable since pipelines are persistent)
317class CC_Desc implements Serializable {
[93fe3154]318 public String name
319 public String CXX
[6ebc13f]320 public String CC
[93fe3154]321
[6ebc13f]322 CC_Desc(String name, String CXX, String CC) {
[93fe3154]323 this.name = name
324 this.CXX = CXX
[6ebc13f]325 this.CC = CC
[5b8413b4]326 }
327}
328
329//Description of an architecture (Must be serializable since pipelines are persistent)
330class Arch_Desc implements Serializable {
331 public String name
332 public String flags
[5307c33]333 public String node
[5b8413b4]334
[5307c33]335 Arch_Desc(String name, String flags, String node) {
[5b8413b4]336 this.name = name
337 this.flags = flags
[5307c33]338 this.node = node
[5b8413b4]339 }
340}
341
342class BuildSettings implements Serializable {
343 public final CC_Desc Compiler
344 public final Arch_Desc Architecture
345 public final Boolean RunAllTests
346 public final Boolean RunBenchmark
347 public final Boolean BuildDocumentation
348 public final Boolean Publish
349 public final Boolean Silent
350 public final Boolean IsSandbox
351 public final String DescLong
352 public final String DescShort
353
[a336d46]354 public String GitNewRef
355 public String GitOldRef
356
[490cb3c]357 BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
[5b8413b4]358 switch( param.Compiler ) {
359 case 'gcc-6':
360 this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
361 break
362 case 'gcc-5':
363 this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
364 break
365 case 'gcc-4.9':
366 this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
367 break
368 case 'clang':
369 this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
370 break
371 default :
372 error "Unhandled compiler : ${cc}"
373 }
374
375 switch( param.Architecture ) {
376 case 'x64':
[a3e8281]377 this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
[5b8413b4]378 break
379 case 'x86':
[a3e8281]380 this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
[5b8413b4]381 break
382 default :
383 error "Unhandled architecture : ${arch}"
384 }
385
[f95e8f0]386 this.IsSandbox = (branch == "jenkins-sandbox")
[5b8413b4]387 this.RunAllTests = param.RunAllTests
[7a230fd]388 this.RunBenchmark = param.RunBenchmark
[5b8413b4]389 this.BuildDocumentation = param.BuildDocumentation
[7a230fd]390 this.Publish = param.Publish
[5b8413b4]391 this.Silent = param.Silent
392
393 def full = param.RunAllTests ? " (Full)" : ""
[490cb3c]394 this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
[5b8413b4]395
[93fe3154]396 this.DescLong = """Compiler : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
[5b8413b4]397Architecture : ${ this.Architecture.name }
398Arc Flags : ${ this.Architecture.flags }
399Run All Tests : ${ this.RunAllTests.toString() }
400Run Benchmark : ${ this.RunBenchmark.toString() }
401Build Documentation : ${ this.BuildDocumentation.toString() }
402Publish : ${ this.Publish.toString() }
403Silent : ${ this.Silent.toString() }
404"""
[a336d46]405
406 this.GitNewRef = ''
407 this.GitOldRef = ''
[5b8413b4]408 }
409}
410
[490cb3c]411class PlotGroup implements Serializable {
412 public String name
413 public String unit
414 public boolean log
415
416 PlotGroup(String name, String unit, boolean log) {
417 this.name = name
418 this.unit = unit
419 this.log = log
420 }
421}
422
[5b8413b4]423def prepare_build() {
424 // prepare the properties
425 properties ([ \
426 [$class: 'ParametersDefinitionProperty', \
427 parameterDefinitions: [ \
428 [$class: 'ChoiceParameterDefinition', \
429 description: 'Which compiler to use', \
430 name: 'Compiler', \
431 choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang', \
432 defaultValue: 'gcc-6', \
433 ], \
434 [$class: 'ChoiceParameterDefinition', \
435 description: 'The target architecture', \
436 name: 'Architecture', \
437 choices: 'x64\nx86', \
438 defaultValue: 'x64', \
439 ], \
440 [$class: 'BooleanParameterDefinition', \
441 description: 'If false, only the quick test suite is ran', \
442 name: 'RunAllTests', \
443 defaultValue: false, \
444 ], \
445 [$class: 'BooleanParameterDefinition', \
446 description: 'If true, jenkins also runs benchmarks', \
447 name: 'RunBenchmark', \
448 defaultValue: false, \
449 ], \
450 [$class: 'BooleanParameterDefinition', \
451 description: 'If true, jenkins also builds documentation', \
452 name: 'BuildDocumentation', \
453 defaultValue: true, \
454 ], \
455 [$class: 'BooleanParameterDefinition', \
456 description: 'If true, jenkins also publishes results', \
457 name: 'Publish', \
458 defaultValue: false, \
459 ], \
460 [$class: 'BooleanParameterDefinition', \
461 description: 'If true, jenkins will not send emails', \
462 name: 'Silent', \
463 defaultValue: false, \
464 ], \
465 ],
466 ]])
467
[4c55047]468 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
469 checkout scm
[2407853]470
[490cb3c]471 final settings = new BuildSettings(params, env.BRANCH_NAME)
[5b8413b4]472
473 currentBuild.description = settings.DescShort
474 echo settings.DescLong
475
476 return settings
477}
478
[6c55a3d]479def build_stage(String name, boolean run, Closure block ) {
[5b8413b4]480 StageName = name
481 echo " -------- ${StageName} -------- "
[8ecb590]482 if(run) {
483 stage(name, block)
484 } else {
485 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
486 }
[5b8413b4]487}
488
489def make_doc() {
490 def err = null
491 try {
492 sh 'make clean > /dev/null'
493 sh 'make > /dev/null 2>&1'
494 }
495 catch (Exception caughtError) {
496 err = caughtError //rethrow error later
[65f4a51]497 sh 'cat build/*.log'
[5b8413b4]498 }
499 finally {
500 if (err) throw err // Must re-throw exception to propagate error
501 }
[a2a0065]502}
503
[3221a2b]504def do_plot(boolean new_data, String file, PlotGroup group, boolean relative, String title) {
[8d63649]505
[1b3eef8]506 if(new_data) {
507 echo "Publishing new data"
508 }
509
[cdcd53dc]510 def series = new_data ? [[
[df57a84]511 file: "${file}.csv",
[3c40dc2a]512 exclusionValues: '',
513 displayTableFlag: false,
514 inclusionFlag: 'OFF',
515 url: ''
[cdcd53dc]516 ]] : [];
[8d63649]517
518 echo "file is ${BuildDir}/benchmark/${file}.csv, group ${group}, title ${title}"
519 dir("${BuildDir}/benchmark/") {
520 plot csvFileName: "cforall-${env.BRANCH_NAME}-${file}.csv",
521 csvSeries: series,
[490cb3c]522 group: "${group.name}",
[3c40dc2a]523 title: "${title}",
524 style: 'lineSimple',
525 exclZero: false,
526 keepRecords: false,
[3221a2b]527 logarithmic: !relative && group.log,
[3c40dc2a]528 numBuilds: '120',
529 useDescr: true,
[490cb3c]530 yaxis: group.unit,
[3c40dc2a]531 yaxisMaximum: '',
532 yaxisMinimum: ''
[df57a84]533 }
534}
Note: See TracBrowser for help on using the repository browser.