Remove s_isProcessExiting and Clear of ALC list at exit
[platform/upstream/coreclr.git] / perf.groovy
1 // Import the utility functionality.
2
3 import jobs.generation.*;
4
5 def project = GithubProject
6 def branch = GithubBranchName
7 def projectName = Utilities.getFolderName(project)
8 def projectFolder = projectName + '/' + Utilities.getFolderName(branch)
9
10 def static getOSGroup(def os) {
11     def osGroupMap = ['Ubuntu14.04':'Linux',
12         'RHEL7.2': 'Linux',
13         'Ubuntu16.04': 'Linux',
14         'Debian8.4':'Linux',
15         'Fedora24':'Linux',
16         'OSX':'OSX',
17         'Windows_NT':'Windows_NT',
18         'FreeBSD':'FreeBSD',
19         'CentOS7.1': 'Linux',
20         'OpenSUSE13.2': 'Linux',
21         'OpenSUSE42.1': 'Linux',
22         'LinuxARMEmulator': 'Linux']
23     def osGroup = osGroupMap.get(os, null)
24     assert osGroup != null : "Could not find os group for ${os}"
25     return osGroupMap[os]
26 }
27
28 // Setup perflab tests runs
29 [true, false].each { isPR ->
30     ['Windows_NT'].each { os ->
31         ['x64', 'x86'].each { arch ->
32             [true, false].each { isSmoketest ->
33                 ['ryujit'].each { jit ->
34                     ['full_opt', 'min_opt'].each { opt_level ->
35
36                         def architecture = arch
37                         def jobName = isSmoketest ? "perf_perflab_${os}_${arch}_${opt_level}_${jit}_smoketest" : "perf_perflab_${os}_${arch}_${opt_level}_${jit}"
38                         def testEnv = ""
39                         def python = "C:\\Python35\\python.exe"
40
41                         def newJob = job(Utilities.getFullJobName(project, jobName, isPR)) {
42                             // Set the label.
43                             if (isSmoketest) {
44                                 label('Windows.10.Amd64.ClientRS4.DevEx.15.8.Open')
45                                 python = "C:\\python3.7.0\\python.exe"
46                             }
47                             else {
48                                 label('windows_server_2016_clr_perf')
49                             }
50
51                             wrappers {
52                                 credentialsBinding {
53                                     string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
54                                 }
55                             }
56
57                             if (isPR) {
58                                 parameters {
59                                     stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
60                                 }
61                             }
62
63                             if (isSmoketest) {
64                                 parameters {
65                                     stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '2', 'Sets the number of iterations to twenty one.  We are doing this to limit the amount of data that we upload as 20 iterations is enough to get a good sample')
66                                     stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '2', 'Sets the number of iterations to twenty one.  We are doing this to limit the amount of data that we upload as 20 iterations is enough to get a good sample')
67                                 }
68                             }
69                             else{
70                                 parameters {
71                                     stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '21', 'Sets the number of iterations to twenty one.  We are doing this to limit the amount of data that we upload as 20 iterations is enough to get a good sample')
72                                     stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '21', 'Sets the number of iterations to twenty one.  We are doing this to limit the amount of data that we upload as 20 iterations is enough to get a good sample')
73                                 }
74                             }
75
76                             def configuration = 'Release'
77                             def runType = isPR ? 'private' : 'rolling'
78                             def benchViewName = isPR ? 'coreclr private %BenchviewCommitName%' : 'coreclr rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
79                             def uploadString = isSmoketest ? '' : '-uploadToBenchview'
80
81                             steps {
82                                 // Batch
83
84                                 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
85                                 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
86                                 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
87                                 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
88                                 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
89                                 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
90                                 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
91                                 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
92                                 "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
93                                 "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
94                                 batchFile("${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
95                                 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
96
97                                 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
98
99                                 def runXUnitPerfCommonArgs = "-arch ${arch} -configuration ${configuration} -os ${os} -generateBenchviewData \"%WORKSPACE%\\Microsoft.Benchview.JSONFormat\\tools\" ${uploadString} -runtype ${runType} ${testEnv} -optLevel ${opt_level} -jitName ${jit} -outputdir \"%WORKSPACE%\\bin\\sandbox_logs\" -stabilityPrefix \"START \\\"CORECLR_PERF_RUN\\\" /B /WAIT /HIGH /AFFINITY 0x2\""
100
101                                 // Run with just stopwatch: Profile=Off
102                                 batchFile("${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\perflab\\Perflab -library")
103                                 batchFile("${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\Jit\\Performance\\CodeQuality")
104
105                                 // Run with the full set of counters enabled: Profile=On
106                                 if (opt_level != 'min_opt') {
107                                     batchFile("${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\perflab\\Perflab -library -collectionFlags default+BranchMispredictions+CacheMisses+InstructionRetired+gcapi")
108                                     batchFile("${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\Jit\\Performance\\CodeQuality -collectionFlags default+BranchMispredictions+CacheMisses+InstructionRetired+gcapi")
109                                 }
110                             }
111                         }
112
113                         def archiveSettings = new ArchivalSettings()
114                         archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
115                         archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
116                         archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
117                         archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
118                         archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
119                         archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
120                         archiveSettings.addFiles('machinedata.json')
121                         archiveSettings.setAlwaysArchive()
122
123                         Utilities.addArchival(newJob, archiveSettings)
124                         Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
125
126                         newJob.with {
127                             logRotator {
128                                 artifactDaysToKeep(14)
129                                 daysToKeep(30)
130                                 artifactNumToKeep(100)
131                                 numToKeep(200)
132                             }
133                             wrappers {
134                                 timeout {
135                                     absolute(240)
136                                 }
137                             }
138                         }
139
140                         if (isPR) {
141                             TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
142                             if (isSmoketest) {
143                                 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} CoreCLR Perf Tests Correctness")
144                             }
145                             else {
146                                 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} CoreCLR Perf Tests")
147
148                                 def opts = ""
149                                 if (opt_level == 'min_opt') {
150                                     opts = '\\W+min_opts'
151                                 }
152                                 def jitt = ""
153                                 if (jit != 'ryujit') {
154                                     jitt = "\\W+${jit}"
155                                 }
156
157                                 builder.triggerOnlyOnComment()
158                                 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}\\W+perf.*")
159                             }
160
161                             builder.triggerForBranch(branch)
162                             builder.emitTrigger(newJob)
163                         }
164                         else if (opt_level == 'full_opt') {
165                             // Set a push trigger
166                             TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
167                             builder.emitTrigger(newJob)
168                         }
169                         else {
170                             // Set periodic trigger
171                             Utilities.addPeriodicTrigger(newJob, '@daily')
172                         }
173                     }
174                 }
175             }
176         }
177     }
178 }
179
180 // Setup throughput perflab tests runs
181 [true, false].each { isPR ->
182     ['Windows_NT'].each { os ->
183         ['x64', 'x86'].each { arch ->
184             ['ryujit'].each { jit ->
185                 [true, false].each { pgo_optimized ->
186                     ['full_opt', 'min_opt'].each { opt_level ->
187                         def architecture = arch
188
189                         def python = "C:\\Python35\\python.exe"
190
191                         pgo_build = ""
192                         pgo_test = ""
193                         pgo_string = "pgo"
194                         if (!pgo_optimized) {
195                             pgo_build = " -nopgooptimize"
196                             pgo_test = " -nopgo"
197                             pgo_string = "nopgo"
198                         }
199
200                         def newJob = job(Utilities.getFullJobName(project, "perf_throughput_perflab_${os}_${arch}_${opt_level}_${jit}_${pgo_string}", isPR)) {
201                             // Set the label.
202                             label('windows_server_2016_clr_perf')
203                             wrappers {
204                                 credentialsBinding {
205                                     string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
206                                 }
207                             }
208
209                             if (isPR) {
210                                 parameters {
211                                     stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that will be used to build the full title of a run in Benchview.')
212                                 }
213                             }
214
215                             def configuration = 'Release'
216                             def runType = isPR ? 'private' : 'rolling'
217                             def benchViewName = isPR ? 'coreclr-throughput private %BenchviewCommitName%' : 'coreclr-throughput rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
218
219                             steps {
220                                 // Batch
221                                 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
222                                 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\"")
223                                 batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
224                                 batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os} -Source https://dotnet.myget.org/F/dotnet-core -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
225                                 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
226                                 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
227                                 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
228                                 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
229                                 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
230                                 "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"${benchViewName}\" --user-email \"dotnet-bot@microsoft.com\"\n" +
231                                 "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
232                                 batchFile("${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
233                                 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}${pgo_build} skiptests")
234                                 batchFile("${python} -u tests\\scripts\\run-throughput-perf.py -arch ${arch} -os ${os} -configuration ${configuration} -opt_level ${opt_level} -jit_name ${jit}${pgo_test} -clr_root \"%WORKSPACE%\" -assembly_root \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\\lib\" -benchview_path \"%WORKSPACE%\\Microsoft.Benchview.JSONFormat\\tools\" -run_type ${runType}")
235                             }
236                         }
237
238                         // Save machinedata.json to /artifact/bin/ Jenkins dir
239                         def archiveSettings = new ArchivalSettings()
240                         archiveSettings.addFiles('throughput-*.csv')
241                         archiveSettings.setAlwaysArchive()
242                         Utilities.addArchival(newJob, archiveSettings)
243
244                         Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
245
246                         if (isPR) {
247                             def opts = ""
248                             if (opt_level == 'min_opt') {
249                                 opts = '\\W+min_opts'
250                             }
251
252                             def jitt = ""
253                             if (jit != 'ryujit') {
254                                 jitt = "\\W+${jit}"
255                             }
256
257                             def pgo_trigger = ""
258                             if (pgo_optimized) {
259                                 pgo_trigger = "\\W+nopgo"
260                             }
261
262
263                             TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
264                             builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} ${pgo_string} CoreCLR Throughput Perf Tests")
265                             builder.triggerOnlyOnComment()
266                             builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}${pgo_trigger}\\W+throughput.*")
267                             builder.triggerForBranch(branch)
268                             builder.emitTrigger(newJob)
269                         }
270                         else if (opt_level == 'full_opt' && pgo_optimized) {
271                             // Set a push trigger
272                             TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
273                             builder.emitTrigger(newJob)
274                         }
275                         else {
276                             // Set periodic trigger
277                             Utilities.addPeriodicTrigger(newJob, '@daily')
278                         }
279                     }
280                 }
281             }
282         }
283     }
284 }
285
286 def static getFullPerfJobName(def project, def os, def arch, def isPR) {
287     return Utilities.getFullJobName(project, "perf_${os}_${arch}", isPR)
288 }
289
290 // Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
291 [true, false].each { isPR ->
292     ['x64'].each { architecture ->
293         def fullBuildJobName = Utilities.getFullJobName(project, "perf_linux_build", isPR)
294         def configuration = 'Release'
295
296         def crossCompile = ""
297         def crossLayout = ""
298         def python = "python3.5"
299
300         // Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
301         ['RHEL7.2'].each { os ->
302             def newBuildJob = job(fullBuildJobName) {
303                 steps {
304                     shell("./build.sh verbose ${architecture} ${configuration}${crossCompile}")
305                     shell("./build-test.sh generatelayoutonly ${architecture} ${configuration}${crossLayout}")
306                 }
307             }
308             Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
309             Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
310             Utilities.addArchival(newBuildJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so,bin/tests/**", "bin/Product/**/.nuget/**")
311         }
312
313
314         // Actual perf testing on the following OSes
315         def perfOSList = ['Ubuntu16.04']
316
317         perfOSList.each { os ->
318             def newJob = job(getFullPerfJobName(project, os, architecture, isPR)) {
319
320                 def machineLabel = 'ubuntu_1604_clr_perf'
321
322                 label(machineLabel)
323                 wrappers {
324                     credentialsBinding {
325                         string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
326                     }
327                 }
328
329                 if (isPR) {
330                     parameters {
331                         stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
332                     }
333                 }
334
335                 parameters {
336                     // Cap the maximum number of iterations to 21.
337                     stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '21', 'Sets the number of iterations to twenty one.  We are doing this to limit the amount of data that we upload as 20 iterations is enough to get a good sample')
338                     stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '21', 'Sets the number of iterations to twenty one.  We are doing this to limit the amount of data that we upload as 20 iterations is enough to get a good sample')
339                     stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
340                 }
341
342                 def osGroup = getOSGroup(os)
343                 def runType = isPR ? 'private' : 'rolling'
344                 def benchViewName = isPR ? 'coreclr private \$BenchviewCommitName' : 'coreclr rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
345                 def uploadString = '-uploadToBenchview'
346
347                 def runXUnitCommonArgs = "-arch ${architecture} -os ${os} -configuration ${configuration} -stabilityPrefix \"taskset 0x00000002 nice --adjustment=-10\" -generateBenchviewData \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools\" ${uploadString} -runtype ${runType} -outputdir \"\${WORKSPACE}/bin/sandbox_logs\""
348
349                 steps {
350                     shell("./tests/scripts/perf-prep.sh --nocorefx")
351                     shell("./init-tools.sh")
352                     copyArtifacts(fullBuildJobName) {
353                         includePatterns("bin/**")
354                         buildSelector {
355                             buildNumber('\${PRODUCT_BUILD}')
356                         }
357                     }
358                     shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
359                     "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user-email \"dotnet-bot@microsoft.com\"\n" +
360                     "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
361                     shell("""${python} ./tests/scripts/run-xunit-perf.py -testBinLoc bin/tests/Windows_NT.${architecture}.${configuration}/JIT/Performance/CodeQuality ${runXUnitCommonArgs}""")
362                 }
363             }
364
365             def archiveSettings = new ArchivalSettings()
366             archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
367             archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
368             archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
369             archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
370             archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
371             archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
372             archiveSettings.addFiles('machinedata.json')
373             archiveSettings.setAlwaysArchive()
374
375             Utilities.addArchival(newJob, archiveSettings)
376             Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
377
378             // For perf, we need to keep the run results longer
379             newJob.with {
380                 // Enable the log rotator
381                 logRotator {
382                     artifactDaysToKeep(14)
383                     daysToKeep(30)
384                     artifactNumToKeep(100)
385                     numToKeep(200)
386                 }
387                 wrappers {
388                     timeout {
389                         absolute(240)
390                     }
391                 }
392             }
393         } // os
394
395         def flowJobPerfRunList = perfOSList.collect { os ->
396             "{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullPerfJobName(project, os, architecture, isPR)}') }"
397         }
398         def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_linux_${architecture}_flow", isPR, '')) {
399             if (isPR) {
400                 parameters {
401                     stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
402                 }
403             }
404             buildFlow("""
405 // First, build the bits on RHEL7.2
406 b = build(params, '${fullBuildJobName}')
407
408 // Then, run the perf tests
409 parallel(
410     ${flowJobPerfRunList.join(",\n    ")}
411 )
412 """)
413         }
414
415         Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
416         Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
417
418         if (isPR) {
419             TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
420             builder.setGithubContext("Linux Perf Test Flow")
421             builder.triggerOnlyOnComment()
422             builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+perf\\W+flow.*")
423             builder.triggerForBranch(branch)
424             builder.emitTrigger(newFlowJob)
425         }
426         else {
427             // Set a push trigger
428             TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
429             builder.emitTrigger(newFlowJob)
430         }
431     } // architecture
432 } // isPR
433
434 def static getDockerImageName(def architecture, def os, def isBuild) {
435     // We must change some docker private images to official later
436     if (isBuild) {
437         if (architecture == 'arm') {
438             if (os == 'Ubuntu') {
439                 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420"
440             }
441         }
442     }
443     println("Unknown architecture to use docker: ${architecture} ${os}");
444     assert false
445 }
446
447 def static getFullThroughputJobName(def project, def os, def arch, def isPR) {
448     return Utilities.getFullJobName(project, "perf_throughput_${os}_${arch}", isPR)
449 }
450
451 // Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
452 [true, false].each { isPR ->
453     ['x64','arm'].each { architecture ->
454         def fullBuildJobName = Utilities.getFullJobName(project, "perf_throughput_linux_${architecture}_build", isPR)
455         def configuration = 'Release'
456
457         
458         def crossCompile = ""
459         def python = "python3.5"
460         def tgzFile = "bin-Product-Linux.${architecture}.${configuration}.tgz"
461
462         if (architecture == "arm") {
463             python = "python3.6"
464             def buildCommands = []
465             def newBuildJob = job(fullBuildJobName) {
466                 def dockerImage = getDockerImageName(architecture, 'Ubuntu', true)
467                 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${dockerImage} "
468
469                 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh release ${architecture} cross"
470
471                 steps {
472                     buildCommands.each { buildCommand ->
473                         shell(buildCommand)
474                         shell("tar -czf ${tgzFile} bin/Product/Linux.${architecture}.${configuration}")
475                     }
476                 }
477
478                 publishers {
479                     azureVMAgentPostBuildAction {
480                         agentPostBuildAction('Delete agent after build execution (when idle).')
481                     }
482                 }
483             }
484             Utilities.setMachineAffinity(newBuildJob, "Ubuntu16.04", 'latest-or-auto')
485             Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
486             Utilities.addArchival(newBuildJob, "${tgzFile}")
487         }
488         else {
489             // Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
490             ['RHEL7.2'].each { os ->
491                 def newBuildJob = job(fullBuildJobName) {
492                     steps {
493                         shell("./build.sh verbose ${architecture} ${configuration}${crossCompile}")
494                     }
495                 }
496                 Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
497                 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
498                 Utilities.addArchival(newBuildJob, "bin/Product/**")
499             }
500         }
501
502         // Actual perf testing on the following OSes
503         def throughputOSList = ['Ubuntu16.04']
504         if (architecture == 'arm') {
505             throughputOSList = ['Ubuntu14.04']
506         }
507         def throughputOptLevelList = ['full_opt', 'min_opt']
508
509         def throughputOSOptLevelList = []
510
511         throughputOSList.each { os ->
512             throughputOptLevelList.each { opt_level ->
513                 throughputOSOptLevelList.add("${os}_${opt_level}")
514             }
515         }
516
517         throughputOSList.each { os ->
518             throughputOptLevelList.each { opt_level ->
519                 def newJob = job(getFullThroughputJobName(project, "${os}_${opt_level}", architecture, isPR)) {
520
521                     def machineLabel = 'ubuntu_1604_clr_perf'
522                     if (architecture == 'arm') {
523                         machineLabel = 'ubuntu_1404_clr_perf_arm'
524                     }
525
526                     label(machineLabel)
527                         wrappers {
528                             credentialsBinding {
529                                 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
530                             }
531                         }
532
533                     if (isPR) {
534                         parameters {
535                             stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that will be used to build the full title of a run in Benchview.')
536                         }
537                     }
538
539                     parameters {
540                         stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
541                     }
542
543                     def osGroup = getOSGroup(os)
544                     def runType = isPR ? 'private' : 'rolling'
545                     def benchViewName = isPR ? 'coreclr-throughput private \$BenchviewCommitName' : 'coreclr-throughput rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
546                     def archString = architecture == 'arm' ? ' --arch=arm' : ''
547
548                     steps {
549                         shell("bash ./tests/scripts/perf-prep.sh --throughput${archString}")
550                         copyArtifacts(fullBuildJobName) {
551                             if (architecture == 'arm') {
552                                 includePatterns("${tgzFile}")
553                             }
554                             else {
555                                 includePatterns("bin/Product/**")
556                             }
557                             buildSelector {
558                                 buildNumber('\${PRODUCT_BUILD}')
559                             }
560                         }
561                         if (architecture == 'arm') {
562                             shell("tar -xzf ./${tgzFile} || exit 0")
563                         }
564                         shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
565                         "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user-email \"dotnet-bot@microsoft.com\"\n" +
566                         "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
567                         shell("""${python} ./tests/scripts/run-throughput-perf.py \\
568                         -arch \"${architecture}\" \\
569                         -os \"${os}\" \\
570                         -configuration \"${configuration}\" \\
571                         -opt_level \"${opt_level}\" \\
572                         -clr_root \"\${WORKSPACE}\" \\
573                         -assembly_root \"\${WORKSPACE}/Microsoft.Benchview.ThroughputBenchmarks.x64.Windows_NT/lib\" \\
574                         -run_type \"${runType}\" \\
575                         -benchview_path \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools\"""")
576                     }
577                 }
578
579                 // Save machinedata.json to /artifact/bin/ Jenkins dir
580                 def archiveSettings = new ArchivalSettings()
581                 archiveSettings.addFiles('throughput-*.csv')
582                 archiveSettings.addFiles('machinedata.json')
583                 archiveSettings.setAlwaysArchive()
584                 Utilities.addArchival(newJob, archiveSettings)
585
586                 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
587
588                 // For perf, we need to keep the run results longer
589                 newJob.with {
590                     // Enable the log rotator
591                     logRotator {
592                         artifactDaysToKeep(7)
593                         daysToKeep(300)
594                         artifactNumToKeep(25)
595                         numToKeep(1000)
596                     }
597                 }
598             } // opt_level
599         } // os
600
601         def flowJobTPRunList = throughputOSOptLevelList.collect { os ->
602             "{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullThroughputJobName(project, os, architecture, isPR)}') }"
603         }
604         def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_throughput_linux_${architecture}_flow", isPR, '')) {
605             if (isPR) {
606                 parameters {
607                     stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
608                 }
609             }
610             buildFlow("""
611     // First, build the bits on RHEL7.2
612     b = build(params, '${fullBuildJobName}')
613
614     // Then, run the perf tests
615     parallel(
616         ${flowJobTPRunList.join(",\n    ")}
617     )
618     """)
619         }
620
621         Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
622         Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
623
624         if (isPR) {
625             TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
626             builder.setGithubContext("Linux ${architecture} Throughput Perf Test Flow")
627             builder.triggerOnlyOnComment()
628             builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+throughput\\W+flow.*")
629             builder.triggerForBranch(branch)
630             builder.emitTrigger(newFlowJob)
631         }
632         else {
633             // Set a push trigger
634             TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
635             builder.emitTrigger(newFlowJob)
636         }
637     } // architecture
638 } // isPR
639
640 // Setup CoreCLR-Scenarios tests
641 [true, false].each { isPR ->
642     ['Windows_NT'].each { os ->
643         ['x64', 'x86'].each { arch ->
644             ['ryujit'].each { jit ->
645                 ['full_opt', 'min_opt', 'tiered'].each { opt_level ->
646                     def architecture = arch
647                     def newJob = job(Utilities.getFullJobName(project, "perf_scenarios_${os}_${arch}_${opt_level}_${jit}", isPR)) {
648
649                         def testEnv = ""
650                         def python = "C:\\Python35\\python.exe"
651
652                         // Set the label.
653                         label('windows_server_2016_clr_perf')
654                         wrappers {
655                             credentialsBinding {
656                                 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
657                             }
658                         }
659
660                         if (isPR) {
661                             parameters {
662                                 stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
663                             }
664                         }
665
666                         parameters {
667                             stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '1', 'Size test, one iteration is sufficient')
668                             stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '1', 'Size test, one iteration is sufficient')
669                         }
670
671                         def configuration = 'Release'
672                         def runType = isPR ? 'private' : 'rolling'
673                         def benchViewName = isPR ? 'CoreCLR-Scenarios private %BenchviewCommitName%' : 'CoreCLR-Scenarios rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
674                         def uploadString = '-uploadToBenchview'
675
676                         steps {
677                             // Batch
678                             batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
679                             batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
680                             batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
681
682                             //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
683                             //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
684                             batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
685                             "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
686                             "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
687                             "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
688                             "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
689                             batchFile("${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
690                             batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
691
692                             batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
693
694                             def runXUnitPerfCommonArgs = "-arch ${arch} -configuration ${configuration} -os ${os} -generateBenchviewData \"%WORKSPACE%\\Microsoft.Benchview.JSONFormat\\tools\" ${uploadString} -runtype ${runType} ${testEnv} -optLevel ${opt_level} -jitName ${jit} -outputdir \"%WORKSPACE%\\bin\\sandbox_logs\" -stabilityPrefix \"START \\\"CORECLR_PERF_RUN\\\" /B /WAIT /HIGH\" -scenarioTest"
695
696                             // Profile=Off
697                             batchFile("${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\Scenario\\JitBench -group CoreCLR-Scenarios")
698
699                             // Profile=On
700                             if (opt_level != 'min_opt') {
701                                 batchFile("${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\Scenario\\JitBench -group CoreCLR-Scenarios -collectionFlags BranchMispredictions+CacheMisses+InstructionRetired")
702                             }
703                         }
704                     }
705
706                     def archiveSettings = new ArchivalSettings()
707                     archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
708                     archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
709                     archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
710                     archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
711                     archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
712                     archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
713                     archiveSettings.addFiles('machinedata.json')
714                     archiveSettings.setAlwaysArchive()
715
716                     Utilities.addArchival(newJob, archiveSettings)
717                     Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
718
719                     newJob.with {
720                         logRotator {
721                             artifactDaysToKeep(14)
722                             daysToKeep(30)
723                             artifactNumToKeep(100)
724                             numToKeep(200)
725                         }
726                         wrappers {
727                             timeout {
728                                 absolute(240)
729                             }
730                         }
731                     }
732
733                     if (isPR) {
734                         def opts = ""
735                         if (opt_level == 'min_opt') {
736                             opts = '\\W+min_opts'
737                         }
738                         def jitt = ""
739                         if (jit != 'ryujit') {
740                             jitt = "\\W+${jit}"
741                         }
742
743                         TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
744                         builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} Performance Scenarios Tests")
745                         builder.triggerOnlyOnComment()
746                         builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}\\W+perf\\W+scenarios.*")
747                         builder.triggerForBranch(branch)
748                         builder.emitTrigger(newJob)
749                     }
750                     else if (opt_level == 'full_opt') {
751                         // Set a push trigger
752                         TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
753                         builder.emitTrigger(newJob)
754                     }
755                     else {
756                         // Set periodic trigger
757                         Utilities.addPeriodicTrigger(newJob, '@daily')
758                     }
759                 }
760             }
761         }
762     }
763 }
764
765 // Setup size-on-disk test
766 ['Windows_NT'].each { os ->
767     ['x64', 'x86'].each { arch ->
768         def architecture = arch
769         def newJob = job(Utilities.getFullJobName(project, "sizeondisk_${arch}", false)) {
770             label('Windows.10.Amd64.ClientRS4.DevEx.15.8.Open')
771
772             wrappers {
773                 credentialsBinding {
774                     string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
775                 }
776             }
777
778             def channel = 'master'
779             def configuration = 'Release'
780             def runType = 'rolling'
781             def benchViewName = 'Dotnet Size on Disk %DATE% %TIME%'
782             def testBin = "%WORKSPACE%\\bin\\tests\\${os}.${architecture}.${configuration}"
783             def coreRoot = "${testBin}\\Tests\\Core_Root"
784             def benchViewTools = "%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools"
785             def python = "C:\\python3.7.0\\python.exe"
786
787             steps {
788                 // Install nuget and get BenchView tools
789                 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
790                 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
791                 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
792
793                 // Generate submission metadata for BenchView
794                 // Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
795                 // we have to do it all as one statement because cmd is called each time and we lose the set environment variable
796                 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
797                 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
798                 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
799                 "${python} \"${benchViewTools}\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
800                 "${python} \"${benchViewTools}\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
801
802                 // Generate machine data from BenchView
803                 batchFile("${python} \"${benchViewTools}\\machinedata.py\"")
804
805                 // Build CoreCLR and gnerate test layout
806                 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
807                 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
808
809                 // Run the size on disk benchmark
810                 batchFile("\"${coreRoot}\\CoreRun.exe\" \"${testBin}\\sizeondisk\\sodbench\\SoDBench\\SoDBench.exe\" -o \"%WORKSPACE%\\sodbench.csv\" --architecture ${arch} --channel ${channel}")
811
812                 // From sodbench.csv, create measurment.json, then submission.json
813                 batchFile("${python} \"${benchViewTools}\\measurement.py\" csv \"%WORKSPACE%\\sodbench.csv\" --metric \"Size on Disk\" --unit \"bytes\" --better \"desc\"")
814                 batchFile("${python} \"${benchViewTools}\\submission.py\" measurement.json --build build.json --machine-data machinedata.json --metadata submission-metadata.json --group \"Dotnet Size on Disk\" --type ${runType} --config-name ${configuration} --architecture ${arch} --machinepool VM --config Channel ${channel}")
815
816                 // If this is a PR, upload submission.json
817                 batchFile("${python} \"${benchViewTools}\\upload.py\" submission.json --container coreclr")
818             }
819         }
820
821         def archiveSettings = new ArchivalSettings()
822         archiveSettings.addFiles('bin/toArchive/**')
823         archiveSettings.addFiles('machinedata.json')
824         archiveSettings.setAlwaysArchive()
825
826         Utilities.addArchival(newJob, archiveSettings)
827         Utilities.standardJobSetup(newJob, project, false, "*/${branch}")
828
829         // Set the cron job here.  We run nightly on each flavor, regardless of code changes
830         Utilities.addPeriodicTrigger(newJob, "@daily", true /*always run*/)
831
832         newJob.with {
833             logRotator {
834                 artifactDaysToKeep(14)
835                 daysToKeep(30)
836                 artifactNumToKeep(100)
837                 numToKeep(200)
838             }
839             wrappers {
840                 timeout {
841                     absolute(240)
842                 }
843             }
844         }
845     }
846 }
847
848 // Setup IlLink tests
849 [true, false].each { isPR ->
850     ['Windows_NT'].each { os ->
851         ['x64'].each { arch ->
852             ['ryujit'].each { jit ->
853                 ['full_opt'].each { opt_level ->
854                     def architecture = arch
855                     def newJob = job(Utilities.getFullJobName(project, "perf_illink_${os}_${arch}_${opt_level}_${jit}", isPR)) {
856                         label('Windows.10.Amd64.ClientRS4.DevEx.15.8.Open')
857
858                         def testEnv = ""
859                         def python = "C:\\python3.7.0\\python.exe"
860                         wrappers {
861                             credentialsBinding {
862                                 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
863                             }
864                         }
865
866                         if (isPR) {
867                             parameters {
868                                 stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
869                             }
870                         }
871
872                         parameters {
873                             stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '1', 'Size test, one iteration is sufficient')
874                             stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '1', 'Size test, one iteration is sufficient')
875                         }
876
877                         def configuration = 'Release'
878                         def runType = isPR ? 'private' : 'rolling'
879                         def benchViewName = isPR ? 'CoreCLR-Scenarios private %BenchviewCommitName%' : 'CoreCLR-Scenarios rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
880                         def uploadString = '-uploadToBenchview'
881
882                         steps {
883                             // Batch
884                             batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
885                             batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
886                             batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
887
888                             //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
889                             //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
890                             batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
891                             "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
892                             "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
893                             "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
894                             "${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
895                             batchFile("${python} \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
896                             batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
897
898                             batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
899
900                             def runXUnitPerfCommonArgs = "-arch ${arch} -configuration ${configuration} -os ${os} -generateBenchviewData \"%WORKSPACE%\\Microsoft.Benchview.JSONFormat\\tools\" ${uploadString} -runtype ${runType} ${testEnv} -optLevel ${opt_level} -jitName ${jit} -outputdir \"%WORKSPACE%\\bin\\sandbox_logs\" -scenarioTest"
901
902                             // Scenario: ILLink
903                             batchFile("\"%VS140COMNTOOLS%\\..\\..\\VC\\vcvarsall.bat\" x86_amd64 && " +
904                             "${python} tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\linkbench\\linkbench -group ILLink -nowarmup")
905                         }
906                     }
907
908                     def archiveSettings = new ArchivalSettings()
909                     archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
910                     archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
911                     archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
912                     archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
913                     archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
914                     archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
915                     archiveSettings.addFiles('machinedata.json')
916                     archiveSettings.setAlwaysArchive()
917
918                     // Set the label (currently we are only measuring size, therefore we are running on VM).
919                     Utilities.addArchival(newJob, archiveSettings)
920                     Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
921
922                     newJob.with {
923                         logRotator {
924                             artifactDaysToKeep(14)
925                             daysToKeep(30)
926                             artifactNumToKeep(100)
927                             numToKeep(200)
928                         }
929                         wrappers {
930                             timeout {
931                                 absolute(240)
932                             }
933                         }
934                     }
935
936                     if (isPR) {
937                         TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
938                         builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} IlLink Tests")
939                         builder.triggerOnlyOnComment()
940                         builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}\\W+illink.*")
941                         builder.triggerForBranch(branch)
942                         builder.emitTrigger(newJob)
943                     }
944                     else {
945                         // Set a push trigger
946                         TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
947                         builder.emitTrigger(newJob)
948                     }
949                 }
950             }
951         }
952     }
953 }
954
955 Utilities.createHelperJob(this, project, branch,
956     "Welcome to the ${project} Perf help",
957     "Have a nice day!")