1 // Import the utility functionality.
3 import jobs.generation.*;
5 def project = GithubProject
6 def branch = GithubBranchName
7 def projectName = Utilities.getFolderName(project)
8 def projectFolder = projectName + '/' + Utilities.getFolderName(branch)
10 def static getOSGroup(def os) {
11 def osGroupMap = ['Ubuntu14.04':'Linux',
13 'Ubuntu16.04': 'Linux',
17 'Windows_NT':'Windows_NT',
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}"
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 ->
36 def architecture = arch
37 def jobName = isSmoketest ? "perf_perflab_${os}_${arch}_${opt_level}_${jit}_smoketest" : "perf_perflab_${os}_${arch}_${opt_level}_${jit}"
40 def newJob = job(Utilities.getFullJobName(project, jobName, isPR)) {
43 label('Windows.Amd64.ClientRS4.DevEx.15.8.Perf')
46 label('windows_server_2016_clr_perf')
51 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
57 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')
63 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')
64 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')
69 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')
70 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')
74 def configuration = 'Release'
75 def runType = isPR ? 'private' : 'rolling'
76 def benchViewName = isPR ? 'coreclr private %BenchviewCommitName%' : 'coreclr rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
77 def uploadString = isSmoketest ? '' : '-uploadToBenchview'
82 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
83 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
84 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
85 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
86 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
87 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
88 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
89 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
90 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
91 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
92 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
93 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
95 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
97 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\""
99 // Run with just stopwatch: Profile=Off
100 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\perflab\\Perflab -library")
101 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\Jit\\Performance\\CodeQuality")
103 // Run with the full set of counters enabled: Profile=On
104 if (opt_level != 'min_opt') {
105 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\perflab\\Perflab -library -collectionFlags default+BranchMispredictions+CacheMisses+InstructionRetired+gcapi")
106 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\Jit\\Performance\\CodeQuality -collectionFlags default+BranchMispredictions+CacheMisses+InstructionRetired+gcapi")
111 def archiveSettings = new ArchivalSettings()
112 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
113 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
114 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
115 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
116 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
117 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
118 archiveSettings.addFiles('machinedata.json')
119 archiveSettings.setAlwaysArchive()
121 Utilities.addArchival(newJob, archiveSettings)
122 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
126 artifactDaysToKeep(14)
128 artifactNumToKeep(100)
139 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
141 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} CoreCLR Perf Tests Correctness")
144 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} CoreCLR Perf Tests")
147 if (opt_level == 'min_opt') {
148 opts = '\\W+min_opts'
151 if (jit != 'ryujit') {
155 builder.triggerOnlyOnComment()
156 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}\\W+perf.*")
159 builder.triggerForBranch(branch)
160 builder.emitTrigger(newJob)
162 else if (opt_level == 'full_opt') {
163 // Set a push trigger
164 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
165 builder.emitTrigger(newJob)
168 // Set periodic trigger
169 Utilities.addPeriodicTrigger(newJob, '@daily')
178 // Setup throughput perflab tests runs
179 [true, false].each { isPR ->
180 ['Windows_NT'].each { os ->
181 ['x64', 'x86'].each { arch ->
182 ['ryujit'].each { jit ->
183 [true, false].each { pgo_optimized ->
184 ['full_opt', 'min_opt'].each { opt_level ->
185 def architecture = arch
190 if (!pgo_optimized) {
191 pgo_build = " -nopgooptimize"
196 def newJob = job(Utilities.getFullJobName(project, "perf_throughput_perflab_${os}_${arch}_${opt_level}_${jit}_${pgo_string}", isPR)) {
198 label('windows_server_2016_clr_perf')
201 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
207 stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that will be used to build the full title of a run in Benchview.')
211 def configuration = 'Release'
212 def runType = isPR ? 'private' : 'rolling'
213 def benchViewName = isPR ? 'coreclr-throughput private %BenchviewCommitName%' : 'coreclr-throughput rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
217 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
218 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\"")
219 batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
220 batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os} -Source https://dotnet.myget.org/F/dotnet-core -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
221 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
222 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
223 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
224 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
225 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
226 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"${benchViewName}\" --user-email \"dotnet-bot@microsoft.com\"\n" +
227 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
228 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
229 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}${pgo_build} skiptests")
230 batchFile("py -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}")
234 // Save machinedata.json to /artifact/bin/ Jenkins dir
235 def archiveSettings = new ArchivalSettings()
236 archiveSettings.addFiles('throughput-*.csv')
237 archiveSettings.setAlwaysArchive()
238 Utilities.addArchival(newJob, archiveSettings)
240 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
244 if (opt_level == 'min_opt') {
245 opts = '\\W+min_opts'
249 if (jit != 'ryujit') {
255 pgo_trigger = "\\W+nopgo"
259 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
260 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} ${pgo_string} CoreCLR Throughput Perf Tests")
261 builder.triggerOnlyOnComment()
262 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}${pgo_trigger}\\W+throughput.*")
263 builder.triggerForBranch(branch)
264 builder.emitTrigger(newJob)
266 else if (opt_level == 'full_opt' && pgo_optimized) {
267 // Set a push trigger
268 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
269 builder.emitTrigger(newJob)
272 // Set periodic trigger
273 Utilities.addPeriodicTrigger(newJob, '@daily')
282 def static getFullPerfJobName(def project, def os, def arch, def isPR) {
283 return Utilities.getFullJobName(project, "perf_${os}_${arch}", isPR)
286 // Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
287 [true, false].each { isPR ->
288 ['x64'].each { architecture ->
289 def fullBuildJobName = Utilities.getFullJobName(project, "perf_linux_build", isPR)
290 def configuration = 'Release'
292 def crossCompile = ""
294 def python = "python3.5"
296 // Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
297 ['RHEL7.2'].each { os ->
298 def newBuildJob = job(fullBuildJobName) {
300 shell("./build.sh verbose ${architecture} ${configuration}${crossCompile}")
301 shell("./build-test.sh generatelayoutonly ${architecture} ${configuration}${crossLayout}")
304 Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
305 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
306 Utilities.addArchival(newBuildJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so,bin/tests/**", "bin/Product/**/.nuget/**")
310 // Actual perf testing on the following OSes
311 def perfOSList = ['Ubuntu16.04']
313 perfOSList.each { os ->
314 def newJob = job(getFullPerfJobName(project, os, architecture, isPR)) {
316 def machineLabel = 'ubuntu_1604_clr_perf'
321 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
327 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 // Cap the maximum number of iterations to 21.
333 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')
334 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')
335 stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
338 def osGroup = getOSGroup(os)
339 def runType = isPR ? 'private' : 'rolling'
340 def benchViewName = isPR ? 'coreclr private \$BenchviewCommitName' : 'coreclr rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
341 def uploadString = '-uploadToBenchview'
343 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\""
346 shell("./tests/scripts/perf-prep.sh --nocorefx")
347 shell("./init-tools.sh")
348 copyArtifacts(fullBuildJobName) {
349 includePatterns("bin/**")
351 buildNumber('\${PRODUCT_BUILD}')
354 shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
355 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user-email \"dotnet-bot@microsoft.com\"\n" +
356 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
357 shell("""${python} ./tests/scripts/run-xunit-perf.py -testBinLoc bin/tests/Windows_NT.${architecture}.${configuration}/JIT/Performance/CodeQuality ${runXUnitCommonArgs}""")
361 def archiveSettings = new ArchivalSettings()
362 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
363 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
364 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
365 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
366 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
367 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
368 archiveSettings.addFiles('machinedata.json')
369 archiveSettings.setAlwaysArchive()
371 Utilities.addArchival(newJob, archiveSettings)
372 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
374 // For perf, we need to keep the run results longer
376 // Enable the log rotator
378 artifactDaysToKeep(14)
380 artifactNumToKeep(100)
391 def flowJobPerfRunList = perfOSList.collect { os ->
392 "{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullPerfJobName(project, os, architecture, isPR)}') }"
394 def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_linux_${architecture}_flow", isPR, '')) {
397 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')
401 // First, build the bits on RHEL7.2
402 b = build(params, '${fullBuildJobName}')
404 // Then, run the perf tests
406 ${flowJobPerfRunList.join(",\n ")}
411 Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
412 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
415 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
416 builder.setGithubContext("Linux Perf Test Flow")
417 builder.triggerOnlyOnComment()
418 builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+perf\\W+flow.*")
419 builder.triggerForBranch(branch)
420 builder.emitTrigger(newFlowJob)
423 // Set a push trigger
424 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
425 builder.emitTrigger(newFlowJob)
430 def static getDockerImageName(def architecture, def os, def isBuild) {
431 // We must change some docker private images to official later
433 if (architecture == 'arm') {
434 if (os == 'Ubuntu') {
435 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420"
439 println("Unknown architecture to use docker: ${architecture} ${os}");
443 def static getFullThroughputJobName(def project, def os, def arch, def isPR) {
444 return Utilities.getFullJobName(project, "perf_throughput_${os}_${arch}", isPR)
447 // Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
448 [true, false].each { isPR ->
449 ['x64','arm'].each { architecture ->
450 def fullBuildJobName = Utilities.getFullJobName(project, "perf_throughput_linux_${architecture}_build", isPR)
451 def configuration = 'Release'
454 def crossCompile = ""
455 def python = "python3.5"
457 if (architecture == "arm") {
459 def buildCommands = []
460 def newBuildJob = job(fullBuildJobName) {
461 def additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86"
462 def dockerImage = getDockerImageName(architecture, 'Ubuntu', true)
463 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} "
465 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh release ${architecture} cross crosscomponent"
468 buildCommands.each { buildCommand ->
474 azureVMAgentPostBuildAction {
475 agentPostBuildAction('Delete agent after build execution (when idle).')
479 Utilities.setMachineAffinity(newBuildJob, "Ubuntu16.04", 'latest-or-auto')
480 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
481 Utilities.addArchival(newBuildJob, "bin/Product/**")
484 // Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
485 ['RHEL7.2'].each { os ->
486 def newBuildJob = job(fullBuildJobName) {
488 shell("./build.sh verbose ${architecture} ${configuration}${crossCompile}")
491 Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
492 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
493 Utilities.addArchival(newBuildJob, "bin/Product/**")
497 // Actual perf testing on the following OSes
498 def throughputOSList = ['Ubuntu16.04']
499 if (architecture == 'arm') {
500 throughputOSList = ['Ubuntu14.04']
502 def throughputOptLevelList = ['full_opt', 'min_opt']
504 def throughputOSOptLevelList = []
506 throughputOSList.each { os ->
507 throughputOptLevelList.each { opt_level ->
508 throughputOSOptLevelList.add("${os}_${opt_level}")
512 throughputOSList.each { os ->
513 throughputOptLevelList.each { opt_level ->
514 def newJob = job(getFullThroughputJobName(project, "${os}_${opt_level}", architecture, isPR)) {
516 def machineLabel = 'ubuntu_1604_clr_perf'
517 if (architecture == 'arm') {
518 machineLabel = 'ubuntu_1404_clr_perf_arm'
524 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
530 stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that will be used to build the full title of a run in Benchview.')
535 stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
538 def osGroup = getOSGroup(os)
539 def runType = isPR ? 'private' : 'rolling'
540 def benchViewName = isPR ? 'coreclr-throughput private \$BenchviewCommitName' : 'coreclr-throughput rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
541 def archString = architecture == 'arm' ? ' --arch=arm' : ''
544 shell("bash ./tests/scripts/perf-prep.sh --throughput${archString}")
545 copyArtifacts(fullBuildJobName) {
546 includePatterns("bin/Product/**")
548 buildNumber('\${PRODUCT_BUILD}')
551 shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
552 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user-email \"dotnet-bot@microsoft.com\"\n" +
553 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
554 shell("""${python} ./tests/scripts/run-throughput-perf.py \\
555 -arch \"${architecture}\" \\
557 -configuration \"${configuration}\" \\
558 -opt_level \"${opt_level}\" \\
559 -clr_root \"\${WORKSPACE}\" \\
560 -assembly_root \"\${WORKSPACE}/Microsoft.Benchview.ThroughputBenchmarks.x64.Windows_NT/lib\" \\
561 -run_type \"${runType}\" \\
562 -benchview_path \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools\"""")
566 // Save machinedata.json to /artifact/bin/ Jenkins dir
567 def archiveSettings = new ArchivalSettings()
568 archiveSettings.addFiles('throughput-*.csv')
569 archiveSettings.addFiles('machinedata.json')
570 archiveSettings.setAlwaysArchive()
571 Utilities.addArchival(newJob, archiveSettings)
573 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
575 // For perf, we need to keep the run results longer
577 // Enable the log rotator
579 artifactDaysToKeep(7)
581 artifactNumToKeep(25)
588 def flowJobTPRunList = throughputOSOptLevelList.collect { os ->
589 "{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullThroughputJobName(project, os, architecture, isPR)}') }"
591 def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_throughput_linux_${architecture}_flow", isPR, '')) {
594 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')
598 // First, build the bits on RHEL7.2
599 b = build(params, '${fullBuildJobName}')
601 // Then, run the perf tests
603 ${flowJobTPRunList.join(",\n ")}
608 Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
609 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
612 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
613 builder.setGithubContext("Linux ${architecture} Throughput Perf Test Flow")
614 builder.triggerOnlyOnComment()
615 builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+throughput\\W+flow.*")
616 builder.triggerForBranch(branch)
617 builder.emitTrigger(newFlowJob)
620 // Set a push trigger
621 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
622 builder.emitTrigger(newFlowJob)
627 // Setup CoreCLR-Scenarios tests
628 [true, false].each { isPR ->
629 ['Windows_NT'].each { os ->
630 ['x64', 'x86'].each { arch ->
631 ['ryujit'].each { jit ->
632 ['full_opt', 'min_opt', 'tiered'].each { opt_level ->
633 def architecture = arch
634 def newJob = job(Utilities.getFullJobName(project, "perf_scenarios_${os}_${arch}_${opt_level}_${jit}", isPR)) {
639 label('windows_server_2016_clr_perf')
642 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
648 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')
653 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '1', 'Size test, one iteration is sufficient')
654 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '1', 'Size test, one iteration is sufficient')
657 def configuration = 'Release'
658 def runType = isPR ? 'private' : 'rolling'
659 def benchViewName = isPR ? 'CoreCLR-Scenarios private %BenchviewCommitName%' : 'CoreCLR-Scenarios rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
660 def uploadString = '-uploadToBenchview'
664 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
665 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
666 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
668 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
669 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
670 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
671 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
672 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
673 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
674 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
675 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
676 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
678 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
680 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"
683 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\Scenario\\JitBench -group CoreCLR-Scenarios")
686 if (opt_level != 'min_opt') {
687 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\Scenario\\JitBench -group CoreCLR-Scenarios -collectionFlags BranchMispredictions+CacheMisses+InstructionRetired")
692 def archiveSettings = new ArchivalSettings()
693 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
694 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
695 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
696 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
697 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
698 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
699 archiveSettings.addFiles('machinedata.json')
700 archiveSettings.setAlwaysArchive()
702 Utilities.addArchival(newJob, archiveSettings)
703 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
707 artifactDaysToKeep(14)
709 artifactNumToKeep(100)
721 if (opt_level == 'min_opt') {
722 opts = '\\W+min_opts'
725 if (jit != 'ryujit') {
729 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
730 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} Performance Scenarios Tests")
731 builder.triggerOnlyOnComment()
732 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}\\W+perf\\W+scenarios.*")
733 builder.triggerForBranch(branch)
734 builder.emitTrigger(newJob)
736 else if (opt_level == 'full_opt') {
737 // Set a push trigger
738 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
739 builder.emitTrigger(newJob)
742 // Set periodic trigger
743 Utilities.addPeriodicTrigger(newJob, '@daily')
751 // Setup size-on-disk test
752 ['Windows_NT'].each { os ->
753 ['x64', 'x86'].each { arch ->
754 def architecture = arch
755 def newJob = job(Utilities.getFullJobName(project, "sizeondisk_${arch}", false)) {
759 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
763 def channel = 'master'
764 def configuration = 'Release'
765 def runType = 'rolling'
766 def benchViewName = 'Dotnet Size on Disk %DATE% %TIME%'
767 def testBin = "%WORKSPACE%\\bin\\tests\\${os}.${architecture}.${configuration}"
768 def coreRoot = "${testBin}\\Tests\\Core_Root"
769 def benchViewTools = "%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools"
772 // Install nuget and get BenchView tools
773 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
774 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
775 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
777 // Generate submission metadata for BenchView
778 // Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
779 // we have to do it all as one statement because cmd is called each time and we lose the set environment variable
780 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
781 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
782 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
783 "py \"${benchViewTools}\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
784 "py \"${benchViewTools}\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
786 // Generate machine data from BenchView
787 batchFile("py \"${benchViewTools}\\machinedata.py\"")
789 // Build CoreCLR and gnerate test layout
790 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
791 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
793 // Run the size on disk benchmark
794 batchFile("\"${coreRoot}\\CoreRun.exe\" \"${testBin}\\sizeondisk\\sodbench\\SoDBench\\SoDBench.exe\" -o \"%WORKSPACE%\\sodbench.csv\" --architecture ${arch} --channel ${channel}")
796 // From sodbench.csv, create measurment.json, then submission.json
797 batchFile("py \"${benchViewTools}\\measurement.py\" csv \"%WORKSPACE%\\sodbench.csv\" --metric \"Size on Disk\" --unit \"bytes\" --better \"desc\"")
798 batchFile("py \"${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}")
800 // If this is a PR, upload submission.json
801 batchFile("py \"${benchViewTools}\\upload.py\" submission.json --container coreclr")
805 Utilities.setMachineAffinity(newJob, "Windows_NT", '20170427-elevated')
807 def archiveSettings = new ArchivalSettings()
808 archiveSettings.addFiles('bin/toArchive/**')
809 archiveSettings.addFiles('machinedata.json')
810 archiveSettings.setAlwaysArchive()
812 Utilities.addArchival(newJob, archiveSettings)
813 Utilities.standardJobSetup(newJob, project, false, "*/${branch}")
815 // Set the cron job here. We run nightly on each flavor, regardless of code changes
816 Utilities.addPeriodicTrigger(newJob, "@daily", true /*always run*/)
820 artifactDaysToKeep(14)
822 artifactNumToKeep(100)
834 // Setup IlLink tests
835 [true, false].each { isPR ->
836 ['Windows_NT'].each { os ->
837 ['x64'].each { arch ->
838 ['ryujit'].each { jit ->
839 ['full_opt'].each { opt_level ->
840 def architecture = arch
841 def newJob = job(Utilities.getFullJobName(project, "perf_illink_${os}_${arch}_${opt_level}_${jit}", isPR)) {
846 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
852 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')
857 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '1', 'Size test, one iteration is sufficient')
858 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '1', 'Size test, one iteration is sufficient')
861 def configuration = 'Release'
862 def runType = isPR ? 'private' : 'rolling'
863 def benchViewName = isPR ? 'CoreCLR-Scenarios private %BenchviewCommitName%' : 'CoreCLR-Scenarios rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
864 def uploadString = '-uploadToBenchview'
868 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
869 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
870 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
872 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
873 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
874 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
875 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
876 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
877 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
878 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
879 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
880 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
882 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
884 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"
887 batchFile("\"%VS140COMNTOOLS%\\..\\..\\VC\\vcvarsall.bat\" x86_amd64 && " +
888 "py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\linkbench\\linkbench -group ILLink -nowarmup")
892 def archiveSettings = new ArchivalSettings()
893 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
894 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
895 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
896 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
897 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
898 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
899 archiveSettings.addFiles('machinedata.json')
900 archiveSettings.setAlwaysArchive()
902 // Set the label (currently we are only measuring size, therefore we are running on VM).
903 Utilities.setMachineAffinity(newJob, "Windows_NT", '20170427-elevated')
904 Utilities.addArchival(newJob, archiveSettings)
905 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
909 artifactDaysToKeep(14)
911 artifactNumToKeep(100)
922 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
923 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} IlLink Tests")
924 builder.triggerOnlyOnComment()
925 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}\\W+illink.*")
926 builder.triggerForBranch(branch)
927 builder.emitTrigger(newJob)
930 // Set a push trigger
931 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
932 builder.emitTrigger(newJob)
940 Utilities.createHelperJob(this, project, branch,
941 "Welcome to the ${project} Perf help",