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')
50 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
56 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')
62 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')
63 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')
68 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')
69 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 def configuration = 'Release'
74 def runType = isPR ? 'private' : 'rolling'
75 def benchViewName = isPR ? 'coreclr private %BenchviewCommitName%' : 'coreclr rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
76 def uploadString = isSmoketest ? '' : '-uploadToBenchview'
81 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
82 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
83 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
84 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
85 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
86 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
87 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
88 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
89 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
90 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
91 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
92 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
94 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
96 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\""
98 // Run with just stopwatch: Profile=Off
99 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\perflab\\Perflab -library")
100 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\Jit\\Performance\\CodeQuality")
102 // Run with the full set of counters enabled: Profile=On
103 if (opt_level != 'min_opt') {
104 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")
105 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\Jit\\Performance\\CodeQuality -collectionFlags default+BranchMispredictions+CacheMisses+InstructionRetired+gcapi")
110 def archiveSettings = new ArchivalSettings()
111 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
112 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
113 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
114 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
115 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
116 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
117 archiveSettings.addFiles('machinedata.json')
118 archiveSettings.setAlwaysArchive()
120 Utilities.addArchival(newJob, archiveSettings)
121 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
125 artifactDaysToKeep(14)
127 artifactNumToKeep(100)
138 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
140 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} CoreCLR Perf Tests Correctness")
143 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} CoreCLR Perf Tests")
146 if (opt_level == 'min_opt') {
147 opts = '\\W+min_opts'
150 if (jit != 'ryujit') {
154 builder.triggerOnlyOnComment()
155 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}\\W+perf.*")
158 builder.triggerForBranch(branch)
159 builder.emitTrigger(newJob)
161 else if (opt_level == 'full_opt') {
162 // Set a push trigger
163 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
164 builder.emitTrigger(newJob)
167 // Set periodic trigger
168 Utilities.addPeriodicTrigger(newJob, '@daily')
177 // Setup throughput perflab tests runs
178 [true, false].each { isPR ->
179 ['Windows_NT'].each { os ->
180 ['x64', 'x86'].each { arch ->
181 ['ryujit'].each { jit ->
182 [true, false].each { pgo_optimized ->
183 ['full_opt', 'min_opt'].each { opt_level ->
184 def architecture = arch
189 if (!pgo_optimized) {
190 pgo_build = " -nopgooptimize"
195 def newJob = job(Utilities.getFullJobName(project, "perf_throughput_perflab_${os}_${arch}_${opt_level}_${jit}_${pgo_string}", isPR)) {
197 label('windows_server_2016_clr_perf')
200 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
206 stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that will be used to build the full title of a run in Benchview.')
210 def configuration = 'Release'
211 def runType = isPR ? 'private' : 'rolling'
212 def benchViewName = isPR ? 'coreclr-throughput private %BenchviewCommitName%' : 'coreclr-throughput rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
216 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
217 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os}\"")
218 batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
219 batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.ThroughputBenchmarks.${architecture}.${os} -Source https://dotnet.myget.org/F/dotnet-core -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
220 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
221 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
222 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
223 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
224 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
225 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"${benchViewName}\" --user-email \"dotnet-bot@microsoft.com\"\n" +
226 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
227 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
228 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}${pgo_build} skiptests")
229 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}")
233 // Save machinedata.json to /artifact/bin/ Jenkins dir
234 def archiveSettings = new ArchivalSettings()
235 archiveSettings.addFiles('throughput-*.csv')
236 archiveSettings.setAlwaysArchive()
237 Utilities.addArchival(newJob, archiveSettings)
239 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
243 if (opt_level == 'min_opt') {
244 opts = '\\W+min_opts'
248 if (jit != 'ryujit') {
254 pgo_trigger = "\\W+nopgo"
258 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
259 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} ${pgo_string} CoreCLR Throughput Perf Tests")
260 builder.triggerOnlyOnComment()
261 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}${pgo_trigger}\\W+throughput.*")
262 builder.triggerForBranch(branch)
263 builder.emitTrigger(newJob)
265 else if (opt_level == 'full_opt' && pgo_optimized) {
266 // Set a push trigger
267 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
268 builder.emitTrigger(newJob)
271 // Set periodic trigger
272 Utilities.addPeriodicTrigger(newJob, '@daily')
281 def static getFullPerfJobName(def project, def os, def arch, def isPR) {
282 return Utilities.getFullJobName(project, "perf_${os}_${arch}", isPR)
285 // Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
286 [true, false].each { isPR ->
287 ['x64'].each { architecture ->
288 def fullBuildJobName = Utilities.getFullJobName(project, "perf_linux_build", isPR)
289 def configuration = 'Release'
291 def crossCompile = ""
293 def python = "python3.5"
295 // Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
296 ['RHEL7.2'].each { os ->
297 def newBuildJob = job(fullBuildJobName) {
299 shell("./build.sh verbose ${architecture} ${configuration}${crossCompile}")
300 shell("./build-test.sh generatelayoutonly ${architecture} ${configuration}${crossLayout}")
303 Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
304 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
305 Utilities.addArchival(newBuildJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so,bin/tests/**", "bin/Product/**/.nuget/**")
309 // Actual perf testing on the following OSes
310 def perfOSList = ['Ubuntu16.04']
312 perfOSList.each { os ->
313 def newJob = job(getFullPerfJobName(project, os, architecture, isPR)) {
315 def machineLabel = 'ubuntu_1604_clr_perf'
320 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
326 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')
331 // Cap the maximum number of iterations to 21.
332 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')
333 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')
334 stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
337 def osGroup = getOSGroup(os)
338 def runType = isPR ? 'private' : 'rolling'
339 def benchViewName = isPR ? 'coreclr private \$BenchviewCommitName' : 'coreclr rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
340 def uploadString = '-uploadToBenchview'
342 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\""
345 shell("./tests/scripts/perf-prep.sh --nocorefx")
346 shell("./init-tools.sh")
347 copyArtifacts(fullBuildJobName) {
348 includePatterns("bin/**")
350 buildNumber('\${PRODUCT_BUILD}')
353 shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
354 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user-email \"dotnet-bot@microsoft.com\"\n" +
355 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
356 shell("""${python} ./tests/scripts/run-xunit-perf.py -testBinLoc bin/tests/Windows_NT.${architecture}.${configuration}/JIT/Performance/CodeQuality ${runXUnitCommonArgs}""")
360 def archiveSettings = new ArchivalSettings()
361 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
362 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
363 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
364 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
365 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
366 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
367 archiveSettings.addFiles('machinedata.json')
368 archiveSettings.setAlwaysArchive()
370 Utilities.addArchival(newJob, archiveSettings)
371 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
373 // For perf, we need to keep the run results longer
375 // Enable the log rotator
377 artifactDaysToKeep(14)
379 artifactNumToKeep(100)
390 def flowJobPerfRunList = perfOSList.collect { os ->
391 "{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullPerfJobName(project, os, architecture, isPR)}') }"
393 def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_linux_${architecture}_flow", isPR, '')) {
396 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')
400 // First, build the bits on RHEL7.2
401 b = build(params, '${fullBuildJobName}')
403 // Then, run the perf tests
405 ${flowJobPerfRunList.join(",\n ")}
410 Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
411 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
414 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
415 builder.setGithubContext("Linux Perf Test Flow")
416 builder.triggerOnlyOnComment()
417 builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+perf\\W+flow.*")
418 builder.triggerForBranch(branch)
419 builder.emitTrigger(newFlowJob)
422 // Set a push trigger
423 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
424 builder.emitTrigger(newFlowJob)
429 def static getDockerImageName(def architecture, def os, def isBuild) {
430 // We must change some docker private images to official later
432 if (architecture == 'arm') {
433 if (os == 'Ubuntu') {
434 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420"
438 println("Unknown architecture to use docker: ${architecture} ${os}");
442 def static getFullThroughputJobName(def project, def os, def arch, def isPR) {
443 return Utilities.getFullJobName(project, "perf_throughput_${os}_${arch}", isPR)
446 // Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
447 [true, false].each { isPR ->
448 ['x64','arm'].each { architecture ->
449 def fullBuildJobName = Utilities.getFullJobName(project, "perf_throughput_linux_${architecture}_build", isPR)
450 def configuration = 'Release'
453 def crossCompile = ""
454 def python = "python3.5"
456 if (architecture == "arm") {
458 def buildCommands = []
459 def newBuildJob = job(fullBuildJobName) {
460 def additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86"
461 def dockerImage = getDockerImageName(architecture, 'Ubuntu', true)
462 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} "
464 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh release ${architecture} cross crosscomponent"
467 buildCommands.each { buildCommand ->
473 azureVMAgentPostBuildAction {
474 agentPostBuildAction('Delete agent after build execution (when idle).')
478 Utilities.setMachineAffinity(newBuildJob, "Ubuntu16.04", 'latest-or-auto')
479 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
480 Utilities.addArchival(newBuildJob, "bin/Product/**")
483 // Build has to happen on RHEL7.2 (that's where we produce the bits we ship)
484 ['RHEL7.2'].each { os ->
485 def newBuildJob = job(fullBuildJobName) {
487 shell("./build.sh verbose ${architecture} ${configuration}${crossCompile}")
490 Utilities.setMachineAffinity(newBuildJob, os, 'latest-or-auto')
491 Utilities.standardJobSetup(newBuildJob, project, isPR, "*/${branch}")
492 Utilities.addArchival(newBuildJob, "bin/Product/**")
496 // Actual perf testing on the following OSes
497 def throughputOSList = ['Ubuntu16.04']
498 if (architecture == 'arm') {
499 throughputOSList = ['Ubuntu14.04']
501 def throughputOptLevelList = ['full_opt', 'min_opt']
503 def throughputOSOptLevelList = []
505 throughputOSList.each { os ->
506 throughputOptLevelList.each { opt_level ->
507 throughputOSOptLevelList.add("${os}_${opt_level}")
511 throughputOSList.each { os ->
512 throughputOptLevelList.each { opt_level ->
513 def newJob = job(getFullThroughputJobName(project, "${os}_${opt_level}", architecture, isPR)) {
515 def machineLabel = 'ubuntu_1604_clr_perf'
516 if (architecture == 'arm') {
517 machineLabel = 'ubuntu_1404_clr_perf_arm'
523 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
529 stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that will be used to build the full title of a run in Benchview.')
534 stringParam('PRODUCT_BUILD', '', 'Build number from which to copy down the CoreCLR Product binaries built for Linux')
537 def osGroup = getOSGroup(os)
538 def runType = isPR ? 'private' : 'rolling'
539 def benchViewName = isPR ? 'coreclr-throughput private \$BenchviewCommitName' : 'coreclr-throughput rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
540 def archString = architecture == 'arm' ? ' --arch=arm' : ''
543 shell("bash ./tests/scripts/perf-prep.sh --throughput${archString}")
544 copyArtifacts(fullBuildJobName) {
545 includePatterns("bin/Product/**")
547 buildNumber('\${PRODUCT_BUILD}')
550 shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
551 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name \" ${benchViewName} \" --user-email \"dotnet-bot@microsoft.com\"\n" +
552 "${python} \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type ${runType}")
553 shell("""${python} ./tests/scripts/run-throughput-perf.py \\
554 -arch \"${architecture}\" \\
556 -configuration \"${configuration}\" \\
557 -opt_level \"${opt_level}\" \\
558 -clr_root \"\${WORKSPACE}\" \\
559 -assembly_root \"\${WORKSPACE}/Microsoft.Benchview.ThroughputBenchmarks.x64.Windows_NT/lib\" \\
560 -run_type \"${runType}\" \\
561 -benchview_path \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools\"""")
565 // Save machinedata.json to /artifact/bin/ Jenkins dir
566 def archiveSettings = new ArchivalSettings()
567 archiveSettings.addFiles('throughput-*.csv')
568 archiveSettings.addFiles('machinedata.json')
569 archiveSettings.setAlwaysArchive()
570 Utilities.addArchival(newJob, archiveSettings)
572 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
574 // For perf, we need to keep the run results longer
576 // Enable the log rotator
578 artifactDaysToKeep(7)
580 artifactNumToKeep(25)
587 def flowJobTPRunList = throughputOSOptLevelList.collect { os ->
588 "{ build(params + [PRODUCT_BUILD: b.build.number], '${getFullThroughputJobName(project, os, architecture, isPR)}') }"
590 def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, "perf_throughput_linux_${architecture}_flow", isPR, '')) {
593 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')
597 // First, build the bits on RHEL7.2
598 b = build(params, '${fullBuildJobName}')
600 // Then, run the perf tests
602 ${flowJobTPRunList.join(",\n ")}
607 Utilities.setMachineAffinity(newFlowJob, 'Windows_NT', 'latest-or-auto')
608 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
611 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
612 builder.setGithubContext("Linux ${architecture} Throughput Perf Test Flow")
613 builder.triggerOnlyOnComment()
614 builder.setCustomTriggerPhrase("(?i).*test\\W+linux\\W+throughput\\W+flow.*")
615 builder.triggerForBranch(branch)
616 builder.emitTrigger(newFlowJob)
619 // Set a push trigger
620 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
621 builder.emitTrigger(newFlowJob)
626 // Setup CoreCLR-Scenarios tests
627 [true, false].each { isPR ->
628 ['Windows_NT'].each { os ->
629 ['x64', 'x86'].each { arch ->
630 ['ryujit'].each { jit ->
631 ['full_opt', 'min_opt', 'tiered'].each { opt_level ->
632 def architecture = arch
633 def newJob = job(Utilities.getFullJobName(project, "perf_scenarios_${os}_${arch}_${opt_level}_${jit}", isPR)) {
638 label('windows_server_2016_clr_perf')
641 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
647 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')
652 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '1', 'Size test, one iteration is sufficient')
653 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '1', 'Size test, one iteration is sufficient')
656 def configuration = 'Release'
657 def runType = isPR ? 'private' : 'rolling'
658 def benchViewName = isPR ? 'CoreCLR-Scenarios private %BenchviewCommitName%' : 'CoreCLR-Scenarios rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
659 def uploadString = '-uploadToBenchview'
663 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
664 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
665 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
667 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
668 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
669 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
670 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
671 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
672 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
673 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
674 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
675 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
677 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
679 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"
682 batchFile("py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\Scenario\\JitBench -group CoreCLR-Scenarios")
685 if (opt_level != 'min_opt') {
686 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")
691 def archiveSettings = new ArchivalSettings()
692 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
693 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
694 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
695 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
696 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
697 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
698 archiveSettings.addFiles('machinedata.json')
699 archiveSettings.setAlwaysArchive()
701 Utilities.addArchival(newJob, archiveSettings)
702 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
706 artifactDaysToKeep(14)
708 artifactNumToKeep(100)
720 if (opt_level == 'min_opt') {
721 opts = '\\W+min_opts'
724 if (jit != 'ryujit') {
728 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
729 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} Performance Scenarios Tests")
730 builder.triggerOnlyOnComment()
731 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}${opts}${jitt}\\W+perf\\W+scenarios.*")
732 builder.triggerForBranch(branch)
733 builder.emitTrigger(newJob)
735 else if (opt_level == 'full_opt') {
736 // Set a push trigger
737 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
738 builder.emitTrigger(newJob)
741 // Set periodic trigger
742 Utilities.addPeriodicTrigger(newJob, '@daily')
750 // Setup size-on-disk test
751 ['Windows_NT'].each { os ->
752 ['x64', 'x86'].each { arch ->
753 def architecture = arch
754 def newJob = job(Utilities.getFullJobName(project, "sizeondisk_${arch}", false)) {
758 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
762 def channel = 'master'
763 def configuration = 'Release'
764 def runType = 'rolling'
765 def benchViewName = 'Dotnet Size on Disk %DATE% %TIME%'
766 def testBin = "%WORKSPACE%\\bin\\tests\\${os}.${architecture}.${configuration}"
767 def coreRoot = "${testBin}\\Tests\\Core_Root"
768 def benchViewTools = "%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools"
771 // Install nuget and get BenchView tools
772 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
773 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
774 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
776 // Generate submission metadata for BenchView
777 // Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
778 // we have to do it all as one statement because cmd is called each time and we lose the set environment variable
779 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
780 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
781 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
782 "py \"${benchViewTools}\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
783 "py \"${benchViewTools}\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
785 // Generate machine data from BenchView
786 batchFile("py \"${benchViewTools}\\machinedata.py\"")
788 // Build CoreCLR and gnerate test layout
789 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
790 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
792 // Run the size on disk benchmark
793 batchFile("\"${coreRoot}\\CoreRun.exe\" \"${testBin}\\sizeondisk\\sodbench\\SoDBench\\SoDBench.exe\" -o \"%WORKSPACE%\\sodbench.csv\" --architecture ${arch} --channel ${channel}")
795 // From sodbench.csv, create measurment.json, then submission.json
796 batchFile("py \"${benchViewTools}\\measurement.py\" csv \"%WORKSPACE%\\sodbench.csv\" --metric \"Size on Disk\" --unit \"bytes\" --better \"desc\"")
797 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}")
799 // If this is a PR, upload submission.json
800 batchFile("py \"${benchViewTools}\\upload.py\" submission.json --container coreclr")
804 Utilities.setMachineAffinity(newJob, "Windows_NT", '20170427-elevated')
806 def archiveSettings = new ArchivalSettings()
807 archiveSettings.addFiles('bin/toArchive/**')
808 archiveSettings.addFiles('machinedata.json')
809 archiveSettings.setAlwaysArchive()
811 Utilities.addArchival(newJob, archiveSettings)
812 Utilities.standardJobSetup(newJob, project, false, "*/${branch}")
814 // Set the cron job here. We run nightly on each flavor, regardless of code changes
815 Utilities.addPeriodicTrigger(newJob, "@daily", true /*always run*/)
819 artifactDaysToKeep(14)
821 artifactNumToKeep(100)
833 // Setup IlLink tests
834 [true, false].each { isPR ->
835 ['Windows_NT'].each { os ->
836 ['x64'].each { arch ->
837 ['ryujit'].each { jit ->
838 ['full_opt'].each { opt_level ->
839 def architecture = arch
840 def newJob = job(Utilities.getFullJobName(project, "perf_illink_${os}_${arch}_${opt_level}_${jit}", isPR)) {
845 string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
851 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')
856 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION', '1', 'Size test, one iteration is sufficient')
857 stringParam('XUNIT_PERFORMANCE_MAX_ITERATION_INNER_SPECIFIED', '1', 'Size test, one iteration is sufficient')
860 def configuration = 'Release'
861 def runType = isPR ? 'private' : 'rolling'
862 def benchViewName = isPR ? 'CoreCLR-Scenarios private %BenchviewCommitName%' : 'CoreCLR-Scenarios rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
863 def uploadString = '-uploadToBenchview'
867 batchFile("powershell -NoProfile wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile \"%WORKSPACE%\\nuget.exe\"")
868 batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
869 batchFile("\"%WORKSPACE%\\nuget.exe\" install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
871 //Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
872 //we have to do it all as one statement because cmd is called each time and we lose the set environment variable
873 batchFile("if \"%GIT_BRANCH:~0,7%\" == \"origin/\" (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%\") else (set \"GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%\")\n" +
874 "set \"BENCHVIEWNAME=${benchViewName}\"\n" +
875 "set \"BENCHVIEWNAME=%BENCHVIEWNAME:\"=\"\"%\"\n" +
876 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name \"%BENCHVIEWNAME%\" --user-email \"dotnet-bot@microsoft.com\"\n" +
877 "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type ${runType}")
878 batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
879 batchFile("set __TestIntermediateDir=int&&build.cmd ${configuration} ${architecture}")
881 batchFile("tests\\runtest.cmd ${configuration} ${architecture} GenerateLayoutOnly")
883 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"
886 batchFile("\"%VS140COMNTOOLS%\\..\\..\\VC\\vcvarsall.bat\" x86_amd64 && " +
887 "py tests\\scripts\\run-xunit-perf.py ${runXUnitPerfCommonArgs} -testBinLoc bin\\tests\\${os}.${architecture}.${configuration}\\performance\\linkbench\\linkbench -group ILLink -nowarmup")
891 def archiveSettings = new ArchivalSettings()
892 archiveSettings.addFiles('bin/sandbox_logs/**/*_log.txt')
893 archiveSettings.addFiles('bin/sandbox_logs/**/*.csv')
894 archiveSettings.addFiles('bin/sandbox_logs/**/*.xml')
895 archiveSettings.addFiles('bin/sandbox_logs/**/*.log')
896 archiveSettings.addFiles('bin/sandbox_logs/**/*.md')
897 archiveSettings.addFiles('bin/sandbox_logs/**/*.etl')
898 archiveSettings.addFiles('machinedata.json')
899 archiveSettings.setAlwaysArchive()
901 // Set the label (currently we are only measuring size, therefore we are running on VM).
902 Utilities.setMachineAffinity(newJob, "Windows_NT", '20170427-elevated')
903 Utilities.addArchival(newJob, archiveSettings)
904 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
908 artifactDaysToKeep(14)
910 artifactNumToKeep(100)
921 TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
922 builder.setGithubContext("${os} ${arch} ${opt_level} ${jit} IlLink Tests")
923 builder.triggerOnlyOnComment()
924 builder.setCustomTriggerPhrase("(?i).*test\\W+${os}\\W+${arch}\\W+illink.*")
925 builder.triggerForBranch(branch)
926 builder.emitTrigger(newJob)
929 // Set a push trigger
930 TriggerBuilder builder = TriggerBuilder.triggerOnCommit()
931 builder.emitTrigger(newJob)
939 Utilities.createHelperJob(this, project, branch,
940 "Welcome to the ${project} Perf help",