1 // Import the utility functionality.
3 import jobs.generation.*
5 // The input project name (e.g. dotnet/coreclr)
6 def project = GithubProject
7 // The input branch name (e.g. master)
8 def branch = GithubBranchName
9 def projectFolder = Utilities.getFolderName(project) + '/' + Utilities.getFolderName(branch)
11 // Create a folder for JIT stress jobs and associated folder views
13 Utilities.addStandardFolderView(this, 'jitstress', project)
15 // Create a folder for testing via illink
17 Utilities.addStandardFolderView(this, 'illink', project)
19 def static getOSGroup(def os) {
20 def osGroupMap = ['Ubuntu':'Linux',
22 'Ubuntu16.04': 'Linux',
23 'Ubuntu16.10': 'Linux',
27 'Windows_NT':'Windows_NT',
30 def osGroup = osGroupMap.get(os, null)
31 assert osGroup != null : "Could not find os group for ${os}"
35 // We use this class (vs variables) so that the static functions can access data here.
38 // We have very limited ARM64 hardware (used for ARM/ARMLB/ARM64 testing). So only allow certain branches to use it.
39 def static WindowsArm64Branches = [
42 // Innerloop build OS's
43 // The Windows_NT_BuildOnly OS is a way to speed up the Non-Windows builds by avoiding
44 // test execution in the build flow runs. It generates the exact same build
45 // as Windows_NT but without running the tests.
51 'Windows_NT_BuildOnly',
59 def static crossList = [
67 // This is a set of JIT stress modes combined with the set of variables that
68 // need to be set to actually enable that stress mode. The key of the map is the stress mode and
69 // the values are the environment variables
70 def static jitStressModeScenarios = [
71 'minopts' : ['COMPlus_JITMinOpts' : '1'],
72 'tieredcompilation' : ['COMPlus_EXPERIMENTAL_TieredCompilation' : '1'],
73 'forcerelocs' : ['COMPlus_ForceRelocs' : '1'],
74 'jitstress1' : ['COMPlus_JitStress' : '1'],
75 'jitstress2' : ['COMPlus_JitStress' : '2'],
76 'jitstressregs1' : ['COMPlus_JitStressRegs' : '1'],
77 'jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
78 'jitstressregs3' : ['COMPlus_JitStressRegs' : '3'],
79 'jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
80 'jitstressregs8' : ['COMPlus_JitStressRegs' : '8'],
81 'jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
82 'jitstressregs0x80' : ['COMPlus_JitStressRegs' : '0x80'],
83 'jitstressregs0x1000' : ['COMPlus_JitStressRegs' : '0x1000'],
84 'jitstress2_jitstressregs1' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '1'],
85 'jitstress2_jitstressregs2' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '2'],
86 'jitstress2_jitstressregs3' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '3'],
87 'jitstress2_jitstressregs4' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '4'],
88 'jitstress2_jitstressregs8' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '8'],
89 'jitstress2_jitstressregs0x10' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x10'],
90 'jitstress2_jitstressregs0x80' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x80'],
91 'jitstress2_jitstressregs0x1000' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x1000'],
92 'tailcallstress' : ['COMPlus_TailcallStress' : '1'],
93 'jitsse2only' : ['COMPlus_EnableAVX' : '0', 'COMPlus_EnableSSE3_4' : '0'],
94 'jitnosimd' : ['COMPlus_FeatureSIMD' : '0'],
95 'jitincompletehwintrinsic' : ['COMPlus_EnableIncompleteISAClass' : '1'],
96 'jitx86hwintrinsicnoavx' : ['COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX' : '0'], // testing the legacy SSE encoding
97 'jitx86hwintrinsicnoavx2' : ['COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX2' : '0'], // testing SNB/IVB
98 'jitx86hwintrinsicnosimd' : ['COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_FeatureSIMD' : '0'], // match "jitnosimd", may need to remove after decoupling HW intrinsic from FeatureSIMD
99 'jitnox86hwintrinsic' : ['COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableSSE' : '0' , 'COMPlus_EnableSSE2' : '0' , 'COMPlus_EnableSSE3' : '0' , 'COMPlus_EnableSSSE3' : '0' , 'COMPlus_EnableSSE41' : '0' , 'COMPlus_EnableSSE42' : '0' , 'COMPlus_EnableAVX' : '0' , 'COMPlus_EnableAVX2' : '0' , 'COMPlus_EnableAES' : '0' , 'COMPlus_EnableBMI1' : '0' , 'COMPlus_EnableBMI2' : '0' , 'COMPlus_EnableFMA' : '0' , 'COMPlus_EnableLZCNT' : '0' , 'COMPlus_EnablePCLMULQDQ' : '0' , 'COMPlus_EnablePOPCNT' : '0'],
100 'corefx_baseline' : [ : ], // corefx baseline
101 'corefx_minopts' : ['COMPlus_JITMinOpts' : '1'],
102 'corefx_tieredcompilation' : ['COMPlus_EXPERIMENTAL_TieredCompilation' : '1'],
103 'corefx_jitstress1' : ['COMPlus_JitStress' : '1'],
104 'corefx_jitstress2' : ['COMPlus_JitStress' : '2'],
105 'corefx_jitstressregs1' : ['COMPlus_JitStressRegs' : '1'],
106 'corefx_jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
107 'corefx_jitstressregs3' : ['COMPlus_JitStressRegs' : '3'],
108 'corefx_jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
109 'corefx_jitstressregs8' : ['COMPlus_JitStressRegs' : '8'],
110 'corefx_jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
111 'corefx_jitstressregs0x80' : ['COMPlus_JitStressRegs' : '0x80'],
112 'corefx_jitstressregs0x1000' : ['COMPlus_JitStressRegs' : '0x1000'],
113 'gcstress0x3' : ['COMPlus_GCStress' : '0x3'],
114 'gcstress0xc' : ['COMPlus_GCStress' : '0xC'],
115 'zapdisable' : ['COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
116 'heapverify1' : ['COMPlus_HeapVerify' : '1'],
117 'gcstress0xc_zapdisable' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
118 'gcstress0xc_zapdisable_jitstress2' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_JitStress' : '2'],
119 'gcstress0xc_zapdisable_heapverify1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_HeapVerify' : '1'],
120 'gcstress0xc_jitstress1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '1'],
121 'gcstress0xc_jitstress2' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '2'],
122 'gcstress0xc_minopts_heapverify1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JITMinOpts' : '1', 'COMPlus_HeapVerify' : '1']
125 // This is a set of ReadyToRun stress scenarios
126 def static r2rStressScenarios = [
127 'r2r_jitstress1' : ["COMPlus_JitStress": "1"],
128 'r2r_jitstress2' : ["COMPlus_JitStress": "2"],
129 'r2r_jitstressregs1' : ["COMPlus_JitStressRegs": "1"],
130 'r2r_jitstressregs2' : ["COMPlus_JitStressRegs": "2"],
131 'r2r_jitstressregs3' : ["COMPlus_JitStressRegs": "3"],
132 'r2r_jitstressregs4' : ["COMPlus_JitStressRegs": "4"],
133 'r2r_jitstressregs8' : ["COMPlus_JitStressRegs": "8"],
134 'r2r_jitstressregs0x10' : ["COMPlus_JitStressRegs": "0x10"],
135 'r2r_jitstressregs0x80' : ["COMPlus_JitStressRegs": "0x80"],
136 'r2r_jitstressregs0x1000' : ["COMPlus_JitStressRegs": "0x1000"],
137 'r2r_jitminopts' : ["COMPlus_JITMinOpts": "1"],
138 'r2r_jitforcerelocs' : ["COMPlus_ForceRelocs": "1"],
139 'r2r_gcstress15' : ["COMPlus_GCStress": "0xF"]
142 // This is the basic set of scenarios
143 def static basicScenarios = [
151 // 'jitdiff', // jitdiff is currently disabled, until someone spends the effort to make it fully work
153 'gc_reliability_framework',
156 def static allScenarios = basicScenarios + r2rStressScenarios.keySet() + jitStressModeScenarios.keySet()
158 // Valid PR trigger combinations.
159 def static prTriggeredValidInnerLoopCombos = [
178 'Windows_NT_BuildOnly': [
215 // A set of scenarios that are valid for arm/arm64/armlb tests run on hardware. This is a map from valid scenario name
216 // to Tests.lst file categories to exclude.
218 // This list should contain a subset of the scenarios from `allScenarios`. Please keep this in the same order as that,
219 // and with the same values, with some commented out, for easier maintenance.
221 // Note that some scenarios that are commented out should be enabled, but haven't yet been.
223 def static validArmWindowsScenarios = [
227 'r2r': ["R2R_FAIL", "R2R_EXCLUDE"],
233 // 'gc_reliability_framework'
235 'r2r_jitstress1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
236 'r2r_jitstress2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
237 'r2r_jitstressregs1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
238 'r2r_jitstressregs2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
239 'r2r_jitstressregs3': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
240 'r2r_jitstressregs4': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
241 'r2r_jitstressregs8': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
242 'r2r_jitstressregs0x10': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
243 'r2r_jitstressregs0x80': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
244 'r2r_jitstressregs0x1000': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
245 'r2r_jitminopts': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
246 'r2r_jitforcerelocs': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
247 'r2r_gcstress15': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
248 'minopts': ["MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
249 'tieredcompilation': [],
251 'jitstress1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
252 'jitstress2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
253 'jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
254 'jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
255 'jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
256 'jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
257 'jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
258 'jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
259 'jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
260 'jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
261 'jitstress2_jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
262 'jitstress2_jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
263 'jitstress2_jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
264 'jitstress2_jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
265 'jitstress2_jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
266 'jitstress2_jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
267 'jitstress2_jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
268 'jitstress2_jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
269 'tailcallstress': ["TAILCALLSTRESS_FAIL", "TAILCALLSTRESS_EXCLUDE"],
270 // 'jitsse2only' // Only relevant to xarch
271 'jitnosimd': [], // Only interesting on platforms where SIMD support exists.
272 // 'jitincompletehwintrinsic'
273 // 'jitx86hwintrinsicnoavx'
274 // 'jitx86hwintrinsicnoavx2'
275 // 'jitx86hwintrinsicnosimd'
276 // 'jitnox86hwintrinsic'
277 'corefx_baseline': [], // corefx tests don't use smarty
278 'corefx_minopts': [], // corefx tests don't use smarty
279 'corefx_tieredcompilation': [], // corefx tests don't use smarty
280 'corefx_jitstress1': [], // corefx tests don't use smarty
281 'corefx_jitstress2': [], // corefx tests don't use smarty
282 'corefx_jitstressregs1': [], // corefx tests don't use smarty
283 'corefx_jitstressregs2': [], // corefx tests don't use smarty
284 'corefx_jitstressregs3': [], // corefx tests don't use smarty
285 'corefx_jitstressregs4': [], // corefx tests don't use smarty
286 'corefx_jitstressregs8': [], // corefx tests don't use smarty
287 'corefx_jitstressregs0x10': [], // corefx tests don't use smarty
288 'corefx_jitstressregs0x80': [], // corefx tests don't use smarty
289 'corefx_jitstressregs0x1000': [], // corefx tests don't use smarty
290 'gcstress0x3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
291 'gcstress0xc': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
292 'zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
294 'gcstress0xc_zapdisable': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
295 'gcstress0xc_zapdisable_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
296 'gcstress0xc_zapdisable_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
297 'gcstress0xc_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
298 'gcstress0xc_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
299 'gcstress0xc_minopts_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
302 // NOTE: the following scenarios are not defined in the 'allScenarios' list! Is this a bug?
305 'minopts_zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
306 'gcstress0x3_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
307 'gcstress0x3_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
308 'gcstress0x3_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
309 'gcstress0x3_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
310 'gcstress0x3_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
311 'gcstress0x3_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
312 'gcstress0x3_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
313 'gcstress0x3_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
314 'gcstress0x3_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
315 'gcstress0x3_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
316 'gcstress0xc_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
317 'gcstress0xc_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
318 'gcstress0xc_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
319 'gcstress0xc_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
320 'gcstress0xc_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
321 'gcstress0xc_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
322 'gcstress0xc_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
323 'gcstress0xc_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"]
326 def static validLinuxArm64Scenarios = [
334 def static validLinuxArmScenarios = [
340 'r2r_jitstressregs1',
341 'r2r_jitstressregs2',
342 'r2r_jitstressregs3',
343 'r2r_jitstressregs4',
344 'r2r_jitstressregs8',
345 'r2r_jitstressregs0x10',
346 'r2r_jitstressregs0x80',
347 'r2r_jitstressregs0x1000',
349 'r2r_jitforcerelocs',
362 'jitstressregs0x1000',
363 'jitstress2_jitstressregs1',
364 'jitstress2_jitstressregs2',
365 'jitstress2_jitstressregs3',
366 'jitstress2_jitstressregs4',
367 'jitstress2_jitstressregs8',
368 'jitstress2_jitstressregs0x10',
369 'jitstress2_jitstressregs0x80',
370 'jitstress2_jitstressregs0x1000',
376 'gcstress0xc_zapdisable',
377 'gcstress0xc_zapdisable_jitstress2',
378 'gcstress0xc_zapdisable_heapverify1',
379 'gcstress0xc_jitstress1',
380 'gcstress0xc_jitstress2',
381 'gcstress0xc_minopts_heapverify1'
384 def static configurationList = ['Debug', 'Checked', 'Release']
386 // This is the set of architectures
387 // Some of these are pseudo-architectures:
388 // armlb -- same as arm, but use the LEGACY_BACKEND JIT
389 // armem -- ARM builds/runs using an emulator. Used for Ubuntu/Ubuntu16.04/Tizen runs.
390 // x86_arm_altjit -- ARM runs on x86 using the ARM altjit
391 // x64_arm64_altjit -- ARM64 runs on x64 using the ARM64 altjit
392 def static architectureList = ['arm', 'armlb', 'armem', 'x86_arm_altjit', 'x64_arm64_altjit', 'arm64', 'x64', 'x86']
394 // This set of architectures that cross build on Windows and run on Windows ARM64 hardware.
395 def static armWindowsCrossArchitectureList = ['arm', 'armlb', 'arm64']
398 // **************************************************************
399 // Create some specific views
401 // These aren't using the Utilities.addStandardFolderView() function, because that creates
402 // views based on a single regular expression. These views will be generated by adding a
403 // specific set of jobs to them.
405 // Utilities.addStandardFolderView() also creates a lot of additional stuff around the
406 // view, like "Build Statistics", "Job Statistics", "Unstable Jobs". Until it is determined
407 // those are required, don't add them (which simplifies the view pages, as well).
408 // **************************************************************
411 def static MergeJobView = null
412 def static PeriodicJobView = null
413 def static ArchitectureViews = [:]
414 def static OSViews = [:]
417 // MergeJobView: include all jobs that execute when a PR change is merged.
418 Views.MergeJobView = listView('Merge') {
431 // PeriodicJobView: include all jobs that execute on a schedule
432 Views.PeriodicJobView = listView('Periodic') {
445 // Create a view for non-PR jobs for each architecture.
446 Constants.architectureList.each { architecture ->
447 Views.ArchitectureViews[architecture] = listView(architecture) {
461 // Create a view for non-PR jobs for each OS.
462 Constants.osList.each { os ->
463 // Don't create one for the special 'Windows_NT_BuildOnly'
464 if (os == 'Windows_NT_BuildOnly') {
467 Views.OSViews[os] = listView(os) {
481 def static addToMergeView(def job) {
482 Views.MergeJobView.with {
489 def static addToPeriodicView(def job) {
490 Views.PeriodicJobView.with {
497 def static addToViews(def job, def isPR, def architecture, def os) {
499 // No views want PR jobs currently.
503 // Add to architecture view.
504 Views.ArchitectureViews[architecture].with {
511 Views.OSViews[os].with {
518 def static addPeriodicTriggerHelper(def job, String cronString, boolean alwaysRuns = false) {
519 addToPeriodicView(job)
520 Utilities.addPeriodicTrigger(job, cronString, alwaysRuns)
523 def static addGithubPushTriggerHelper(def job) {
525 Utilities.addGithubPushTrigger(job)
529 def static setMachineAffinity(def job, def os, def architecture, def options = null) {
530 assert os instanceof String
531 assert architecture instanceof String
533 def armArches = ['arm', 'armlb', 'armem', 'arm64']
534 def supportedArmLinuxOs = ['Ubuntu', 'Ubuntu16.04', 'Tizen']
536 if (!(architecture in armArches)) {
537 assert options == null
538 Utilities.setMachineAffinity(job, os, 'latest-or-auto')
543 // This is an arm(64) job.
545 // There are several options.
549 // Arm32 (Build) -> latest-arm64
550 // |-> os == "Windows_NT" && (architecture == "arm" || architecture == "armlb") && options['use_arm64_build_machine'] == true
551 // Arm32 (Test) -> arm64-windows_nt
552 // |-> os == "Windows_NT" && (architecture == "arm" || architecture == "armlb") && options['use_arm64_build_machine'] == false
554 // Arm64 (Build) -> latest-arm64
555 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == true
556 // Arm64 (Test) -> arm64-windows_nt
557 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == false
561 // Arm32 emulator (Build, Test) -> arm-cross-latest
562 // |-> os in supportedArmLinuxOs && (architecture == "armem")
564 // Arm32 hardware (Flow) -> Ubuntu 16.04 latest-or-auto (don't use limited arm hardware)
565 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_flow_job'] == true
566 // Arm32 hardware (Build) -> Ubuntu 16.04 latest-or-auto
567 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_build_job'] == true
568 // Arm32 hardware (Test) -> ubuntu.1404.arm32.open
569 // |-> os == "Ubuntu" && (architecture == "arm")
571 // Arm64 (Build) -> arm64-cross-latest
572 // |-> os != "Windows_NT" && architecture == "arm64" && options['is_build_only'] == true
573 // Arm64 Small Page Size (Test) -> arm64-small-page-size
574 // |-> os != "Windows_NT" && architecture == "arm64" && options['large_pages'] == false
575 // Arm64 Large Page Size (Test) -> arm64-huge-page-size
576 // |-> os != "Windows_NT" && architecture == "arm64" && options['large_pages'] == true
578 // This has to be a arm arch
579 assert architecture in armArches
580 if (os == "Windows_NT") {
581 // arm32/arm64 Windows jobs share the same machines for now
582 def isBuild = options['use_arm64_build_machine'] == true
584 if (isBuild == true) {
585 Utilities.setMachineAffinity(job, os, 'latest-arm64')
587 Utilities.setMachineAffinity(job, os, 'arm64-windows_nt')
590 assert os != 'Windows_NT'
591 assert os in supportedArmLinuxOs
593 if (architecture == 'arm64') {
594 if ((options != null) && (options['is_build_only'] == true)) {
595 // Arm64 Linux build machine
596 Utilities.setMachineAffinity(job, os, 'arm64-cross-latest')
598 // Arm64 Linux test machines
599 if ((options != null) && (options['large_pages'] == true)) {
600 Utilities.setMachineAffinity(job, os, 'arm64-huge-page-size')
602 Utilities.setMachineAffinity(job, os, 'arm64-small-page-size')
606 else if (architecture == 'armem') {
607 // arm emulator (Ubuntu/Ubuntu16.04/Tizen). Build and test on same machine,
609 Utilities.setMachineAffinity(job, 'Ubuntu', 'arm-cross-latest')
612 // arm Ubuntu on hardware.
613 assert (architecture == 'arm') && (os == 'Ubuntu')
614 def isFlow = (options != null) && (options['is_flow_job'] == true)
615 def isBuild = (options != null) && (options['is_build_job'] == true)
616 if (isFlow || isBuild) {
617 // arm Ubuntu build machine. Build uses docker, so the actual host OS is not
618 // very important. Therefore, use latest or auto. Flow jobs don't need to use
620 Utilities.setMachineAffinity(job, 'Ubuntu16.04', 'latest-or-auto')
622 // arm Ubuntu test machine
623 // There is no tag (like, e.g., "arm-latest") for this, so don't call
624 // Utilities.setMachineAffinity. Just add the machine affinity
625 // manually. We specify the Helix queue name here.
627 label('ubuntu.1404.arm32.open')
634 // setJobMachineAffinity: compute the machine affinity options for a job,
635 // then set the job with those affinity options.
636 def static setJobMachineAffinity(def architecture, def os, def isBuildJob, def isTestJob, def isFlowJob, def job)
638 assert (isBuildJob && !isTestJob && !isFlowJob) ||
639 (!isBuildJob && isTestJob && !isFlowJob) ||
640 (!isBuildJob && !isTestJob && isFlowJob)
642 def affinityOptions = null
643 def affinityArchitecture = architecture
645 if (os == "Windows_NT") {
646 if (architecture in Constants.armWindowsCrossArchitectureList) {
648 affinityOptions = [ "use_arm64_build_machine" : true ]
649 } else if (isTestJob) {
650 affinityOptions = [ "use_arm64_build_machine" : false ]
651 } else if (isFlowJob) {
652 // For the flow jobs set the machine affinity as x64
653 affinityArchitecture = 'x64'
658 if (architecture == 'arm64') {
660 affinityOptions = ['is_build_only': true]
661 } else if (isTestJob) {
662 affinityOptions = [ "large_pages" : false ]
665 else if (architecture == 'arm') {
667 affinityOptions = ['is_build_job': true]
668 } else if (isFlowJob) {
669 affinityOptions = ['is_flow_job': true]
674 setMachineAffinity(job, os, affinityArchitecture, affinityOptions)
677 def static isGCStressRelatedTesting(def scenario) {
678 // The 'r2r_gcstress15' scenario is a basic scenario.
679 // Detect it and make it a GCStress related.
680 if (scenario == 'r2r_gcstress15')
685 def gcStressTestEnvVars = [ 'COMPlus_GCStress', 'COMPlus_ZapDisable', 'COMPlus_HeapVerify']
686 def scenarioName = scenario.toLowerCase()
687 def isGCStressTesting = false
688 Constants.jitStressModeScenarios[scenario].each{ k, v ->
689 if (k in gcStressTestEnvVars) {
690 isGCStressTesting = true;
693 return isGCStressTesting
696 def static isCoreFxScenario(def scenario) {
697 def corefx_prefix = 'corefx_'
698 if (scenario.length() < corefx_prefix.length()) {
701 return scenario.substring(0,corefx_prefix.length()) == corefx_prefix
704 def static isR2RBaselineScenario(def scenario) {
705 return (scenario == 'r2r')
708 def static isR2RStressScenario(def scenario) {
709 return Constants.r2rStressScenarios.containsKey(scenario)
712 def static isR2RScenario(def scenario) {
713 return isR2RBaselineScenario(scenario) || isR2RStressScenario(scenario)
716 def static isJitStressScenario(def scenario) {
717 return Constants.jitStressModeScenarios.containsKey(scenario)
720 def static isLongGc(def scenario) {
721 return (scenario == 'longgc' || scenario == 'gcsimulator')
724 def static isJitDiff(def scenario) {
725 return (scenario == 'jitdiff')
728 def static isGcReliabilityFramework(def scenario) {
729 return (scenario == 'gc_reliability_framework')
732 def static isArmWindowsScenario(def scenario) {
733 return Constants.validArmWindowsScenarios.containsKey(scenario)
736 def static isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly) {
737 if (isBuildOnly == true) {
738 os = 'Windows_NT_BuildOnly'
741 def validOsPrTriggerArchConfigs = Constants.prTriggeredValidInnerLoopCombos[os]
743 if (validOsPrTriggerArchConfigs == null) {
747 if (validOsPrTriggerArchConfigs[architecture] != null) {
748 def validOsPrTriggerConfigs = validOsPrTriggerArchConfigs[architecture]
750 if (!(configuration in validOsPrTriggerConfigs)) {
760 def static setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly) {
761 // 2 hours (120 minutes) is the default timeout
763 def innerLoop = (scenario == "innerloop")
766 // Pri-1 test builds take a long time. Default PR jobs are Pri-0; everything else is Pri-1
767 // (see calculateBuildCommands()). So up the Pri-1 build jobs timeout.
772 // Note that these can only increase, never decrease, the Pri-1 timeout possibly set above.
773 if (isGCStressRelatedTesting(scenario)) {
776 else if (isCoreFxScenario(scenario)) {
779 else if (isJitStressScenario(scenario)) {
782 else if (isR2RBaselineScenario(scenario)) {
785 else if (isLongGc(scenario)) {
788 else if (isJitDiff(scenario)) {
791 else if (isGcReliabilityFramework(scenario)) {
794 else if (architecture == 'armlb' || architecture == 'armem' || architecture == 'arm64') {
798 if (architecture == 'arm') {
799 // ARM32 machines are particularly slow.
804 if (configuration == 'Debug') {
805 // Debug runs can be very slow. Add an hour.
809 if (architecture == 'x86_arm_altjit' || architecture == 'x64_arm64_altjit') {
810 // AltJit runs compile all methods twice.
814 // If we've changed the timeout from the default, set it in the job.
816 if (timeout != 120) {
817 Utilities.setJobTimeout(newJob, timeout)
821 def static getJobFolder(def scenario) {
822 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
825 if (scenario == 'illink') {
831 def static getStressModeDisplayName(def scenario) {
833 Constants.jitStressModeScenarios[scenario].each{ k, v ->
834 def prefixLength = 'COMPlus_'.length()
835 if (k.length() >= prefixLength) {
836 def modeName = k.substring(prefixLength, k.length())
837 displayStr += ' ' + modeName + '=' + v
841 if (isCoreFxScenario(scenario)) {
842 displayStr = ('CoreFx ' + displayStr).trim()
848 def static getR2RDisplayName(def scenario) {
849 // Assume the scenario name is one from the r2rStressScenarios dict, and remove its "r2r_" prefix.
850 def displayStr = scenario
851 def prefixLength = 'r2r_'.length()
852 if (displayStr.length() >= prefixLength) {
853 displayStr = "R2R " + displayStr.substring(prefixLength, displayStr.length())
854 } else if (scenario == 'r2r') {
861 // Functions to create an environment script.
862 // envScriptCreate -- initialize the script (call first)
863 // envScriptFinalize -- finalize the script (call last)
864 // envScriptSetStressModeVariables -- set stress mode variables in the env script
865 // envScriptAppendExistingScript -- append an existing script to the generated script
867 // Each script returns a string of commands. Concatenate all the strings together before
868 // adding them to the builds commands, to make sure they get executed as one Jenkins script.
871 // Initialize the environment setting script.
872 def static envScriptCreate(def os, def stepScriptLocation) {
874 if (os == 'Windows_NT') {
875 stepScript += "echo Creating TestEnv script\r\n"
876 stepScript += "if exist ${stepScriptLocation} del ${stepScriptLocation}\r\n"
878 // Create at least an empty script.
879 stepScript += "echo. > ${stepScriptLocation}\r\n"
882 stepScript += "echo Creating environment setting script\n"
883 stepScript += "echo \\#\\!/usr/bin/env bash > ${stepScriptLocation}\n"
889 // Generates the string for setting stress mode variables.
890 def static envScriptSetStressModeVariables(def os, def stressModeVars, def stepScriptLocation) {
892 if (os == 'Windows_NT') {
893 stressModeVars.each{ k, v ->
894 // Write out what we are writing to the script file
895 stepScript += "echo Setting ${k}=${v}\r\n"
896 // Write out the set itself to the script file`
897 stepScript += "echo set ${k}=${v} >> ${stepScriptLocation}\r\n"
901 stressModeVars.each{ k, v ->
902 // Write out what we are writing to the script file
903 stepScript += "echo Setting ${k}=${v}\n"
904 // Write out the set itself to the script file`
905 stepScript += "echo export ${k}=${v} >> ${stepScriptLocation}\n"
912 // Append an existing script to an environment script.
913 // Returns string of commands to do this.
914 def static envScriptAppendExistingScript(def os, def appendScript, def stepScriptLocation) {
915 assert (os == 'Windows_NT')
918 stepScript += "echo Appending ${appendScript} to ${stepScriptLocation}\r\n"
919 stepScript += "type ${appendScript} >> ${stepScriptLocation}\r\n"
924 // Finalize an environment setting script.
925 // Returns string of commands to do this.
926 def static envScriptFinalize(def os, def stepScriptLocation) {
929 if (os == 'Windows_NT') {
930 // Display the resulting script. This is useful when looking at the output log file.
931 stepScript += "echo Display the total script ${stepScriptLocation}\r\n"
932 stepScript += "type ${stepScriptLocation}\r\n"
935 stepScript += "chmod +x ${stepScriptLocation}\n"
941 def static isNeedDocker(def architecture, def os, def isBuild) {
943 if (architecture == 'x86' && os == 'Ubuntu') {
946 else if (architecture == 'armem') {
949 else if (architecture == 'arm') {
950 if (os == 'Ubuntu') {
956 if (architecture == 'x86' && os == 'Ubuntu') {
963 def static getDockerImageName(def architecture, def os, def isBuild) {
964 // We must change some docker private images to official later
966 if (architecture == 'x86' && os == 'Ubuntu') {
967 return "hseok82/dotnet-buildtools-prereqs:ubuntu-16.04-crossx86-ef0ac75-20175511035548"
969 else if (architecture == 'armem') {
970 if (os == 'Ubuntu') {
971 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180405193556"
973 else if (os == 'Ubuntu16.04') {
974 return "microsoft/dotnet-buildtools-prereqs:ubuntu-16.04-cross-e435274-20180404203310"
976 else if (os == 'Tizen') {
977 return "hqueue/dotnetcore:ubuntu1404_cross_prereqs_v4-tizen_rootfs"
980 else if (architecture == 'arm') {
981 if (os == 'Ubuntu') {
982 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180405193556"
987 if (architecture == 'x86' && os == 'Ubuntu') {
988 return "hseok82/dotnet-buildtools-prereqs:ubuntu1604_x86_test"
991 println("Unknown architecture to use docker: ${architecture} ${os}");
996 // We have a limited amount of some hardware. For these, scale back the periodic testing we do.
997 def static jobRequiresLimitedHardware(def architecture, def os) {
998 if (((architecture == 'arm64') || (architecture == 'arm') || (architecture == 'armlb')) && (os == 'Windows_NT')) {
999 // These test jobs require ARM64 hardware
1002 else if ((architecture == 'arm') && (os == 'Ubuntu')) {
1003 // These test jobs require Linux/arm32 hardware
1011 // Calculates the name of the build job based on some typical parameters.
1013 def static getJobName(def configuration, def architecture, def os, def scenario, def isBuildOnly) {
1014 // If the architecture is x64, do not add that info into the build name.
1015 // Need to change around some systems and other builds to pick up the right builds
1018 def suffix = scenario != 'normal' ? "_${scenario}" : '';
1023 switch (architecture) {
1025 if (scenario == 'normal') {
1026 // For now we leave x64 off of the name for compatibility with other jobs
1027 baseName = configuration.toLowerCase() + '_' + os.toLowerCase()
1029 else if (scenario == 'formatting') {
1030 // we don't care about the configuration for the formatting job. It runs all configs
1031 baseName = architecture.toLowerCase() + '_' + os.toLowerCase()
1034 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1038 if (os.toLowerCase() == "windows_nt") {
1039 // These are cross builds
1040 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1043 // Defaults to a small page size set of machines.
1044 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + "small_page_size"
1048 // These are cross builds
1049 if (os == 'Tizen') {
1051 baseName = 'armel_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1054 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1059 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1062 case 'x86_arm_altjit':
1063 case 'x64_arm64_altjit':
1064 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1067 println("Unknown architecture: ${architecture}");
1072 return baseName + suffix
1075 def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob, def bidailyCrossList) {
1077 // Limited Windows ARM64 hardware is restricted for non-PR triggers to certain branches.
1078 if (os == 'Windows_NT') {
1079 if ((architecture == 'arm64') || (architecture == 'arm') || (architecture == 'armlb')) {
1080 if (!(branch in Constants.WindowsArm64Branches)) {
1086 if ((architecture == 'arm') && (os != 'Windows_NT') && isGCStressRelatedTesting(scenario)) {
1087 // Non-Windows Arm GCStress jobs currently don't get cron or push triggers (until they are functional).
1088 // See https://github.com/dotnet/coreclr/issues/17241.
1097 switch (architecture) {
1100 if (isFlowJob && architecture == 'x86' && os == 'Ubuntu') {
1101 addPeriodicTriggerHelper(job, '@daily')
1103 else if (isFlowJob || os == 'Windows_NT' || !(os in Constants.crossList)) {
1104 addGithubPushTriggerHelper(job)
1108 if (os == 'Windows_NT') {
1109 addGithubPushTriggerHelper(job)
1112 // Currently no push triggers, with limited arm Linux hardware.
1113 // TODO: If we have enough machine capacity, add some arm Linux push triggers.
1114 assert os == 'Ubuntu'
1116 addPeriodicTriggerHelper(job, '@daily')
1122 case 'x86_arm_altjit':
1123 case 'x64_arm64_altjit':
1124 addGithubPushTriggerHelper(job)
1127 // We would normally want a per-push trigger, but with limited hardware we can't keep up
1128 addPeriodicTriggerHelper(job, "H H/4 * * *")
1131 println("Unknown architecture: ${architecture}");
1137 assert !(os in bidailyCrossList)
1138 // r2r gets a push trigger for checked/release
1139 if (configuration == 'Checked' || configuration == 'Release') {
1140 assert (os == 'Windows_NT') || (os in Constants.crossList)
1141 if (architecture == 'x64' && os != 'OSX10.12') {
1142 //Flow jobs should be Windows, Ubuntu, OSX0.12, or CentOS
1143 if (isFlowJob || os == 'Windows_NT') {
1144 addGithubPushTriggerHelper(job)
1146 // OSX10.12 r2r jobs should only run every 12 hours, not daily.
1147 } else if (architecture == 'x64' && os == 'OSX10.12'){
1149 addPeriodicTriggerHelper(job, 'H H/12 * * *')
1152 // For x86, only add per-commit jobs for Windows
1153 else if (architecture == 'x86') {
1154 if (os == 'Windows_NT') {
1155 addGithubPushTriggerHelper(job)
1158 // arm64 r2r jobs should only run daily.
1159 else if (architecture == 'arm64') {
1160 if (os == 'Windows_NT') {
1161 addPeriodicTriggerHelper(job, '@daily')
1166 case 'r2r_jitstress1':
1167 case 'r2r_jitstress2':
1168 case 'r2r_jitstressregs1':
1169 case 'r2r_jitstressregs2':
1170 case 'r2r_jitstressregs3':
1171 case 'r2r_jitstressregs4':
1172 case 'r2r_jitstressregs8':
1173 case 'r2r_jitstressregs0x10':
1174 case 'r2r_jitstressregs0x80':
1175 case 'r2r_jitstressregs0x1000':
1176 case 'r2r_jitminopts':
1177 case 'r2r_jitforcerelocs':
1178 case 'r2r_gcstress15':
1179 assert !(os in bidailyCrossList)
1181 // GCStress=C is currently not supported on OS X
1182 if (os == 'OSX10.12' && isGCStressRelatedTesting(scenario)) {
1186 // GC Stress 15 r2r gets a push trigger for checked/release
1187 if (configuration == 'Checked' || configuration == 'Release') {
1188 assert (os == 'Windows_NT') || (os in Constants.crossList)
1189 if (architecture == 'x64') {
1190 //Flow jobs should be Windows, Ubuntu, OSX10.12, or CentOS
1191 if (isFlowJob || os == 'Windows_NT') {
1192 // Add a weekly periodic trigger
1193 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1196 // For x86, only add per-commit jobs for Windows
1197 else if (architecture == 'x86') {
1198 if (os == 'Windows_NT') {
1199 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1205 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1206 assert configuration == 'Release'
1207 assert architecture == 'x64'
1208 addPeriodicTriggerHelper(job, '@daily')
1209 // TODO: Add once external email sending is available again
1210 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1213 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1214 assert configuration == 'Release'
1215 assert architecture == 'x64'
1216 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1217 // TODO: Add once external email sending is available again
1218 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1220 case 'standalone_gc':
1221 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1222 assert (configuration == 'Release' || configuration == 'Checked')
1223 // TODO: Add once external email sending is available again
1224 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1225 addPeriodicTriggerHelper(job, '@daily')
1227 case 'gc_reliability_framework':
1228 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1229 assert (configuration == 'Release' || configuration == 'Checked')
1230 // Only triggered by phrase.
1233 assert !(os in bidailyCrossList)
1234 // ILASM/ILDASM roundtrip one gets a daily build, and only for release
1235 if (architecture == 'x64' && configuration == 'Release') {
1236 // We don't expect to see a job generated except in these scenarios
1237 assert (os == 'Windows_NT') || (os in Constants.crossList)
1238 if (isFlowJob || os == 'Windows_NT') {
1239 addPeriodicTriggerHelper(job, '@daily')
1244 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1245 assert configuration == 'Checked'
1246 assert (architecture == 'x64' || architecture == 'x86')
1247 addGithubPushTriggerHelper(job)
1250 assert (os == 'Windows_NT' || os == "Ubuntu")
1251 assert architecture == 'x64'
1252 addGithubPushTriggerHelper(job)
1254 case 'jitstressregs1':
1255 case 'jitstressregs2':
1256 case 'jitstressregs3':
1257 case 'jitstressregs4':
1258 case 'jitstressregs8':
1259 case 'jitstressregs0x10':
1260 case 'jitstressregs0x80':
1261 case 'jitstressregs0x1000':
1266 case 'jitstress2_jitstressregs1':
1267 case 'jitstress2_jitstressregs2':
1268 case 'jitstress2_jitstressregs3':
1269 case 'jitstress2_jitstressregs4':
1270 case 'jitstress2_jitstressregs8':
1271 case 'jitstress2_jitstressregs0x10':
1272 case 'jitstress2_jitstressregs0x80':
1273 case 'jitstress2_jitstressregs0x1000':
1274 case 'tailcallstress':
1277 case 'jitnox86hwintrinsic':
1278 case 'jitincompletehwintrinsic':
1279 case 'jitx86hwintrinsicnoavx':
1280 case 'jitx86hwintrinsicnoavx2':
1281 case 'jitx86hwintrinsicnosimd':
1282 case 'corefx_baseline':
1283 case 'corefx_minopts':
1284 case 'corefx_jitstress1':
1285 case 'corefx_jitstress2':
1286 case 'corefx_jitstressregs1':
1287 case 'corefx_jitstressregs2':
1288 case 'corefx_jitstressregs3':
1289 case 'corefx_jitstressregs4':
1290 case 'corefx_jitstressregs8':
1291 case 'corefx_jitstressregs0x10':
1292 case 'corefx_jitstressregs0x80':
1293 case 'corefx_jitstressregs0x1000':
1295 if (os == 'CentOS7.1') {
1298 if (os in bidailyCrossList) {
1301 assert (os == 'Windows_NT') || (os in Constants.crossList)
1302 if (jobRequiresLimitedHardware(architecture, os)) {
1303 addPeriodicTriggerHelper(job, '@weekly')
1306 addPeriodicTriggerHelper(job, '@daily')
1311 if (os == 'CentOS7.1') {
1314 if (os in bidailyCrossList) {
1317 if ((architecture == 'arm64') && (os != 'Windows_NT')) {
1318 // TODO: should we have cron jobs for arm64 Linux GCStress?
1321 assert (os == 'Windows_NT') || (os in Constants.crossList)
1322 addPeriodicTriggerHelper(job, '@weekly')
1325 case 'gcstress0xc_zapdisable':
1326 case 'gcstress0xc_zapdisable_jitstress2':
1327 case 'gcstress0xc_zapdisable_heapverify1':
1328 case 'gcstress0xc_jitstress1':
1329 case 'gcstress0xc_jitstress2':
1330 case 'gcstress0xc_minopts_heapverify1':
1331 if (os == 'CentOS7.1') {
1334 if (os == 'OSX10.12') {
1335 // GCStress=C is currently not supported on OS X
1338 if (os in bidailyCrossList) {
1341 if ((architecture == 'arm64') && (os != 'Windows_NT')) {
1342 // TODO: should we have cron jobs for arm64 Linux GCStress?
1345 assert (os == 'Windows_NT') || (os in Constants.crossList)
1346 addPeriodicTriggerHelper(job, '@weekly')
1350 // Testing on other operating systems TBD
1351 assert (os == 'Windows_NT' || os == 'Ubuntu')
1352 if (architecture == 'x64' || architecture == 'x86') {
1353 if (configuration == 'Checked') {
1354 addPeriodicTriggerHelper(job, '@daily')
1359 case 'tieredcompilation':
1360 case 'corefx_tieredcompilation':
1361 // No periodic jobs just yet, still testing
1365 println("Unknown scenario: ${scenario}");
1372 // **************************
1373 // Define the basic inner loop builds for PR and commit. This is basically just the set
1374 // of coreclr builds over linux/osx 10.12/windows and debug/release/checked. In addition, the windows
1375 // builds will do a couple extra steps.
1376 // **************************
1378 // Adds a trigger for the PR build if one is needed. If isFlowJob is true, then this is the
1379 // flow job that rolls up the build and test for non-windows OS's. // If the job is a windows build only job,
1380 // it's just used for internal builds
1381 // If you add a job with a trigger phrase, please add that phrase to coreclr/Documentation/project-docs/ci-trigger-phrases.md
1382 def static addTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob) {
1383 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1385 if (isWindowsBuildOnlyJob) {
1389 def bidailyCrossList = ['RHEL7.2', 'Debian8.4']
1390 // Non pull request builds.
1392 addNonPRTriggers(job, branch, isPR, architecture, os, configuration, scenario, isFlowJob, isWindowsBuildOnlyJob, bidailyCrossList)
1418 // Pull request builds. Generally these fall into two categories: default triggers and on-demand triggers
1419 // We generally only have a distinct set of default triggers but a bunch of on-demand ones.
1420 def osGroup = getOSGroup(os)
1421 switch (architecture) {
1422 case 'x64': // editor brace matching: {
1423 if (scenario == 'formatting') {
1424 assert configuration == 'Checked'
1425 if (os == 'Windows_NT' || os == 'Ubuntu') {
1426 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Formatting")
1433 // OpenSUSE, Debian & RedHat get trigger phrases for pri 0 build, and pri 1 build & test
1436 if (scenario == 'innerloop') {
1438 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Innerloop Build")
1440 else if (scenario == 'normal') {
1441 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build", "(?i).*test\\W+${os}\\W+${architecture}.*")
1447 assert scenario != 'innerloop'
1448 // Distinguish with the other architectures (arm and x86)
1449 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build", "(?i).*test\\W+${os}\\W+${architecture}.*")
1455 assert scenario != 'innerloop'
1456 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build", "(?i).*test\\W+${os}\\W+.*")
1460 if (scenario == 'illink') {
1461 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} via ILLink", "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1467 // Triggers on the non-flow jobs aren't necessary here
1468 // Corefx testing uses non-flow jobs.
1469 if (!isFlowJob && !isCoreFxScenario(scenario)) {
1474 // PR Triggered jobs. These jobs will run pri0 tests.
1475 if (configuration == 'Checked') {
1476 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Innerloop Build and Test")
1481 // OSX uses checked for default PR tests
1482 if (configuration == 'Checked') {
1484 assert !job.name.contains("centos")
1485 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test", "(?i).*test\\W+${os}\\W+${architecture}\\W+Build and Test.*")
1490 if (configuration == 'Checked') {
1491 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Jit Diff Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
1496 if (configuration == 'Release') {
1497 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
1502 if (configuration == 'Release') {
1503 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Long-Running GC Build & Test", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1508 if (configuration == 'Release') {
1509 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Simulator", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1513 case 'standalone_gc':
1514 if (configuration == 'Release' || configuration == 'Checked') {
1515 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Standalone GC", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1519 case 'gc_reliability_framework':
1520 if (configuration == 'Release' || configuration == 'Checked') {
1521 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Reliability Framework", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1526 if (isJitStressScenario(scenario)) {
1527 def displayStr = getStressModeDisplayName(scenario)
1528 assert (os == 'Windows_NT') || (os in Constants.crossList)
1529 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayStr})",
1530 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1532 else if (isR2RScenario(scenario)) {
1533 if (configuration == 'Release' || configuration == 'Checked') {
1534 def displayStr = getR2RDisplayName(scenario)
1535 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ${displayStr} Build and Test",
1536 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1540 println("Unknown scenario: ${scenario}");
1551 // CentOS uses checked for default PR tests while debug is build only
1552 if (configuration == 'Debug') {
1554 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Innerloop Build")
1557 // Make sure this is a flow job to get build and test.
1558 if (configuration == 'Checked' && isFlowJob) {
1559 assert job.name.contains("flow")
1561 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Innerloop Build and Test")
1566 // Make sure this is a flow job to get build and test.
1567 if (configuration == 'Checked' && isFlowJob) {
1568 assert job.name.contains("flow")
1570 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test", "(?i).*test\\W+${os}\\W+${architecture}\\W+Build and Test.*")
1575 if (isR2RScenario(scenario)) {
1576 if (configuration == 'Release' || configuration == 'Checked') {
1577 def displayStr = getR2RDisplayName(scenario)
1578 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ${displayStr} Build & Test",
1579 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1591 if (configuration == 'Checked' || configuration == 'Release') {
1592 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Innerloop Build and Test")
1597 if (configuration == 'Checked') {
1598 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test", "(?i).*test\\W+${os}\\W+${architecture}\\W+Build and Test.*")
1603 if (configuration == 'Checked') {
1604 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Jit Diff Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
1609 if (configuration == 'Release') {
1610 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
1615 if (configuration == 'Release') {
1616 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Long-Running GC Build & Test", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1621 if (configuration == 'Release') {
1622 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Simulator", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1626 case 'standalone_gc':
1627 if (configuration == 'Release' || configuration == 'Checked') {
1628 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Standalone GC", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1632 case 'gc_reliability_framework':
1633 if (configuration == 'Release' || configuration == 'Checked') {
1634 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Reliability Framework", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
1639 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} via ILLink", "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1643 if (isJitStressScenario(scenario)) {
1644 def displayStr = getStressModeDisplayName(scenario)
1645 assert (os == 'Windows_NT') || (os in Constants.crossList)
1646 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayStr})",
1647 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1649 else if (isR2RScenario(scenario)) {
1650 if (configuration == 'Release' || configuration == 'Checked') {
1651 def displayStr = getR2RDisplayName(scenario)
1652 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ${displayStr} Build & Test",
1653 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1657 println("Unknown scenario: ${scenario}");
1666 println("Unknown os: ${os}");
1673 // editor brace matching: }
1675 case 'armem': // editor brace matching: {
1678 azureVMAgentPostBuildAction {
1679 agentPostBuildAction('Delete agent if the build was not successful (when idle).')
1687 assert scenario != 'innerloop'
1688 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Cross ${configuration} Build",
1689 "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}\\W+Build.*")
1693 architecture = 'armel'
1695 assert scenario != 'innerloop'
1696 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Cross ${configuration} Build",
1697 "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}\\W+Build.*")
1702 // editor brace matching: }
1705 case 'arm': // editor brace matching: {
1707 // Triggers on the non-flow jobs aren't necessary
1712 // Set up a private trigger
1713 def contextString = "${os} ${architecture} Cross ${configuration}"
1714 def triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}"
1715 if (scenario == 'innerloop') {
1716 contextString += " Innerloop"
1717 triggerString += "\\W+Innerloop"
1720 contextString += " ${scenario}"
1721 triggerString += "\\W+${scenario}"
1724 if (configuration == 'Debug') {
1725 contextString += " Build"
1726 triggerString += "\\W+Build"
1728 contextString += " Build and Test"
1729 triggerString += "\\W+Build and Test"
1732 triggerString += ".*"
1736 if (architecture == 'armlb') { // No arm legacy backend testing for Ubuntu
1740 if (scenario == 'innerloop') {
1741 if (configuration == 'Checked') {
1742 Utilities.addGithubPRTriggerForBranch(job, branch, contextString)
1746 Utilities.addGithubPRTriggerForBranch(job, branch, contextString, triggerString)
1751 if (architecture == "armlb") {
1752 // Disable armlb windows jobs
1757 // Only Checked is an innerloop trigger.
1758 if (configuration == 'Checked')
1760 Utilities.addDefaultPrivateGithubPRTriggerForBranch(job, branch, contextString, null, arm64Users)
1764 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
1767 // Stress jobs will use this code path.
1768 if (isArmWindowsScenario(scenario)) {
1769 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
1775 println("NYI os: ${os}");
1780 // editor brace matching: }
1781 case 'arm64': // editor brace matching: {
1782 // Set up a private trigger
1783 def contextString = "${os} ${architecture} Cross ${configuration}"
1784 def triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}"
1786 if (scenario == 'innerloop') {
1787 contextString += " Innerloop"
1788 triggerString += "\\W+Innerloop"
1791 contextString += " ${scenario}"
1792 triggerString += "\\W+${scenario}"
1795 if (configuration == 'Debug') {
1796 contextString += " Build"
1797 triggerString += "\\W+Build"
1799 contextString += " Build and Test"
1800 triggerString += "\\W+Build and Test"
1803 triggerString += ".*"
1810 if (configuration == 'Debug' && !isFlowJob) {
1811 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Cross ${configuration} Innerloop Build")
1816 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test", triggerString)
1819 if (isR2RScenario(scenario)) {
1820 if (configuration == 'Checked' || configuration == 'Release') {
1821 def displayStr = getR2RDisplayName(scenario)
1822 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ${displayStr} Build and Test", triggerString)
1830 // Triggers on the non-flow jobs aren't necessary here
1835 assert isArmWindowsScenario(scenario)
1838 if (configuration == 'Checked') {
1839 Utilities.addDefaultPrivateGithubPRTriggerForBranch(job, branch, contextString, null, arm64Users)
1844 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
1847 // Stress jobs will use this code path.
1848 if (isArmWindowsScenario(scenario)) {
1849 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
1855 println("NYI os: ${os}");
1861 // editor brace matching: }
1862 case 'x86': // editor brace matching: {
1863 assert ((os == 'Windows_NT') || ((os == 'Ubuntu') && isNormalOrInnerloop))
1864 if (os == 'Ubuntu') {
1865 // Triggers on the non-flow jobs aren't necessary here
1870 // on-demand only for ubuntu x86
1871 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build",
1872 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}.*")
1878 if (configuration == 'Checked' || configuration == 'Release') {
1879 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Innerloop Build and Test")
1884 if (configuration == 'Checked') {
1885 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test",
1886 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+Build and Test.*")
1891 if (configuration == 'Release') {
1892 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test",
1893 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1898 if (configuration == 'Release') {
1899 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Long-Running GC Build & Test",
1900 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1905 if (configuration == 'Release') {
1906 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Simulator",
1907 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1911 case 'standalone_gc':
1912 if (configuration == 'Release' || configuration == 'Checked') {
1913 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Standalone GC",
1914 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1919 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} via ILLink", "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1923 if (isJitStressScenario(scenario)) {
1924 def displayStr = getStressModeDisplayName(scenario)
1925 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayStr})",
1926 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1928 else if (isR2RScenario(scenario)) {
1929 if (configuration == 'Release' || configuration == 'Checked') {
1930 def displayStr = getR2RDisplayName(scenario)
1931 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ${displayStr} Build & Test",
1932 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1936 println("Unknown scenario: ${os} ${architecture} ${scenario}");
1944 // editor brace matching: }
1945 case 'x64_arm64_altjit':
1946 case 'x86_arm_altjit': // editor brace matching: {
1947 assert (os == 'Windows_NT')
1950 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test",
1951 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+Build and Test.*")
1954 Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ${scenario}",
1955 "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
1960 // editor brace matching: }
1962 println("Unknown architecture: ${architecture}");
1968 def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR, def architecture, def configuration, def os, def isBuildOnly) {
1969 def buildCommands = []
1970 def osGroup = getOSGroup(os)
1971 def lowerConfiguration = configuration.toLowerCase()
1974 if (scenario == 'innerloop') {
1978 def doCoreFxTesting = isCoreFxScenario(scenario)
1980 // Calculate the build steps, archival, and xunit results
1982 case 'Windows_NT': // editor brace matching: {
1983 switch (architecture) {
1986 case 'x86_arm_altjit':
1987 case 'x64_arm64_altjit':
1988 def arch = architecture
1990 if (architecture == 'x86_arm_altjit') {
1993 else if (architecture == 'x64_arm64_altjit') {
1997 if (scenario == 'formatting') {
1998 buildCommands += "python -u tests\\scripts\\format.py -c %WORKSPACE% -o Windows_NT -a ${arch}"
1999 Utilities.addArchival(newJob, "format.patch", "", true, false)
2003 if (scenario == 'illink') {
2004 buildCommands += "tests\\scripts\\build_illink.cmd clone ${arch}"
2007 // If it is a release build for Windows, ensure PGO is used, else fail the build.
2008 if ((lowerConfiguration == 'release') &&
2009 (scenario in Constants.basicScenarios) &&
2010 (architecture != 'x86_arm_altjit') &&
2011 (architecture != 'x64_arm64_altjit')) {
2013 buildOpts += ' -enforcepgo'
2016 if (doCoreFxTesting) {
2017 buildOpts += ' skiptests';
2019 buildOpts += " -priority=${priority}"
2022 // Set __TestIntermediateDir to something short. If __TestIntermediateDir is already set, build-test.cmd will
2023 // output test binaries to that directory. If it is not set, the binaries are sent to a default directory whose name is about
2024 // 35 characters long.
2026 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts}"
2029 def runtestArguments = ''
2030 def testOpts = 'collectdumps'
2032 if (isR2RScenario(scenario)) {
2034 // If this is a ReadyToRun scenario, pass 'crossgen' or 'crossgenaltjit'
2035 // to cause framework assemblies to be crossgen'ed. Pass 'runcrossgentests'
2036 // to cause the tests to be crossgen'ed.
2038 if ((architecture == 'x86_arm_altjit') || (architecture == 'x64_arm64_altjit')) {
2039 testOpts += ' crossgenaltjit protononjit.dll'
2041 testOpts += ' crossgen'
2044 testOpts += ' runcrossgentests'
2046 else if (scenario == 'jitdiff') {
2047 testOpts += ' jitdisasm crossgen'
2049 else if (scenario == 'ilrt') {
2050 testOpts += ' ilasmroundtrip'
2052 else if (isLongGc(scenario)) {
2053 testOpts += " ${scenario} sequential"
2055 else if (scenario == 'standalone_gc') {
2056 testOpts += ' gcname clrgc.dll'
2058 else if (scenario == 'illink') {
2059 testOpts += " link %WORKSPACE%\\linker\\linker\\bin\\netcore_Release\\netcoreapp2.0\\win10-${arch}\\publish\\illink.exe"
2062 // Default per-test timeout is 10 minutes. For stress modes and Debug scenarios, increase this
2063 // to 30 minutes (30 * 60 * 1000 = 180000). The "timeout" argument to runtest.cmd sets this, by
2064 // taking a timeout value in milliseconds. (Note that it sets the __TestTimeout environment variable,
2065 // which is read by the xunit harness.)
2066 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario) || (lowerConfiguration == 'debug'))
2068 def timeout = 1800000
2069 testOpts += " timeout ${timeout}"
2072 // If we are running a stress mode, we should write out the set of key
2073 // value env pairs to a file at this point and then we'll pass that to runtest.cmd
2075 def envScriptPath = ''
2076 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2077 def buildCommandsStr = ''
2078 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2079 buildCommandsStr += envScriptCreate(os, envScriptPath)
2081 if (isJitStressScenario(scenario)) {
2082 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2084 else if (isR2RStressScenario(scenario)) {
2085 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.r2rStressScenarios[scenario], envScriptPath)
2088 if (architecture == 'x86_arm_altjit') {
2089 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x86_arm_altjit.cmd", envScriptPath)
2091 else if (architecture == 'x64_arm64_altjit') {
2092 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd", envScriptPath)
2095 envScriptFinalize(os, envScriptPath)
2097 // Note that buildCommands is an array of individually executed commands; we want all the commands used to
2098 // create the SetStressModes.bat script to be executed together, hence we accumulate them as strings
2099 // into a single script.
2100 buildCommands += buildCommandsStr
2102 else if (architecture == 'x86_arm_altjit') {
2103 envScriptPath = "%WORKSPACE%\\tests\\x86_arm_altjit.cmd"
2105 else if (architecture == 'x64_arm64_altjit') {
2106 envScriptPath = "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd"
2108 if (envScriptPath != '') {
2109 testOpts += " TestEnv ${envScriptPath}"
2112 runtestArguments = "${lowerConfiguration} ${arch} ${testOpts}"
2114 if (doCoreFxTesting) {
2115 def workspaceRelativeFxRoot = "_/fx"
2116 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2118 buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${arch} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${branch} -env_script ${envScriptPath}"
2120 // Archive and process (only) the test results
2121 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2122 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2124 //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
2125 Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
2126 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
2128 else if (isGcReliabilityFramework(scenario)) {
2129 buildCommands += "tests\\runtest.cmd ${runtestArguments} GenerateLayoutOnly"
2130 buildCommands += "tests\\scripts\\run-gc-reliability-framework.cmd ${arch} ${configuration}"
2133 buildCommands += "tests\\runtest.cmd ${runtestArguments}"
2135 } // end if (!isBuildOnly)
2137 if (!doCoreFxTesting) {
2138 // Run the rest of the build
2139 // Build the mscorlib for the other OS's
2140 buildCommands += "build.cmd ${lowerConfiguration} ${arch} linuxmscorlib"
2141 buildCommands += "build.cmd ${lowerConfiguration} ${arch} osxmscorlib"
2143 if (arch == 'x64') {
2144 buildCommands += "build.cmd ${lowerConfiguration} arm64 linuxmscorlib"
2147 // Zip up the tests directory so that we don't use so much space/time copying
2148 // 10s of thousands of files around.
2149 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${arch}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
2151 if (!isJitStressScenario(scenario)) {
2152 // For Windows, pull full test results and test drops for x86/x64.
2153 // No need to pull for stress mode scenarios (downstream builds use the default scenario)
2154 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2157 if (scenario == 'jitdiff') {
2158 // retrieve jit-dasm output for base commit, and run jit-diff
2160 // if this is a build only job, we want to keep the default (build) artifacts for the flow job
2161 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${arch}.${configuration}/dasm/**")
2166 Utilities.addXUnitDotNETResults(newJob, 'bin/**/TestRun*.xml', true)
2172 assert isArmWindowsScenario(scenario)
2174 def buildArchitecture = 'arm'
2178 // For 'armlb' (the JIT LEGACY_BACKEND architecture for arm), tell build.cmd to use legacy backend for crossgen compilation.
2179 // Legacy backend is not the default JIT; it is an aljit. So, this is a special case.
2180 if (architecture == 'armlb') {
2181 buildOpts += ' -crossgenaltjit legacyjit.dll'
2184 if (doCoreFxTesting) {
2185 // We shouldn't need to build the tests. However, run-corefx-tests.py currently depends on having the restored corefx
2186 // package available, to determine the correct corefx version git commit hash, and we need to build the tests before
2187 // running "tests\\runtest.cmd GenerateLayoutOnly". So build the pri-0 tests to make this happen.
2189 // buildOpts += ' skiptests';
2190 buildOpts += " -priority=0"
2192 buildOpts += " -priority=${priority}"
2195 // This is now a build only job. Do not run tests. Use the flow job.
2196 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${buildArchitecture} ${buildOpts}"
2198 if (doCoreFxTesting) {
2200 assert architecture == 'arm'
2202 // Generate the test layout because it restores the corefx package which allows run-corefx-tests.py
2203 // to determine the correct matching corefx version git commit hash.
2204 buildCommands += "tests\\runtest.cmd ${lowerConfiguration} ${architecture} GenerateLayoutOnly"
2206 // Set the stress mode variables; this is incorporated into the generated CoreFx RunTests.cmd files.
2207 def envScriptPath = ''
2208 def buildCommandsStr = ''
2209 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2210 buildCommandsStr += envScriptCreate(os, envScriptPath)
2211 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2212 envScriptFinalize(os, envScriptPath)
2213 buildCommands += buildCommandsStr
2215 def workspaceRelativeFxRootLinux = "_/fx"
2216 def workspaceRelativeFxRootWin = "_\\fx"
2217 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2219 buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${branch} -env_script ${envScriptPath} -no_run_tests"
2221 // Zip up the CoreFx runtime and tests. We don't need the CoreCLR binaries; they have been copied to the CoreFX tree.
2222 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\testhost\\netcoreapp-Windows_NT-Release-arm', '${workspaceRelativeFxRootWin}\\fxruntime.zip')\"";
2223 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\tests', '${workspaceRelativeFxRootWin}\\fxtests.zip')\"";
2225 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2226 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2228 // Zip up the tests directory so that we don't use so much space/time copying
2229 // 10s of thousands of files around.
2230 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${buildArchitecture}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
2233 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2237 assert isArmWindowsScenario(scenario)
2239 // This is now a build only job. Do not run tests. Use the flow job.
2240 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} toolset_dir C:\\ats2 -priority=${priority}"
2242 // Zip up the tests directory so that we don't use so much space/time copying
2243 // 10s of thousands of files around.
2244 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${architecture}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
2247 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2250 println("Unknown architecture: ${architecture}");
2255 // end case 'Windows_NT'; editor brace matching: }
2264 case 'Fedora24': // editor brace matching: {
2265 switch (architecture) {
2268 if (architecture == 'x86' && os == 'Ubuntu') {
2269 // build and PAL test
2270 def dockerImage = getDockerImageName(architecture, os, true)
2271 buildCommands += "docker run -i --rm -v \${WORKSPACE}:/opt/code -w /opt/code -e ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} ./build.sh ${architecture} cross ${lowerConfiguration}"
2272 dockerImage = getDockerImageName(architecture, os, false)
2273 buildCommands += "docker run -i --rm -v \${WORKSPACE}:/opt/code -w /opt/code ${dockerImage} ./src/pal/tests/palsuite/runpaltests.sh /opt/code/bin/obj/${osGroup}.${architecture}.${configuration} /opt/code/bin/paltestout"
2274 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2275 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2279 if (scenario == 'formatting') {
2280 buildCommands += "python tests/scripts/format.py -c \${WORKSPACE} -o Linux -a ${architecture}"
2281 Utilities.addArchival(newJob, "format.patch", "", true, false)
2285 if (scenario == 'illink') {
2286 assert(os == 'Ubuntu')
2287 buildCommands += "./tests/scripts/build_illink.sh --clone --arch=${architecture}"
2290 if (!doCoreFxTesting) {
2291 // We run pal tests on all OS but generate mscorlib (and thus, nuget packages)
2292 // only on supported OS platforms.
2293 def bootstrapRid = Utilities.getBoostrapPublishRid(os)
2294 def bootstrapRidEnv = bootstrapRid != null ? "__PUBLISH_RID=${bootstrapRid} " : ''
2296 buildCommands += "${bootstrapRidEnv}./build.sh verbose ${lowerConfiguration} ${architecture}"
2297 buildCommands += "src/pal/tests/palsuite/runpaltests.sh \${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration} \${WORKSPACE}/bin/paltestout"
2299 // Basic archiving of the build
2300 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2302 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2305 // Corefx stress testing
2306 assert os == 'Ubuntu'
2307 assert architecture == 'x64'
2308 assert lowerConfiguration == 'checked'
2309 assert isJitStressScenario(scenario)
2312 buildCommands += "./build.sh verbose ${lowerConfiguration} ${architecture}"
2314 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2316 def envScriptCmds = envScriptCreate(os, scriptFileName)
2317 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2318 envScriptCmds += envScriptFinalize(os, scriptFileName)
2319 buildCommands += envScriptCmds
2321 // Build and text corefx
2322 def workspaceRelativeFxRoot = "_/fx"
2323 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRoot}"
2325 buildCommands += "python -u \$WORKSPACE/tests/scripts/run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${branch} -env_script ${scriptFileName}"
2327 // Archive and process (only) the test results
2328 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2329 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2333 if (!doCoreFxTesting) {
2334 buildCommands += "ROOTFS_DIR=/opt/arm64-xenial-rootfs ./build.sh verbose ${lowerConfiguration} ${architecture} cross clang3.8"
2336 // HACK -- Arm64 does not have corefx jobs yet.
2337 buildCommands += "git clone https://github.com/dotnet/corefx fx"
2338 buildCommands += "ROOTFS_DIR=/opt/arm64-xenial-rootfs-corefx ./fx/build-native.sh -release -buildArch=arm64 -- verbose cross clang3.8"
2339 buildCommands += "mkdir ./bin/Product/Linux.arm64.${configuration}/corefxNative"
2340 buildCommands += "cp fx/bin/Linux.arm64.Release/native/* ./bin/Product/Linux.arm64.${configuration}/corefxNative"
2342 // Basic archiving of the build
2343 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2347 // Emulator cross builds for ARM runs on Ubuntu, Ubuntu16.04 and Tizen currently
2348 assert (os == 'Ubuntu') || (os == 'Ubuntu16.04') || (os == 'Tizen')
2350 // default values for Ubuntu
2352 def linuxCodeName = "trusty"
2353 if (os == 'Ubuntu16.04') {
2354 linuxCodeName = "xenial"
2356 else if (os == 'Tizen') {
2358 linuxCodeName = "tizen"
2361 // Unzip the Windows test binaries first. Exit with 0
2362 buildCommands += "unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.x64.${configuration} || exit 0"
2364 // Unpack the corefx binaries
2365 buildCommands += "mkdir ./bin/CoreFxBinDir"
2366 buildCommands += "tar -xf ./bin/build.tar.gz -C ./bin/CoreFxBinDir"
2367 if (os != 'Tizen') {
2368 buildCommands += "chmod a+x ./bin/CoreFxBinDir/corerun"
2370 // Test environment emulation using docker and qemu has some problem to use lttng library.
2371 // We should remove libcoreclrtraceptprovider.so to avoid test hang.
2372 if (os == 'Ubuntu') {
2373 buildCommands += "rm -f -v ./bin/CoreFxBinDir/libcoreclrtraceptprovider.so"
2376 // Call the ARM CI script to cross build and test using docker
2377 buildCommands += """./tests/scripts/arm32_ci_script.sh \\
2380 --linuxCodeName=${linuxCodeName} \\
2381 --buildConfig=${lowerConfiguration} \\
2382 --testRootDir=./bin/tests/Windows_NT.x64.${configuration} \\
2383 --coreFxBinDir=./bin/CoreFxBinDir \\
2384 --testDirFile=./tests/testsRunningInsideARM.txt"""
2386 // Basic archiving of the build, no pal tests
2387 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2390 // Non-Windows ARM cross builds on hardware run on Ubuntu only
2391 assert (os == 'Ubuntu')
2393 // Add some useful information to the log file. Ignore return codes.
2394 buildCommands += "uname -a || true"
2396 // Cross build the Ubuntu/arm product using docker with a docker image that contains the correct
2397 // Ubuntu cross-compilation toolset (running on a Ubuntu x64 host).
2399 def dockerImage = getDockerImageName(architecture, os, true)
2400 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/arm -e CAC_ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} "
2402 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh ${lowerConfiguration} ${architecture} cross crosscomponent"
2404 // Then, using the same docker image, generate the CORE_ROOT layout using build-test.sh to
2405 // download the appropriate CoreFX packages.
2406 // Note that docker should not be necessary here, for the "generatelayoutonly" case, but we use it
2407 // just to be consistent with the "build.sh" case -- so both are run with the same environment.
2409 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2411 // ZIP up for the test job (created in the flow job code):
2412 // (1) the built CORE_ROOT, /home/user/coreclr/bin/tests/Linux.arm.Checked/Tests/Core_Root,
2413 // used by runtest.sh as the "--coreOverlayDir" argument.
2414 // (2) the native parts of the test build: /home/user/coreclr/bin/obj/Linux.arm.Checked/tests,
2415 // used by runtest.sh as the "--testNativeBinDir" argument.
2417 // These commands are assumed to be run from the root of the workspace.
2418 buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.arm.${configuration}/Tests/Core_Root"
2419 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.arm.${configuration}/tests"
2421 Utilities.addArchival(newJob, "coreroot.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2424 println("Unknown architecture: ${architecture}");
2429 // editor brace matching: }
2431 println("Unknown os: ${os}");
2436 return buildCommands
2439 // Determine if we should generate a job for the given parameters. This is for non-flow jobs: either build and test, or build only.
2440 // Returns true if the job should be generated.
2441 def static shouldGenerateJob(def scenario, def isPR, def architecture, def configuration, def os, def isBuildOnly)
2443 // The "innerloop" (Pri-0 testing) scenario is only available as PR triggered.
2444 // All other scenarios do Pri-1 testing.
2445 if (scenario == 'innerloop' && !isPR) {
2449 // Tizen is only supported for armem architecture
2450 if (os == 'Tizen' && architecture != 'armem') {
2454 // Filter based on architecture.
2456 switch (architecture) {
2459 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2464 if ((os != 'Ubuntu') && (os != 'Ubuntu16.04') && (os != 'Tizen')) {
2469 // Do not create armlb jobs
2471 case 'x86_arm_altjit':
2472 case 'x64_arm64_altjit':
2473 if (os != 'Windows_NT') {
2478 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2483 // Everything implemented
2486 println("Unknown architecture: ${architecture}")
2491 // Which (Windows) build only jobs are required?
2493 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
2496 switch (architecture) {
2498 // We use build only jobs for Windows arm cross-compilation corefx testing, so we need to generate builds for that.
2499 if (!isCoreFxScenario(scenario)) {
2505 if (!isNormalOrInnerloop) {
2514 // Filter based on scenario.
2516 if (isJitStressScenario(scenario)) {
2517 if (configuration != 'Checked') {
2521 def isEnabledOS = (os == 'Windows_NT') || (os == 'Ubuntu' && architecture == 'arm') || (os == 'Ubuntu' && isCoreFxScenario(scenario))
2526 switch (architecture) {
2528 case 'x86_arm_altjit':
2529 case 'x64_arm64_altjit':
2533 // x86 ubuntu: no stress modes
2534 if (os == 'Ubuntu') {
2540 // We use build only jobs for Windows arm cross-compilation corefx testing, so we need to generate builds for that.
2541 if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
2547 // arm64, armlb: stress is handled through flow jobs.
2548 // armem: no stress jobs for ARM emulator.
2552 else if (isR2RScenario(scenario)) {
2553 if (os != 'Windows_NT') {
2556 // Stress scenarios only run with Checked builds, not Release (they would work with Debug, but be slow).
2557 if ((configuration != 'Checked') && isR2RStressScenario(scenario)) {
2565 // The ilrt build isn't necessary except for Windows_NT2003. Non-Windows NT uses
2566 // the default scenario build
2567 if (os != 'Windows_NT') {
2571 if (architecture != 'x64') {
2575 if (configuration != 'Release') {
2580 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2583 if (architecture != 'x64') {
2586 if (configuration != 'Checked') {
2592 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2595 if (architecture != 'x64') {
2598 if (configuration != 'Release') {
2602 case 'gc_reliability_framework':
2603 case 'standalone_gc':
2604 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2608 if (architecture != 'x64') {
2612 if (configuration != 'Release' && configuration != 'Checked') {
2616 // We only run Windows and Ubuntu x64 Checked for formatting right now
2618 if (os != 'Windows_NT' && os != 'Ubuntu') {
2621 if (architecture != 'x64') {
2624 if (configuration != 'Checked') {
2629 if (os != 'Windows_NT' && (os != 'Ubuntu' || architecture != 'x64')) {
2632 if (architecture != 'x64' && architecture != 'x86') {
2640 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly)) {
2645 println("Unknown scenario: ${scenario}")
2651 // For altjit, don't do any scenarios that don't change compilation. That is, scenarios that only change
2652 // runtime behavior, not compile-time behavior, are not interesting.
2653 switch (architecture) {
2654 case 'x86_arm_altjit':
2655 case 'x64_arm64_altjit':
2656 if (isGCStressRelatedTesting(scenario)) {
2664 // The job was not filtered out, so we should generate it!
2668 Constants.allScenarios.each { scenario ->
2669 [true, false].each { isPR ->
2670 Constants.architectureList.each { architecture ->
2671 Constants.configurationList.each { configuration ->
2672 Constants.osList.each { os ->
2673 // If the OS is Windows_NT_BuildOnly, set the isBuildOnly flag to true
2674 // and reset the os to Windows_NT
2675 def isBuildOnly = false
2676 if (os == 'Windows_NT_BuildOnly') {
2681 if (!shouldGenerateJob(scenario, isPR, architecture, configuration, os, isBuildOnly)) {
2686 def jobName = getJobName(configuration, architecture, os, scenario, isBuildOnly)
2687 def folderName = getJobFolder(scenario)
2689 // Create the new job
2690 def newJob = job(Utilities.getFullJobName(project, jobName, isPR, folderName)) {}
2691 addToViews(newJob, isPR, architecture, os)
2693 setJobMachineAffinity(architecture, os, true, false, false, newJob) // isBuildJob = true, isTestJob = false, isFlowJob = false
2695 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
2696 addTriggers(newJob, branch, isPR, architecture, os, configuration, scenario, false, isBuildOnly) // isFlowJob==false
2697 setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly)
2699 // Copy Windows build test binaries and corefx build artifacts for Linux cross build for armem.
2700 // We don't use a flow job for this, but we do depend on there being existing builds with these
2701 // artifacts produced.
2702 if (architecture == 'armem' && (os == 'Ubuntu' || os == 'Ubuntu16.04' || os == 'Tizen')) {
2703 // Define the Windows Tests and Corefx build job names
2704 def lowerConfiguration = configuration.toLowerCase()
2705 def WindowsTestsName = projectFolder + '/' +
2706 Utilities.getFullJobName(project,
2707 getJobName(lowerConfiguration, 'x64' , 'windows_nt', 'normal', true),
2709 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' +
2710 Utilities.getFolderName(branch)
2713 def corefx_os = 'linux'
2714 if (os == 'Tizen') {
2719 // Let's use release CoreFX to test checked CoreCLR,
2720 // because we do not generate checked CoreFX in CoreFX CI yet.
2721 def corefx_lowerConfiguration = lowerConfiguration
2722 if (lowerConfiguration == 'checked') {
2723 corefx_lowerConfiguration = 'release'
2726 // Copy the Windows test binaries and the Corefx build binaries
2729 copyArtifacts(WindowsTestsName) {
2730 includePatterns('bin/tests/tests.zip')
2732 latestSuccessful(true)
2735 copyArtifacts("${corefxFolder}/${corefx_os}_${arm_abi}_cross_${corefx_lowerConfiguration}") {
2736 includePatterns('bin/build.tar.gz')
2738 latestSuccessful(true)
2745 def buildCommands = calculateBuildCommands(newJob, scenario, branch, isPR, architecture, configuration, os, isBuildOnly)
2749 if (os == 'Windows_NT') {
2750 buildCommands.each { buildCommand ->
2751 batchFile(buildCommand)
2755 buildCommands.each { buildCommand ->
2768 // Create a Windows ARM/ARMLB/ARM64 test job that will be used by a flow job.
2769 // Returns the newly created job.
2770 def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
2772 def osGroup = getOSGroup(os)
2773 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
2775 def jobFolder = getJobFolder(scenario)
2776 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
2778 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
2782 // Set up the copies
2784 // Coreclr build we are trying to test
2786 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
2788 copyArtifacts(inputCoreCLRBuildName) {
2789 excludePatterns('**/testResults.xml', '**/*.ni.dll')
2791 buildNumber('${CORECLR_BUILD}')
2795 if (isCoreFxScenario(scenario)) {
2797 // Only arm supported for corefx testing now.
2798 assert architecture == 'arm'
2800 // Unzip CoreFx runtime
2801 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxruntime.zip', '_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-arm')")
2803 // Unzip CoreFx tests.
2804 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxtests.zip', '_\\fx\\bin\\tests')")
2806 // Add the script to run the corefx tests
2807 def corefx_runtime_path = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-arm"
2808 def corefx_tests_dir = "%WORKSPACE%\\_\\fx\\bin\\tests"
2809 def corefx_exclusion_file = "%WORKSPACE%\\tests\\arm\\corefx_test_exclusions.txt"
2810 batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file}")
2812 } else { // !isCoreFxScenario(scenario)
2815 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('bin\\tests\\tests.zip', 'bin\\tests\\${osGroup}.${architecture}.${configuration}')")
2817 def buildCommands = ""
2819 def coreRootLocation = "%WORKSPACE%\\bin\\tests\\Windows_NT.${architecture}.${configuration}\\Tests\\Core_Root"
2820 def addEnvVariable = { variable, value -> buildCommands += "set ${variable}=${value}\r\n"}
2821 def addCommand = { cmd -> buildCommands += "${cmd}\r\n"}
2823 // Make sure Command Extensions are enabled. Used so %ERRORLEVEL% is available.
2824 addCommand("SETLOCAL ENABLEEXTENSIONS")
2827 addEnvVariable("CORE_ROOT", coreRootLocation)
2828 addEnvVariable("COMPlus_NoGuiOnAssert", "1")
2829 addEnvVariable("COMPlus_ContinueOnAssert", "0")
2831 // ARM legacy backend; this is an altjit.
2832 if (architecture == 'armlb') {
2833 addEnvVariable("COMPlus_AltJit", "*")
2834 addEnvVariable("COMPlus_AltJitNgen", "*")
2835 addEnvVariable("COMPlus_AltJitName", "legacyjit.dll")
2836 addEnvVariable("COMPlus_AltJitAssertOnNYI", "1")
2839 // If we are running a stress mode, we'll set those variables as well
2840 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2841 def stressValues = null
2842 if (isJitStressScenario(scenario)) {
2843 stressValues = Constants.jitStressModeScenarios[scenario]
2846 stressValues = Constants.r2rStressScenarios[scenario]
2849 stressValues.each { key, value ->
2850 addEnvVariable(key, value)
2854 if (isR2RScenario(scenario)) {
2855 // Crossgen the framework assemblies.
2856 buildCommands += """
2857 @for %%F in (%CORE_ROOT%\\*.dll) do @call :PrecompileAssembly "%CORE_ROOT%" "%%F" %%~nxF
2858 @goto skip_PrecompileAssembly
2861 @REM Skip mscorlib since it is already precompiled.
2862 @if /I "%3" == "mscorlib.dll" exit /b 0
2863 @if /I "%3" == "mscorlib.ni.dll" exit /b 0
2865 "%CORE_ROOT%\\crossgen.exe" /Platform_Assemblies_Paths "%CORE_ROOT%" %2 >nul 2>nul
2866 @if "%errorlevel%" == "-2146230517" (
2867 echo %2 is not a managed assembly.
2868 ) else if "%errorlevel%" == "-2146234344" (
2869 echo %2 is not a managed assembly.
2870 ) else if %errorlevel% neq 0 (
2871 echo Unable to precompile %2
2877 :skip_PrecompileAssembly
2880 // Set RunCrossGen variable to cause test wrappers to invoke their logic to run
2881 // crossgen on tests before running them.
2882 addEnvVariable("RunCrossGen", "true")
2883 } // isR2RScenario(scenario)
2885 // Create the smarty command
2886 def smartyCommand = "C:\\Tools\\Smarty.exe /noecid /noie /workers 9 /inc EXPECTED_PASS "
2887 def addSmartyFlag = { flag -> smartyCommand += flag + " "}
2888 def addExclude = { exclude -> addSmartyFlag("/exc " + exclude)}
2889 def addArchSpecificExclude = { architectureToExclude, exclude -> if (architectureToExclude == "armlb") { addExclude("LEGACYJIT_" + exclude) } else { addExclude(exclude) } }
2891 if (architecture == 'armlb') {
2892 addExclude("LEGACYJIT_FAIL")
2895 // Exclude tests based on scenario.
2896 Constants.validArmWindowsScenarios[scenario].each { excludeTag ->
2897 addArchSpecificExclude(architecture, excludeTag)
2900 // Innerloop jobs run Pri-0 tests; everyone else runs Pri-1.
2901 if (scenario == 'innerloop') {
2905 // Exclude any test marked LONG_RUNNING; these often exceed the standard timeout and fail as a result.
2906 // TODO: We should create a "long running" job that runs these with a longer timeout.
2907 addExclude("LONG_RUNNING")
2909 smartyCommand += "/lstFile Tests.lst"
2911 def testListArch = [
2917 def archLocation = testListArch[architecture]
2919 addCommand("copy %WORKSPACE%\\tests\\${archLocation}\\Tests.lst bin\\tests\\${osGroup}.${architecture}.${configuration}")
2920 addCommand("pushd bin\\tests\\${osGroup}.${architecture}.${configuration}")
2921 addCommand("${smartyCommand}")
2923 // Save the errorlevel from the smarty command to be used as the errorlevel of this batch file.
2924 // However, we also need to remove all the variables that were set during this batch file, so we
2925 // can run the ZIP powershell command (below) in a clean environment. (We can't run the powershell
2926 // command with the COMPlus_AltJit variables set, for example.) To do that, we do ENDLOCAL as well
2927 // as save the current errorlevel on the same line. This works because CMD evaluates the %errorlevel%
2928 // variable expansion (or any variable expansion on the line) BEFORE it executes the ENDLOCAL command.
2929 // Note that the ENDLOCAL also undoes the pushd command, but we add the popd here for clarity.
2930 addCommand("popd & ENDLOCAL & set __save_smarty_errorlevel=%errorlevel%")
2932 // ZIP up the smarty output, no matter what the smarty result.
2933 addCommand("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${architecture}.${configuration}\\Smarty.run.0', '.\\bin\\tests\\${osGroup}.${architecture}.${configuration}\\Smarty.run.0.zip')\"")
2935 addCommand("echo %errorlevel%")
2936 addCommand("dir .\\bin\\tests\\${osGroup}.${architecture}.${configuration}")
2938 // Use the smarty errorlevel as the script errorlevel.
2939 addCommand("exit /b %__save_smarty_errorlevel%")
2941 batchFile(buildCommands)
2942 } // non-corefx testing
2946 if (!isCoreFxScenario(scenario)) {
2947 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0/*.smrt", '', true, false)
2949 // Archive a ZIP file of the entire Smarty.run.0 directory. This is possibly a little too much,
2950 // but there is no easy way to only archive the HTML/TXT files of the failing tests, so we get
2951 // all the passing test info as well. Not necessarily a bad thing, but possibly somewhat large.
2952 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0.zip", '', true, false)
2958 // Create a test job not covered by the "Windows ARM" case that will be used by a flow job.
2959 // E.g., non-Windows tests.
2960 // Returns the newly created job.
2961 def static CreateOtherTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
2963 def isUbuntuArmJob = ((os == "Ubuntu") && (architecture == 'arm')) // ARM Ubuntu running on hardware (not emulator)
2965 def osGroup = getOSGroup(os)
2966 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
2969 def useServerGC = false
2971 // Enable Server GC for Ubuntu PR builds
2972 // REVIEW: why? Does this apply to all architectures? Why only PR?
2973 if (os == 'Ubuntu' && isPR) {
2974 testOpts += ' --useServerGC'
2978 if (isR2RScenario(scenario)) {
2980 testOpts += ' --crossgen --runcrossgentests'
2982 if (scenario == 'r2r_jitstress1') {
2983 testOpts += ' --jitstress=1'
2985 else if (scenario == 'r2r_jitstress2') {
2986 testOpts += ' --jitstress=2'
2988 else if (scenario == 'r2r_jitstressregs1') {
2989 testOpts += ' --jitstressregs=1'
2991 else if (scenario == 'r2r_jitstressregs2') {
2992 testOpts += ' --jitstressregs=2'
2994 else if (scenario == 'r2r_jitstressregs3') {
2995 testOpts += ' --jitstressregs=3'
2997 else if (scenario == 'r2r_jitstressregs4') {
2998 testOpts += ' --jitstressregs=4'
3000 else if (scenario == 'r2r_jitstressregs8') {
3001 testOpts += ' --jitstressregs=8'
3003 else if (scenario == 'r2r_jitstressregs0x10') {
3004 testOpts += ' --jitstressregs=0x10'
3006 else if (scenario == 'r2r_jitstressregs0x80') {
3007 testOpts += ' --jitstressregs=0x80'
3009 else if (scenario == 'r2r_jitstressregs0x1000') {
3010 testOpts += ' --jitstressregs=0x1000'
3012 else if (scenario == 'r2r_jitminopts') {
3013 testOpts += ' --jitminopts'
3015 else if (scenario == 'r2r_jitforcerelocs') {
3016 testOpts += ' --jitforcerelocs'
3018 else if (scenario == 'r2r_gcstress15') {
3019 testOpts += ' --gcstresslevel=0xF'
3022 else if (scenario == 'jitdiff') {
3023 testOpts += ' --jitdisasm --crossgen'
3025 else if (scenario == 'illink') {
3026 testOpts += ' --link=\$WORKSPACE/linker/linker/bin/netcore_Release/netcoreapp2.0/ubuntu-x64/publish/illink'
3028 else if (isLongGc(scenario)) {
3029 // Long GC tests behave very poorly when they are not
3030 // the only test running (many of them allocate until OOM).
3031 testOpts += ' --sequential'
3033 // A note - runtest.sh does have "--long-gc" and "--gcsimulator" options
3034 // for running long GC and GCSimulator tests, respectively. We don't use them
3035 // here because using a playlist file produces much more readable output on the CI machines
3036 // and reduces running time.
3038 // The Long GC playlist contains all of the tests that are
3039 // going to be run. The GCSimulator playlist contains all of
3040 // the GC simulator tests.
3041 if (scenario == 'longgc') {
3042 testOpts += ' --long-gc --playlist=./tests/longRunningGcTests.txt'
3044 else if (scenario == 'gcsimulator') {
3045 testOpts += ' --gcsimulator --playlist=./tests/gcSimulatorTests.txt'
3048 else if (isGcReliabilityFramework(scenario)) {
3049 testOpts += ' --build-overlay-only'
3051 else if (scenario == 'standalone_gc') {
3052 if (osGroup == 'OSX') {
3053 testOpts += ' --gcname=libclrgc.dylib'
3055 else if (osGroup == 'Linux') {
3056 testOpts += ' --gcname=libclrgc.so'
3059 println("Unexpected OS group: ${osGroup} for os ${os}")
3064 def jobFolder = getJobFolder(scenario)
3065 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3067 stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR Windows test binaries from')
3068 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3072 // Set up the copies
3074 // Coreclr build containing the tests and mscorlib
3075 // pri1 jobs still need to copy windows_nt built tests
3076 assert inputTestsBuildName != null
3077 copyArtifacts(inputTestsBuildName) {
3078 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3080 buildNumber('${CORECLR_WINDOWS_BUILD}')
3084 // Coreclr build we are trying to test
3086 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
3088 copyArtifacts(inputCoreCLRBuildName) {
3089 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3091 buildNumber('${CORECLR_BUILD}')
3095 if (isUbuntuArmJob) {
3096 // Add some useful information to the log file. Ignore return codes.
3097 shell("uname -a || true")
3100 if (architecture == 'arm64') {
3101 shell("mkdir -p ./bin/CoreFxBinDir")
3102 shell("cp ./bin/Product/Linux.arm64.${configuration}/corefxNative/* ./bin/CoreFxBinDir")
3103 shell("chmod +x ./bin/Product/Linux.arm64.${configuration}/corerun")
3105 else if (architecture == 'x86') {
3106 shell("mkdir ./bin/CoreFxNative")
3108 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' + Utilities.getFolderName(branch)
3110 copyArtifacts("${corefxFolder}/ubuntu16.04_x86_release") {
3111 includePatterns('bin/build.tar.gz')
3112 targetDirectory('bin/CoreFxNative')
3114 latestSuccessful(true)
3118 shell("tar -xf ./bin/CoreFxNative/bin/build.tar.gz -C ./bin/CoreFxBinDir")
3121 // Unzip the tests first. Exit with 0
3122 shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/${osGroup}.${architecture}.${configuration} || exit 0")
3123 shell("rm -r ./bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root || exit 0")
3125 // For arm Ubuntu (on hardware), we do the "build-test" step on the build machine, not on the test
3126 // machine. The arm Ubuntu test machines do no building -- they have no CLI, for example.
3127 // We should probably do the "generatelayoutonly" step on the build machine for all architectures.
3128 // However, it's believed that perhaps there's an issue with executable permission bits not getting
3129 // copied correctly.
3130 if (isUbuntuArmJob) {
3131 def lowerConfiguration = configuration.toLowerCase()
3132 shell("unzip -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.arm.${configuration}/Tests/Core_Root
3133 shell("unzip -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.arm.${configuration}/tests
3136 shell("./build-test.sh ${architecture} ${configuration} generatelayoutonly")
3139 // Execute the tests
3140 def runDocker = isNeedDocker(architecture, os, false)
3141 def dockerPrefix = ""
3144 def dockerImage = getDockerImageName(architecture, os, false)
3145 dockerPrefix = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} "
3146 dockerCmd = dockerPrefix + "${dockerImage} "
3149 // If we are running a stress mode, we'll set those variables first
3150 if (isJitStressScenario(scenario)) {
3151 def scriptFileName = "\${WORKSPACE}/set_stress_test_env.sh"
3152 def envScriptCmds = envScriptCreate(os, scriptFileName)
3153 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
3154 envScriptCmds += envScriptFinalize(os, scriptFileName)
3155 shell("${envScriptCmds}")
3156 testOpts += " --test-env=${scriptFileName}"
3159 // setup-stress-dependencies.sh, invoked by runtest.sh to download the coredistools package, depends on the "dotnet"
3160 // tool downloaded by the "init-tools.sh" script. However, it only invokes setup-stress-dependencies.sh for x64. The
3161 // coredistools package is used by GCStress on x86 and x64 to disassemble code to determine instruction boundaries.
3162 // On arm/arm64, it is not required as determining instruction boundaries is trivial.
3163 if (isGCStressRelatedTesting(scenario)) {
3164 if (architecture == 'x64') {
3165 shell('./init-tools.sh')
3170 if (isUbuntuArmJob) {
3171 // Use 'runtesttilstable.sh' to rerun failing tests (in sequential mode);
3172 // there are many tests that pass on rerun (currently), and we don't want
3173 // that flakiness to affect overall test job robustness.
3174 runScript = "${dockerCmd}./tests/runtesttilstable.sh"
3176 runScript = "${dockerCmd}./tests/runtest.sh"
3181 --testRootDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}\" \\
3182 --coreOverlayDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root\" \\
3183 --testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
3184 --copyNativeTestBin --limitedDumpGeneration ${testOpts}""")
3186 if (isGcReliabilityFramework(scenario)) {
3187 // runtest.sh doesn't actually execute the reliability framework - do it here.
3190 dockerCmd = dockerPrefix + "-e COMPlus_gcServer=1 ${dockerImage} "
3193 shell("export COMPlus_gcServer=1")
3197 shell("${dockerCmd}./tests/scripts/run-gc-reliability-framework.sh ${architecture} ${configuration}")
3202 // Experimental: If on Ubuntu 14.04, then attempt to pull in crash dump links
3203 if (os in ['Ubuntu']) {
3204 SummaryBuilder summaries = new SummaryBuilder()
3205 summaries.addLinksSummaryFromFile('Crash dumps from this run:', 'dumplings.txt')
3206 summaries.emit(newJob)
3209 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/coreclrtests.*.txt")
3210 Utilities.addXUnitDotNETResults(newJob, '**/coreclrtests.xml')
3215 // Create a test job that will be used by a flow job.
3216 // Returns the newly created job.
3217 def static CreateTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3219 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3222 if (windowsArmJob) {
3223 assert inputTestsBuildName == null
3224 newJob = CreateWindowsArmTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3226 newJob = CreateOtherTestJob(dslFactory, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3229 setJobMachineAffinity(architecture, os, false, true, false, newJob) // isBuildJob = false, isTestJob = true, isFlowJob = false
3231 addToViews(newJob, isPR, architecture, os)
3233 if (scenario == 'jitdiff') {
3234 def osGroup = getOSGroup(os)
3235 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/dasm/**")
3238 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
3239 setJobTimeout(newJob, isPR, architecture, configuration, scenario, false)
3244 // Create a flow job to tie together a build job with the given test job.
3245 // Returns the new flow job.
3246 def static CreateFlowJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def fullTestJobName, def inputCoreCLRBuildName, def inputTestsBuildName)
3248 // Windows CoreCLR build and Linux CoreCLR build (in parallel) ->
3249 // Linux CoreCLR test
3250 def flowJobName = getJobName(configuration, architecture, os, scenario, false) + "_flow"
3251 def jobFolder = getJobFolder(scenario)
3253 def newFlowJob = null
3255 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3256 if (windowsArmJob) {
3258 assert inputTestsBuildName == null
3260 // For Windows arm jobs there is no reason to build a parallel test job.
3261 // The product build supports building and archiving the tests.
3263 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3265 coreclrBuildJob = build(params, '${inputCoreCLRBuildName}')
3267 // And then build the test build
3268 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number], '${fullTestJobName}')
3271 JobReport.Report.addReference(inputCoreCLRBuildName)
3272 JobReport.Report.addReference(fullTestJobName)
3275 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3277 // Build the input jobs in parallel
3279 { coreclrBuildJob = build(params, '${inputCoreCLRBuildName}') },
3280 { windowsBuildJob = build(params, '${inputTestsBuildName}') }
3283 // And then build the test build
3284 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number,
3285 CORECLR_WINDOWS_BUILD: windowsBuildJob.build.number], '${fullTestJobName}')
3288 JobReport.Report.addReference(inputCoreCLRBuildName)
3289 JobReport.Report.addReference(inputTestsBuildName)
3290 JobReport.Report.addReference(fullTestJobName)
3293 addToViews(newFlowJob, isPR, architecture, os)
3295 setJobMachineAffinity(architecture, os, false, false, true, newFlowJob) // isBuildJob = false, isTestJob = false, isFlowJob = true
3297 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
3298 addTriggers(newFlowJob, branch, isPR, architecture, os, configuration, scenario, true, false) // isFlowJob==true, isWindowsBuildOnlyJob==false
3303 // Determine if we should generate a flow job for the given parameters.
3304 // Returns true if the job should be generated.
3305 def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def configuration, def os)
3307 // The "innerloop" (Pri-0 testing) scenario is only available as PR triggered.
3308 // All other scenarios do Pri-1 testing.
3309 if (scenario == 'innerloop' && !isPR) {
3313 // Filter based on OS and architecture.
3315 switch (architecture) {
3317 if (os != "Ubuntu" && os != "Windows_NT") {
3322 if (os != 'Windows_NT') {
3325 // Do not create armlb windows jobs.
3328 if (os != "Ubuntu" && os != "Windows_NT") {
3333 if (os != "Ubuntu") {
3338 if (!(os in Constants.crossList)) {
3341 if (os == "Windows_NT") {
3346 case 'x86_arm_altjit':
3347 case 'x64_arm64_altjit':
3351 println("Unknown architecture: ${architecture}")
3356 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
3358 // Filter based on scenario in OS.
3360 if (os == 'Windows_NT') {
3361 if (!isArmWindowsScenario(scenario)) {
3367 if (architecture == 'arm64') {
3368 if (!(scenario in Constants.validLinuxArm64Scenarios)) {
3372 else if (architecture == 'arm') {
3373 if (!(scenario in Constants.validLinuxArmScenarios)) {
3377 else if (architecture == 'x86') {
3378 // Linux/x86 only want innerloop and default test
3379 if (!isNormalOrInnerloop) {
3385 // For CentOS, we only want Checked/Release builds.
3386 if (os == 'CentOS7.1') {
3387 if (configuration != 'Checked' && configuration != 'Release') {
3390 if (!isNormalOrInnerloop && !isR2RScenario(scenario) && !isJitStressScenario(scenario)) {
3395 // For RedHat and Debian, we only do Release builds.
3396 else if (os == 'RHEL7.2' || os == 'Debian8.4') {
3397 if (configuration != 'Release') {
3400 if (!isNormalOrInnerloop) {
3405 // Next, filter based on scenario.
3407 if (isJitStressScenario(scenario)) {
3408 if (configuration != 'Checked') {
3412 // CoreFx JIT stress tests currently only implemented for Windows ARM.
3413 if (isCoreFxScenario(scenario) && !( (architecture == 'arm') && (os == 'Windows_NT') )) {
3417 else if (isR2RBaselineScenario(scenario)) {
3418 if (configuration != 'Checked' && configuration != 'Release') {
3422 else if (isR2RStressScenario(scenario)) {
3423 if (configuration != 'Checked') {
3433 // Long GC tests take a long time on non-Release builds
3434 // ilrt is also Release only
3435 if (configuration != 'Release') {
3441 if (configuration != 'Checked') {
3446 case 'gc_reliability_framework':
3447 case 'standalone_gc':
3448 if (configuration != 'Release' && configuration != 'Checked') {
3456 if (os != 'Windows_NT' && os != 'Ubuntu') {
3467 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, false)) {
3473 println("Unknown scenario: ${scenario}")
3479 // The job was not filtered out, so we should generate it!
3483 // Create jobs requiring flow jobs. This includes x64 non-Windows, arm/arm64 Ubuntu, and arm/arm64/armlb Windows.
3484 // Note: no armlb non-Windows; we expect to deprecate/remove armlb soon, so don't want to add new testing for it.
3485 Constants.allScenarios.each { scenario ->
3486 [true, false].each { isPR ->
3487 Constants.architectureList.each { architecture ->
3488 Constants.configurationList.each { configuration ->
3489 Constants.osList.each { os ->
3491 if (!shouldGenerateFlowJob(scenario, isPR, architecture, configuration, os)) {
3495 // Figure out the job name of the CoreCLR build the test will depend on.
3497 def inputCoreCLRBuildScenario = scenario == 'innerloop' ? 'innerloop' : 'normal'
3498 def inputCoreCLRBuildIsBuildOnly = false
3499 if (isCoreFxScenario(scenario)) {
3500 // Every CoreFx test depends on its own unique build.
3501 inputCoreCLRBuildScenario = scenario
3502 inputCoreCLRBuildIsBuildOnly = true
3504 def inputCoreCLRFolderName = getJobFolder(inputCoreCLRBuildScenario)
3505 def inputCoreCLRBuildName = projectFolder + '/' +
3506 Utilities.getFullJobName(project, getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, inputCoreCLRBuildIsBuildOnly), isPR, inputCoreCLRFolderName)
3508 // Figure out the name of the build job that the test job will depend on.
3509 // For Windows ARM tests, this is not used, as the CoreCLR build creates the tests. For other
3510 // tests (e.g., Linux ARM), we depend on a Windows build to get the tests.
3512 def inputTestsBuildName = null
3514 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3515 if (!windowsArmJob) {
3516 def testBuildScenario = scenario == 'innerloop' ? 'innerloop' : 'normal'
3518 def inputTestsBuildArch = architecture
3519 if (architecture == "arm64") {
3520 // Use the x64 test build for arm64 unix
3521 inputTestsBuildArch = "x64"
3523 else if (architecture == "arm") {
3524 // Use the x86 test build for arm unix
3525 inputTestsBuildArch = "x86"
3528 def inputTestsBuildIsBuildOnly = true
3530 inputTestsBuildName = projectFolder + '/' +
3531 Utilities.getFullJobName(project, getJobName(configuration, inputTestsBuildArch, 'windows_nt', testBuildScenario, inputTestsBuildIsBuildOnly), isPR)
3534 // =============================================================================================
3535 // Create the test job
3536 // =============================================================================================
3538 def testJob = CreateTestJob(this, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3540 // =============================================================================================
3541 // Create a build flow to join together the build and tests required to run this test.
3542 // =============================================================================================
3544 if (os == 'RHEL7.2' || os == 'Debian8.4') {
3545 // Do not create the flow job for RHEL jobs.
3549 def fullTestJobName = projectFolder + '/' + testJob.name
3550 def flowJob = CreateFlowJob(this, project, branch, architecture, os, configuration, scenario, isPR, fullTestJobName, inputCoreCLRBuildName, inputTestsBuildName)
3558 JobReport.Report.generateJobReport(out)
3560 // Make the call to generate the help job
3561 Utilities.createHelperJob(this, project, branch,
3562 "Welcome to the ${project} Repository", // This is prepended to the help message
3563 "Have a nice day!") // This is appended to the help message. You might put known issues here.
3565 Utilities.addCROSSCheck(this, project, branch)