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/ARM64 testing). So only allow certain branches to use it.
39 def static LimitedHardwareBranches = [
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_TieredCompilation' : '0', 'COMPlus_JITMinOpts' : '1'],
72 'tieredcompilation' : ['COMPlus_TieredCompilation' : '1'], // this can be removed once tiered compilation is on by default
73 'no_tiered_compilation' : ['COMPlus_TieredCompilation' : '0'],
74 'no_tiered_compilation_innerloop': ['COMPlus_TieredCompilation' : '0'],
75 'forcerelocs' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_ForceRelocs' : '1'],
76 'jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '1'],
77 'jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2'],
78 'jitstress1_tiered' : ['COMPlus_TieredCompilation' : '1', 'COMPlus_JitStress' : '1'],
79 'jitstress2_tiered' : ['COMPlus_TieredCompilation' : '1', 'COMPlus_JitStress' : '2'],
80 'jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '1'],
81 'jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '2'],
82 'jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '3'],
83 'jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '4'],
84 'jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '8'],
85 'jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x10'],
86 'jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x80'],
87 'jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x1000'],
88 'jitstress2_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '1'],
89 'jitstress2_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '2'],
90 'jitstress2_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '3'],
91 'jitstress2_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '4'],
92 'jitstress2_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '8'],
93 'jitstress2_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x10'],
94 'jitstress2_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x80'],
95 'jitstress2_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x1000'],
96 'tailcallstress' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_TailcallStress' : '1'],
97 'jitsse2only' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableAVX' : '0', 'COMPlus_EnableSSE3_4' : '0'],
98 'jitnosimd' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_FeatureSIMD' : '0'],
99 'jitincompletehwintrinsic' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1'],
100 'jitx86hwintrinsicnoavx' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX' : '0'], // testing the legacy SSE encoding
101 'jitx86hwintrinsicnoavx2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX2' : '0'], // testing SNB/IVB
102 'jitx86hwintrinsicnosimd' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_FeatureSIMD' : '0'], // match "jitnosimd", may need to remove after decoupling HW intrinsic from FeatureSIMD
103 'jitnox86hwintrinsic' : ['COMPlus_TieredCompilation' : '0', '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'],
104 'corefx_baseline' : ['COMPlus_TieredCompilation' : '0'], // corefx baseline
105 'corefx_minopts' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JITMinOpts' : '1'],
106 'corefx_tieredcompilation' : ['COMPlus_TieredCompilation' : '1'], // this can be removed once tiered compilation is on by default
107 'corefx_jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '1'],
108 'corefx_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2'],
109 'corefx_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '1'],
110 'corefx_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '2'],
111 'corefx_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '3'],
112 'corefx_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '4'],
113 'corefx_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '8'],
114 'corefx_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x10'],
115 'corefx_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x80'],
116 'corefx_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x1000'],
117 'gcstress0x3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0x3'],
118 'gcstress0xc' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC'],
119 'zapdisable' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
120 'heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_HeapVerify' : '1'],
121 'gcstress0xc_zapdisable' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
122 'gcstress0xc_zapdisable_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_JitStress' : '2'],
123 'gcstress0xc_zapdisable_heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_HeapVerify' : '1'],
124 'gcstress0xc_jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '1'],
125 'gcstress0xc_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '2'],
126 'gcstress0xc_minopts_heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JITMinOpts' : '1', 'COMPlus_HeapVerify' : '1']
129 // This is a set of ReadyToRun stress scenarios
130 def static r2rStressScenarios = [
131 'r2r_jitstress1' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStress": "1"],
132 'r2r_jitstress2' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStress": "2"],
133 'r2r_jitstress1_tiered' : ['COMPlus_TieredCompilation' : '1', "COMPlus_JitStress": "1"],
134 'r2r_jitstress2_tiered' : ['COMPlus_TieredCompilation' : '1', "COMPlus_JitStress": "2"],
135 'r2r_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "1"],
136 'r2r_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "2"],
137 'r2r_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "3"],
138 'r2r_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "4"],
139 'r2r_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "8"],
140 'r2r_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x10"],
141 'r2r_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x80"],
142 'r2r_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x1000"],
143 'r2r_jitminopts' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JITMinOpts": "1"],
144 'r2r_jitforcerelocs' : ['COMPlus_TieredCompilation' : '0', "COMPlus_ForceRelocs": "1"],
145 'r2r_gcstress15' : ['COMPlus_TieredCompilation' : '0', "COMPlus_GCStress": "0xF"],
146 'r2r_no_tiered_compilation' : ['COMPlus_TieredCompilation' : '0'],
149 // This is the basic set of scenarios
150 def static basicScenarios = [
158 // 'jitdiff', // jitdiff is currently disabled, until someone spends the effort to make it fully work
160 'gc_reliability_framework',
164 def static allScenarios = basicScenarios + r2rStressScenarios.keySet() + jitStressModeScenarios.keySet()
166 // Valid PR trigger combinations.
167 def static prTriggeredValidInnerLoopCombos = [
185 'Windows_NT_BuildOnly': [
227 // A set of scenarios that are valid for arm/arm64 tests run on hardware. This is a map from valid scenario name
228 // to Tests.lst file categories to exclude.
230 // This list should contain a subset of the scenarios from `allScenarios`. Please keep this in the same order as that,
231 // and with the same values, with some commented out, for easier maintenance.
233 // Note that some scenarios that are commented out should be enabled, but haven't yet been.
235 def static validArmWindowsScenarios = [
239 'r2r': ["R2R_FAIL", "R2R_EXCLUDE"],
245 // 'gc_reliability_framework'
247 'r2r_jitstress1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
248 'r2r_jitstress2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
249 'r2r_jitstress1_tiered': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
250 'r2r_jitstress2_tiered': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
251 'r2r_jitstressregs1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
252 'r2r_jitstressregs2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
253 'r2r_jitstressregs3': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
254 'r2r_jitstressregs4': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
255 'r2r_jitstressregs8': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
256 'r2r_jitstressregs0x10': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
257 'r2r_jitstressregs0x80': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
258 'r2r_jitstressregs0x1000': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
259 'r2r_jitminopts': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
260 'r2r_jitforcerelocs': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
261 'r2r_gcstress15': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
262 'r2r_no_tiered_compilation': ["R2R_FAIL", "R2R_EXCLUDE"],
263 'minopts': ["MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
264 'tieredcompilation': [],
265 'no_tiered_compilation': [],
266 'no_tiered_compilation_innerloop': [],
268 'jitstress1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
269 'jitstress2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
270 'jitstress1_tiered': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
271 'jitstress2_tiered': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
272 'jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
273 'jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
274 'jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
275 'jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
276 'jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
277 'jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
278 'jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
279 'jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
280 'jitstress2_jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
281 'jitstress2_jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
282 'jitstress2_jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
283 'jitstress2_jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
284 'jitstress2_jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
285 'jitstress2_jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
286 'jitstress2_jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
287 'jitstress2_jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
288 'tailcallstress': ["TAILCALLSTRESS_FAIL", "TAILCALLSTRESS_EXCLUDE"],
289 // 'jitsse2only' // Only relevant to xarch
290 'jitnosimd': [], // Only interesting on platforms where SIMD support exists.
291 // 'jitincompletehwintrinsic'
292 // 'jitx86hwintrinsicnoavx'
293 // 'jitx86hwintrinsicnoavx2'
294 // 'jitx86hwintrinsicnosimd'
295 // 'jitnox86hwintrinsic'
296 'corefx_baseline': [], // corefx tests don't use smarty
297 'corefx_minopts': [], // corefx tests don't use smarty
298 'corefx_tieredcompilation': [], // corefx tests don't use smarty
299 'corefx_jitstress1': [], // corefx tests don't use smarty
300 'corefx_jitstress2': [], // corefx tests don't use smarty
301 'corefx_jitstressregs1': [], // corefx tests don't use smarty
302 'corefx_jitstressregs2': [], // corefx tests don't use smarty
303 'corefx_jitstressregs3': [], // corefx tests don't use smarty
304 'corefx_jitstressregs4': [], // corefx tests don't use smarty
305 'corefx_jitstressregs8': [], // corefx tests don't use smarty
306 'corefx_jitstressregs0x10': [], // corefx tests don't use smarty
307 'corefx_jitstressregs0x80': [], // corefx tests don't use smarty
308 'corefx_jitstressregs0x1000': [], // corefx tests don't use smarty
309 'gcstress0x3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
310 'gcstress0xc': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
311 'zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
313 'gcstress0xc_zapdisable': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
314 'gcstress0xc_zapdisable_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
315 'gcstress0xc_zapdisable_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
316 'gcstress0xc_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
317 'gcstress0xc_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
318 'gcstress0xc_minopts_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
321 // NOTE: the following scenarios are not defined in the 'allScenarios' list! Is this a bug?
324 'minopts_zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
325 'gcstress0x3_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
326 'gcstress0x3_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
327 'gcstress0x3_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
328 'gcstress0x3_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
329 'gcstress0x3_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
330 'gcstress0x3_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
331 'gcstress0x3_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
332 'gcstress0x3_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
333 'gcstress0x3_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
334 'gcstress0x3_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
335 'gcstress0xc_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
336 'gcstress0xc_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
337 'gcstress0xc_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
338 'gcstress0xc_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
339 'gcstress0xc_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
340 'gcstress0xc_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
341 'gcstress0xc_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
342 'gcstress0xc_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"]
345 def static validLinuxArmScenarios = [
355 // 'gc_reliability_framework'
359 'r2r_jitstress1_tiered',
360 'r2r_jitstress2_tiered',
361 'r2r_jitstressregs1',
362 'r2r_jitstressregs2',
363 'r2r_jitstressregs3',
364 'r2r_jitstressregs4',
365 'r2r_jitstressregs8',
366 'r2r_jitstressregs0x10',
367 'r2r_jitstressregs0x80',
368 'r2r_jitstressregs0x1000',
370 'r2r_jitforcerelocs',
372 'r2r_no_tiered_compilation',
375 'no_tiered_compilation',
376 'no_tiered_compilation_innerloop',
389 'jitstressregs0x1000',
390 'jitstress2_jitstressregs1',
391 'jitstress2_jitstressregs2',
392 'jitstress2_jitstressregs3',
393 'jitstress2_jitstressregs4',
394 'jitstress2_jitstressregs8',
395 'jitstress2_jitstressregs0x10',
396 'jitstress2_jitstressregs0x80',
397 'jitstress2_jitstressregs0x1000',
399 // 'jitsse2only' // Only relevant to xarch
400 // 'jitnosimd' // Only interesting on platforms where SIMD support exists.
401 // 'jitincompletehwintrinsic'
402 // 'jitx86hwintrinsicnoavx'
403 // 'jitx86hwintrinsicnoavx2'
404 // 'jitx86hwintrinsicnosimd'
405 // 'jitnox86hwintrinsic'
408 'corefx_tieredcompilation',
411 'corefx_jitstressregs1',
412 'corefx_jitstressregs2',
413 'corefx_jitstressregs3',
414 'corefx_jitstressregs4',
415 'corefx_jitstressregs8',
416 'corefx_jitstressregs0x10',
417 'corefx_jitstressregs0x80',
418 'corefx_jitstressregs0x1000',
423 'gcstress0xc_zapdisable',
424 'gcstress0xc_zapdisable_jitstress2',
425 'gcstress0xc_zapdisable_heapverify1',
426 'gcstress0xc_jitstress1',
427 'gcstress0xc_jitstress2',
428 'gcstress0xc_minopts_heapverify1'
431 def static validLinuxArm64Scenarios = [
441 // 'gc_reliability_framework'
445 'r2r_jitstress1_tiered',
446 'r2r_jitstress2_tiered',
447 'r2r_jitstressregs1',
448 'r2r_jitstressregs2',
449 'r2r_jitstressregs3',
450 'r2r_jitstressregs4',
451 'r2r_jitstressregs8',
452 'r2r_jitstressregs0x10',
453 'r2r_jitstressregs0x80',
454 'r2r_jitstressregs0x1000',
456 'r2r_jitforcerelocs',
472 'jitstressregs0x1000',
473 'jitstress2_jitstressregs1',
474 'jitstress2_jitstressregs2',
475 'jitstress2_jitstressregs3',
476 'jitstress2_jitstressregs4',
477 'jitstress2_jitstressregs8',
478 'jitstress2_jitstressregs0x10',
479 'jitstress2_jitstressregs0x80',
480 'jitstress2_jitstressregs0x1000',
482 // 'jitsse2only' // Only relevant to xarch
483 'jitnosimd', // Only interesting on platforms where SIMD support exists.
484 // 'jitincompletehwintrinsic'
485 // 'jitx86hwintrinsicnoavx'
486 // 'jitx86hwintrinsicnoavx2'
487 // 'jitx86hwintrinsicnosimd'
488 // 'jitnox86hwintrinsic'
491 'corefx_tieredcompilation',
494 'corefx_jitstressregs1',
495 'corefx_jitstressregs2',
496 'corefx_jitstressregs3',
497 'corefx_jitstressregs4',
498 'corefx_jitstressregs8',
499 'corefx_jitstressregs0x10',
500 'corefx_jitstressregs0x80',
501 'corefx_jitstressregs0x1000',
506 'gcstress0xc_zapdisable',
507 'gcstress0xc_zapdisable_jitstress2',
508 'gcstress0xc_zapdisable_heapverify1',
509 'gcstress0xc_jitstress1',
510 'gcstress0xc_jitstress2',
511 'gcstress0xc_minopts_heapverify1'
514 def static configurationList = ['Debug', 'Checked', 'Release']
516 // This is the set of architectures
517 // Some of these are pseudo-architectures:
518 // armem -- ARM builds/runs using an emulator. Used for Tizen runs.
519 // x86_arm_altjit -- ARM runs on x86 using the ARM altjit
520 // x64_arm64_altjit -- ARM64 runs on x64 using the ARM64 altjit
521 def static architectureList = ['arm', 'armem', 'x86_arm_altjit', 'x64_arm64_altjit', 'arm64', 'x64', 'x86']
523 // This set of architectures that cross build on Windows and run on Windows ARM64 hardware.
524 def static armWindowsCrossArchitectureList = ['arm', 'arm64']
527 // **************************************************************
528 // Create some specific views
530 // These aren't using the Utilities.addStandardFolderView() function, because that creates
531 // views based on a single regular expression. These views will be generated by adding a
532 // specific set of jobs to them.
534 // Utilities.addStandardFolderView() also creates a lot of additional stuff around the
535 // view, like "Build Statistics", "Job Statistics", "Unstable Jobs". Until it is determined
536 // those are required, don't add them (which simplifies the view pages, as well).
537 // **************************************************************
540 def static MergeJobView = null
541 def static PeriodicJobView = null
542 def static ArchitectureViews = [:]
543 def static OSViews = [:]
546 // MergeJobView: include all jobs that execute when a PR change is merged.
547 Views.MergeJobView = listView('Merge') {
560 // PeriodicJobView: include all jobs that execute on a schedule
561 Views.PeriodicJobView = listView('Periodic') {
574 // Create a view for non-PR jobs for each architecture.
575 Constants.architectureList.each { architecture ->
576 Views.ArchitectureViews[architecture] = listView(architecture) {
590 // Create a view for non-PR jobs for each OS.
591 Constants.osList.each { os ->
592 // Don't create one for the special 'Windows_NT_BuildOnly'
593 if (os == 'Windows_NT_BuildOnly') {
596 Views.OSViews[os] = listView(os) {
610 def static addToMergeView(def job) {
611 Views.MergeJobView.with {
618 def static addToPeriodicView(def job) {
619 Views.PeriodicJobView.with {
626 def static addToViews(def job, def isPR, def architecture, def os) {
628 // No views want PR jobs currently.
632 // Add to architecture view.
633 Views.ArchitectureViews[architecture].with {
640 Views.OSViews[os].with {
647 def static addPeriodicTriggerHelper(def job, String cronString, boolean alwaysRuns = false) {
648 addToPeriodicView(job)
649 Utilities.addPeriodicTrigger(job, cronString, alwaysRuns)
652 def static addGithubPushTriggerHelper(def job) {
654 Utilities.addGithubPushTrigger(job)
658 def static setMachineAffinity(def job, def os, def architecture, def options = null) {
659 assert os instanceof String
660 assert architecture instanceof String
662 def armArches = ['arm', 'armem', 'arm64']
664 if (!(architecture in armArches)) {
665 assert options == null
666 Utilities.setMachineAffinity(job, os, 'latest-or-auto')
671 // This is an arm(64) job.
673 // There are several options.
677 // Arm32 (Build) -> latest-arm64
678 // |-> os == "Windows_NT" && (architecture == "arm") && options['use_arm64_build_machine'] == true
679 // Arm32 (Test) -> arm64-windows_nt
680 // |-> os == "Windows_NT" && (architecture == "arm") && options['use_arm64_build_machine'] == false
682 // Arm64 (Build) -> latest-arm64
683 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == true
684 // Arm64 (Test) -> arm64-windows_nt
685 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == false
689 // Arm32 emulator (Build, Test) -> arm-cross-latest
690 // |-> os == "Tizen" && (architecture == "armem")
692 // Arm32 hardware (Flow) -> Ubuntu 16.04 latest-or-auto (don't use limited arm hardware)
693 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_flow_job'] == true
694 // Arm32 hardware (Build) -> Ubuntu 16.04 latest-or-auto
695 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_build_job'] == true
696 // Arm32 hardware (Test) -> ubuntu.1404.arm32.open
697 // |-> os == "Ubuntu" && (architecture == "arm")
699 // Arm64 (Build) -> arm64-cross-latest
700 // |-> os != "Windows_NT" && architecture == "arm64" && options['is_build_only'] == true
701 // Arm64 Small Page Size (Test) -> arm64-small-page-size
702 // |-> os != "Windows_NT" && architecture == "arm64" && options['large_pages'] == false
703 // Arm64 Large Page Size (Test) -> arm64-huge-page-size
704 // |-> os != "Windows_NT" && architecture == "arm64" && options['large_pages'] == true
706 // This has to be a arm arch
707 assert architecture in armArches
708 if (os == "Windows_NT") {
709 // arm32/arm64 Windows jobs share the same machines for now
710 def isBuild = options['use_arm64_build_machine'] == true
712 if (isBuild == true) {
713 // Current set of machines with private Windows arm64 toolset:
714 // Utilities.setMachineAffinity(job, os, 'latest-arm64')
716 // New set of machines with public Windows arm64 toolset, coming from Helix:
718 label('Windows.10.Amd64.ClientRS4.DevEx.Open')
721 Utilities.setMachineAffinity(job, os, 'arm64-windows_nt')
724 assert os != 'Windows_NT'
726 if (architecture == 'arm64') {
727 assert os == 'Ubuntu'
728 def isFlow = (options != null) && (options['is_flow_job'] == true)
729 def isBuild = (options != null) && (options['is_build_job'] == true)
730 if (isFlow || isBuild) {
731 // Arm64 Ubuntu build machine. Build uses docker, so the actual host OS is not
732 // very important. Therefore, use latest or auto. Flow jobs don't need to use
734 Utilities.setMachineAffinity(job, 'Ubuntu16.04', 'latest-or-auto')
736 // Arm64 Linux test machines
737 if ((options != null) && (options['large_pages'] == true)) {
738 Utilities.setMachineAffinity(job, os, 'arm64-huge-page-size')
740 Utilities.setMachineAffinity(job, os, 'arm64-small-page-size')
744 else if (architecture == 'armem') {
745 // arm emulator (Tizen). Build and test on same machine,
748 Utilities.setMachineAffinity(job, 'Ubuntu', 'arm-cross-latest')
751 // arm Ubuntu on hardware.
752 assert architecture == 'arm'
753 assert os == 'Ubuntu'
754 def isFlow = (options != null) && (options['is_flow_job'] == true)
755 def isBuild = (options != null) && (options['is_build_job'] == true)
756 if (isFlow || isBuild) {
757 // arm Ubuntu build machine. Build uses docker, so the actual host OS is not
758 // very important. Therefore, use latest or auto. Flow jobs don't need to use
760 Utilities.setMachineAffinity(job, 'Ubuntu16.04', 'latest-or-auto')
762 // arm Ubuntu test machine
763 // There is no tag (like, e.g., "arm-latest") for this, so don't call
764 // Utilities.setMachineAffinity. Just add the machine affinity
765 // manually. We specify the Helix queue name here.
767 label('ubuntu.1404.arm32.open')
774 // setJobMachineAffinity: compute the machine affinity options for a job,
775 // then set the job with those affinity options.
776 def static setJobMachineAffinity(def architecture, def os, def isBuildJob, def isTestJob, def isFlowJob, def job)
778 assert (isBuildJob && !isTestJob && !isFlowJob) ||
779 (!isBuildJob && isTestJob && !isFlowJob) ||
780 (!isBuildJob && !isTestJob && isFlowJob)
782 def affinityOptions = null
783 def affinityArchitecture = architecture
785 if (os == "Windows_NT") {
786 if (architecture in Constants.armWindowsCrossArchitectureList) {
788 affinityOptions = [ "use_arm64_build_machine" : true ]
789 } else if (isTestJob) {
790 affinityOptions = [ "use_arm64_build_machine" : false ]
791 } else if (isFlowJob) {
792 // For the flow jobs set the machine affinity as x64
793 affinityArchitecture = 'x64'
798 if (architecture == 'arm64') {
800 affinityOptions = ['is_build_job': true]
801 } else if (isFlowJob) {
802 affinityOptions = ['is_flow_job': true]
803 } else if (isTestJob) {
804 affinityOptions = [ "large_pages" : false ]
807 else if (architecture == 'arm') {
809 affinityOptions = ['is_build_job': true]
810 } else if (isFlowJob) {
811 affinityOptions = ['is_flow_job': true]
816 setMachineAffinity(job, os, affinityArchitecture, affinityOptions)
819 def static isGCStressRelatedTesting(def scenario) {
820 // The 'r2r_gcstress15' scenario is a basic scenario.
821 // Detect it and make it a GCStress related.
822 if (scenario == 'r2r_gcstress15')
827 def gcStressTestEnvVars = [ 'COMPlus_GCStress', 'COMPlus_ZapDisable', 'COMPlus_HeapVerify']
828 def scenarioName = scenario.toLowerCase()
829 def isGCStressTesting = false
830 Constants.jitStressModeScenarios[scenario].each{ k, v ->
831 if (k in gcStressTestEnvVars) {
832 isGCStressTesting = true;
835 return isGCStressTesting
838 def static isCoreFxScenario(def scenario) {
839 def corefx_prefix = 'corefx_'
840 if (scenario.length() < corefx_prefix.length()) {
843 return scenario.substring(0,corefx_prefix.length()) == corefx_prefix
846 def static isR2RBaselineScenario(def scenario) {
847 return (scenario == 'r2r')
850 def static isR2RStressScenario(def scenario) {
851 return Constants.r2rStressScenarios.containsKey(scenario)
854 def static isR2RScenario(def scenario) {
855 return isR2RBaselineScenario(scenario) || isR2RStressScenario(scenario)
858 def static isJitStressScenario(def scenario) {
859 return Constants.jitStressModeScenarios.containsKey(scenario)
862 def static isLongGc(def scenario) {
863 return (scenario == 'longgc' || scenario == 'gcsimulator')
866 def static isJitDiff(def scenario) {
867 return (scenario == 'jitdiff')
870 def static isGcReliabilityFramework(def scenario) {
871 return (scenario == 'gc_reliability_framework')
874 def static isArmWindowsScenario(def scenario) {
875 return Constants.validArmWindowsScenarios.containsKey(scenario)
878 def static isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly) {
879 if (isBuildOnly == true) {
880 os = 'Windows_NT_BuildOnly'
883 def validOsPrTriggerArchConfigs = Constants.prTriggeredValidInnerLoopCombos[os]
884 if (validOsPrTriggerArchConfigs != null) {
885 def validOsPrTriggerConfigs = validOsPrTriggerArchConfigs[architecture]
886 if (validOsPrTriggerConfigs != null) {
887 if (configuration in validOsPrTriggerConfigs) {
896 // This means the job builds and runs the 'Pri0' test set. This does not mean the job is
897 // scheduled with a default PR trigger despite the correlation being true at the moment.
898 def static isPri0TestScenario(def scenario) {
899 return (scenario == 'innerloop' || scenario == 'no_tiered_compilation_innerloop')
902 def static getFxBranch(def branch) {
903 def fxBranch = branch
904 // Map 'dev/unix_test_workflow' to 'master' so we can test CoreFX jobs in the CoreCLR dev/unix_test_workflow
905 // branch even though CoreFX doesn't have such a branch.
906 if (branch == 'dev/unix_test_workflow') {
912 def static setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly) {
913 // 2 hours (120 minutes) is the default timeout
916 if (!isPri0TestScenario(scenario)) {
917 // Pri-1 test builds take a long time (see calculateBuildCommands()). So up the Pri-1 build jobs timeout.
922 // Note that these can only increase, never decrease, the Pri-1 timeout possibly set above.
923 if (isGCStressRelatedTesting(scenario)) {
926 else if (isCoreFxScenario(scenario)) {
929 else if (isJitStressScenario(scenario)) {
932 else if (isR2RBaselineScenario(scenario)) {
935 else if (isLongGc(scenario)) {
938 else if (isJitDiff(scenario)) {
941 else if (isGcReliabilityFramework(scenario)) {
944 else if (architecture == 'armem' || architecture == 'arm64') {
948 if (architecture == 'arm') {
949 // ARM32 machines are particularly slow.
954 if (configuration == 'Debug') {
955 // Debug runs can be very slow. Add an hour.
959 if (architecture == 'x86_arm_altjit' || architecture == 'x64_arm64_altjit') {
960 // AltJit runs compile all methods twice.
964 // If we've changed the timeout from the default, set it in the job.
966 if (timeout != 120) {
967 Utilities.setJobTimeout(newJob, timeout)
971 def static getJobFolder(def scenario) {
972 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
975 if (scenario == 'illink') {
981 def static getStressModeDisplayName(def scenario) {
983 Constants.jitStressModeScenarios[scenario].each{ k, v ->
984 def prefixLength = 'COMPlus_'.length()
985 if (k.length() >= prefixLength) {
986 def modeName = k.substring(prefixLength, k.length())
987 displayStr += ' ' + modeName + '=' + v
991 if (isCoreFxScenario(scenario)) {
992 displayStr = ('CoreFx ' + displayStr).trim()
998 def static getR2RDisplayName(def scenario) {
999 // Assume the scenario name is one from the r2rStressScenarios dict, and remove its "r2r_" prefix.
1000 def displayStr = scenario
1001 def prefixLength = 'r2r_'.length()
1002 if (displayStr.length() >= prefixLength) {
1003 displayStr = "R2R " + displayStr.substring(prefixLength, displayStr.length())
1004 } else if (scenario == 'r2r') {
1010 def static getScenarioDisplayString(def scenario) {
1013 return "Innerloop Build and Test"
1015 case 'no_tiered_compilation_innerloop':
1016 def displayStr = getStressModeDisplayName(scenario)
1017 return "Innerloop Build and Test (Jit - ${displayStr})"
1019 case 'corefx_innerloop':
1020 return "CoreFX Tests"
1023 return "Build and Test"
1026 return "Jit Diff Build and Test"
1029 return "IL RoundTrip Build and Test"
1032 return "Long-Running GC Build & Test"
1035 return "GC Simulator"
1037 case 'standalone_gc':
1038 return "Standalone GC"
1040 case 'gc_reliability_framework':
1041 return "GC Reliability Framework"
1047 if (isJitStressScenario(scenario)) {
1048 def displayStr = getStressModeDisplayName(scenario)
1049 return "Build and Test (Jit - ${displayStr})"
1051 else if (isR2RScenario(scenario)) {
1052 def displayStr = getR2RDisplayName(scenario)
1053 return "${displayStr} Build and Test"
1056 return "${scenario}"
1061 println("Unknown scenario: ${scenario}");
1066 // Functions to create an environment script.
1067 // envScriptCreate -- initialize the script (call first)
1068 // envScriptFinalize -- finalize the script (call last)
1069 // envScriptSetStressModeVariables -- set stress mode variables in the env script
1070 // envScriptAppendExistingScript -- append an existing script to the generated script
1072 // Each script returns a string of commands. Concatenate all the strings together before
1073 // adding them to the builds commands, to make sure they get executed as one Jenkins script.
1076 // Initialize the environment setting script.
1077 def static envScriptCreate(def os, def stepScriptLocation) {
1079 if (os == 'Windows_NT') {
1080 stepScript += "echo Creating TestEnv script\r\n"
1081 stepScript += "if exist ${stepScriptLocation} del ${stepScriptLocation}\r\n"
1083 // Create at least an empty script.
1084 stepScript += "echo. > ${stepScriptLocation}\r\n"
1087 stepScript += "echo Creating environment setting script\n"
1088 stepScript += "echo \\#\\!/usr/bin/env bash > ${stepScriptLocation}\n"
1094 // Generates the string for setting stress mode variables.
1095 def static envScriptSetStressModeVariables(def os, def stressModeVars, def stepScriptLocation) {
1097 if (os == 'Windows_NT') {
1098 stressModeVars.each{ k, v ->
1099 // Write out what we are writing to the script file
1100 stepScript += "echo Setting ${k}=${v}\r\n"
1101 // Write out the set itself to the script file`
1102 stepScript += "echo set ${k}=${v} >> ${stepScriptLocation}\r\n"
1106 stressModeVars.each{ k, v ->
1107 // Write out what we are writing to the script file
1108 stepScript += "echo Setting ${k}=${v}\n"
1109 // Write out the set itself to the script file`
1110 stepScript += "echo export ${k}=${v} >> ${stepScriptLocation}\n"
1117 // Append an existing script to an environment script.
1118 // Returns string of commands to do this.
1119 def static envScriptAppendExistingScript(def os, def appendScript, def stepScriptLocation) {
1120 assert (os == 'Windows_NT')
1123 stepScript += "echo Appending ${appendScript} to ${stepScriptLocation}\r\n"
1124 stepScript += "type ${appendScript} >> ${stepScriptLocation}\r\n"
1129 // Finalize an environment setting script.
1130 // Returns string of commands to do this.
1131 def static envScriptFinalize(def os, def stepScriptLocation) {
1134 if (os == 'Windows_NT') {
1135 // Display the resulting script. This is useful when looking at the output log file.
1136 stepScript += "echo Display the total script ${stepScriptLocation}\r\n"
1137 stepScript += "type ${stepScriptLocation}\r\n"
1140 stepScript += "chmod +x ${stepScriptLocation}\n"
1146 def static isNeedDocker(def architecture, def os, def isBuild) {
1148 if (architecture == 'x86' && os == 'Ubuntu') {
1151 else if (architecture == 'armem') {
1154 else if (architecture == 'arm') {
1155 if (os == 'Ubuntu') {
1159 else if (architecture == 'arm64') {
1160 if (os == 'Ubuntu') {
1166 if (architecture == 'x86' && os == 'Ubuntu') {
1173 def static getDockerImageName(def architecture, def os, def isBuild) {
1174 // We must change some docker private images to official later
1176 if (architecture == 'x86' && os == 'Ubuntu') {
1177 return "hseok82/dotnet-buildtools-prereqs:ubuntu-16.04-crossx86-ef0ac75-20175511035548"
1179 else if (architecture == 'armem') {
1180 if (os == 'Tizen') {
1181 return "tizendotnet/dotnet-buildtools-prereqs:ubuntu-16.04-cross-e435274-20180426002255-tizen-rootfs-5.0m1"
1184 else if (architecture == 'arm') {
1185 if (os == 'Ubuntu') {
1186 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420"
1189 else if (architecture == 'arm64') {
1190 if (os == 'Ubuntu') {
1191 return "microsoft/dotnet-buildtools-prereqs:ubuntu-16.04-cross-arm64-a3ae44b-20180315221921"
1196 if (architecture == 'x86' && os == 'Ubuntu') {
1197 return "hseok82/dotnet-buildtools-prereqs:ubuntu1604_x86_test"
1200 println("Unknown architecture to use docker: ${architecture} ${os}");
1205 // We have a limited amount of some hardware. For these, scale back the periodic testing we do,
1206 // and only allowing using this hardware in some specific branches.
1207 def static jobRequiresLimitedHardware(def architecture, def os) {
1208 if (((architecture == 'arm64') || (architecture == 'arm')) && (os == 'Windows_NT')) {
1209 // These test jobs require ARM64 hardware
1212 else if ((architecture == 'arm') && (os == 'Ubuntu')) {
1213 // These test jobs require Linux/arm32 hardware
1216 else if ((architecture == 'arm64') && (os == 'Ubuntu')) {
1217 // These test jobs require Linux/arm64 hardware
1225 // Calculates the name of the build job based on some typical parameters.
1227 def static getJobName(def configuration, def architecture, def os, def scenario, def isBuildOnly) {
1228 // If the architecture is x64, do not add that info into the build name.
1229 // Need to change around some systems and other builds to pick up the right builds
1232 def suffix = scenario != 'normal' ? "_${scenario}" : '';
1237 switch (architecture) {
1239 if (scenario == 'normal') {
1240 // For now we leave x64 off of the name for compatibility with other jobs
1241 baseName = configuration.toLowerCase() + '_' + os.toLowerCase()
1243 else if (scenario == 'formatting') {
1244 // we don't care about the configuration for the formatting job. It runs all configs
1245 baseName = architecture.toLowerCase() + '_' + os.toLowerCase()
1248 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1252 if (os.toLowerCase() == "windows_nt") {
1253 // These are cross builds
1254 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1257 // Defaults to a small page size set of machines.
1258 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + "small_page_size"
1262 // These are cross builds
1263 assert os == 'Tizen'
1264 baseName = 'armel_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1267 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1270 case 'x86_arm_altjit':
1271 case 'x64_arm64_altjit':
1272 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1275 println("Unknown architecture: ${architecture}");
1280 return baseName + suffix
1283 def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob, def bidailyCrossList) {
1284 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1286 // Limited hardware is restricted for non-PR triggers to certain branches.
1287 if (jobRequiresLimitedHardware(architecture, os) && (!(branch in Constants.LimitedHardwareBranches))) {
1291 // No arm64 Ubuntu cron jobs for now: we don't have enough hardware.
1292 if ((architecture == 'arm64') && (os != 'Windows_NT')) {
1296 // Ubuntu x86 CI jobs are failing. Disable non-PR triggered jobs to avoid these constant failures
1297 // until this is fixed. Tracked by https://github.com/dotnet/coreclr/issues/19003.
1298 if (architecture == 'x86' && os == 'Ubuntu') {
1305 case 'no_tiered_compilation_innerloop':
1308 switch (architecture) {
1311 if (isFlowJob && architecture == 'x86' && os == 'Ubuntu') {
1312 addPeriodicTriggerHelper(job, '@daily')
1314 else if (isFlowJob || os == 'Windows_NT' || !(os in Constants.crossList)) {
1315 addGithubPushTriggerHelper(job)
1319 if (os == 'Windows_NT') {
1320 if (isFlowJob || (isNormalOrInnerloop && (configuration == 'Debug'))) {
1321 // We would normally want a per-push trigger, but with limited hardware we can't keep up.
1322 // Do the builds daily.
1323 addPeriodicTriggerHelper(job, '@daily')
1327 // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job.
1329 addPeriodicTriggerHelper(job, '@daily')
1334 if (os == 'Windows_NT') {
1335 if (isFlowJob || (isNormalOrInnerloop && (configuration == 'Debug'))) {
1336 // We would normally want a push trigger, but with limited hardware we can't keep up.
1337 // Do the builds daily.
1338 addPeriodicTriggerHelper(job, '@daily')
1342 assert os == 'Ubuntu'
1343 // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job.
1345 // Currently no push triggers, with limited arm Linux hardware.
1346 // TODO: If we have enough machine capacity, add some arm Linux push triggers.
1347 addPeriodicTriggerHelper(job, '@daily')
1352 addGithubPushTriggerHelper(job)
1354 case 'x86_arm_altjit':
1355 case 'x64_arm64_altjit':
1356 // Only do altjit push triggers for Checked; don't waste time on Debug or Release.
1357 if (configuration == 'Checked') {
1358 addGithubPushTriggerHelper(job)
1362 println("Unknown architecture: ${architecture}");
1368 assert !(os in bidailyCrossList)
1369 // r2r gets a push trigger for checked/release
1370 if (configuration == 'Checked' || configuration == 'Release') {
1371 assert (os == 'Windows_NT') || (os in Constants.crossList)
1372 if (architecture == 'x64' && os != 'OSX10.12') {
1373 //Flow jobs should be Windows, Ubuntu, OSX0.12, or CentOS
1374 if (isFlowJob || os == 'Windows_NT') {
1375 addGithubPushTriggerHelper(job)
1377 // OSX10.12 r2r jobs should only run every 12 hours, not daily.
1378 } else if (architecture == 'x64' && os == 'OSX10.12'){
1380 addPeriodicTriggerHelper(job, 'H H/12 * * *')
1383 // For x86, only add per-commit jobs for Windows
1384 else if (architecture == 'x86') {
1385 if (os == 'Windows_NT') {
1386 addGithubPushTriggerHelper(job)
1389 // arm64 r2r jobs should only run weekly.
1390 // arm64 r2r jobs are only run on Windows (Q: should they run on non-Windows?)
1391 else if (architecture == 'arm64') {
1392 if (os == 'Windows_NT') {
1394 addPeriodicTriggerHelper(job, '@weekly')
1398 // arm r2r jobs should only run weekly.
1399 else if (architecture == 'arm') {
1401 addPeriodicTriggerHelper(job, '@weekly')
1406 case 'r2r_jitstress1':
1407 case 'r2r_jitstress2':
1408 case 'r2r_jitstress1_tiered':
1409 case 'r2r_jitstress2_tiered':
1410 case 'r2r_jitstressregs1':
1411 case 'r2r_jitstressregs2':
1412 case 'r2r_jitstressregs3':
1413 case 'r2r_jitstressregs4':
1414 case 'r2r_jitstressregs8':
1415 case 'r2r_jitstressregs0x10':
1416 case 'r2r_jitstressregs0x80':
1417 case 'r2r_jitstressregs0x1000':
1418 case 'r2r_jitminopts':
1419 case 'r2r_jitforcerelocs':
1420 case 'r2r_gcstress15':
1421 case 'r2r_no_tiered_compilation':
1422 assert !(os in bidailyCrossList)
1424 // GCStress=C is currently not supported on OS X
1425 if (os == 'OSX10.12' && isGCStressRelatedTesting(scenario)) {
1429 // GC Stress 15 r2r gets a push trigger for checked/release
1430 if (configuration == 'Checked' || configuration == 'Release') {
1431 assert (os == 'Windows_NT') || (os in Constants.crossList)
1432 if (architecture == 'x64') {
1433 //Flow jobs should be Windows, Ubuntu, OSX10.12, or CentOS
1434 if (isFlowJob || os == 'Windows_NT') {
1435 // Add a weekly periodic trigger
1436 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1439 // For x86, only add periodic jobs for Windows
1440 else if (architecture == 'x86') {
1441 if (os == 'Windows_NT') {
1442 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1445 // arm64 r2r jobs are only run on Windows (Q: should they run on non-Windows?)
1446 else if (architecture == 'arm64') {
1447 if (os == 'Windows_NT') {
1449 addPeriodicTriggerHelper(job, '@weekly')
1453 else if (architecture == 'arm') {
1455 addPeriodicTriggerHelper(job, '@weekly')
1461 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1462 assert configuration == 'Release'
1463 assert architecture == 'x64'
1464 addPeriodicTriggerHelper(job, '@daily')
1465 // TODO: Add once external email sending is available again
1466 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1469 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1470 assert configuration == 'Release'
1471 assert architecture == 'x64'
1472 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1473 // TODO: Add once external email sending is available again
1474 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1476 case 'standalone_gc':
1477 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1478 assert (configuration == 'Release' || configuration == 'Checked')
1479 // TODO: Add once external email sending is available again
1480 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1481 addPeriodicTriggerHelper(job, '@daily')
1483 case 'gc_reliability_framework':
1484 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1485 assert (configuration == 'Release' || configuration == 'Checked')
1486 // Only triggered by phrase.
1489 assert !(os in bidailyCrossList)
1490 // ILASM/ILDASM roundtrip one gets a daily build, and only for release
1491 if (architecture == 'x64' && configuration == 'Release') {
1492 // We don't expect to see a job generated except in these scenarios
1493 assert (os == 'Windows_NT') || (os in Constants.crossList)
1494 if (isFlowJob || os == 'Windows_NT') {
1495 addPeriodicTriggerHelper(job, '@daily')
1500 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1501 assert configuration == 'Checked'
1502 assert (architecture == 'x64' || architecture == 'x86')
1503 addGithubPushTriggerHelper(job)
1506 assert (os == 'Windows_NT' || os == "Ubuntu")
1507 assert architecture == 'x64'
1508 addGithubPushTriggerHelper(job)
1510 case 'jitstressregs1':
1511 case 'jitstressregs2':
1512 case 'jitstressregs3':
1513 case 'jitstressregs4':
1514 case 'jitstressregs8':
1515 case 'jitstressregs0x10':
1516 case 'jitstressregs0x80':
1517 case 'jitstressregs0x1000':
1519 case 'tieredcompilation':
1520 case 'no_tiered_compilation':
1524 case 'jitstress1_tiered':
1525 case 'jitstress2_tiered':
1526 case 'jitstress2_jitstressregs1':
1527 case 'jitstress2_jitstressregs2':
1528 case 'jitstress2_jitstressregs3':
1529 case 'jitstress2_jitstressregs4':
1530 case 'jitstress2_jitstressregs8':
1531 case 'jitstress2_jitstressregs0x10':
1532 case 'jitstress2_jitstressregs0x80':
1533 case 'jitstress2_jitstressregs0x1000':
1534 case 'tailcallstress':
1537 case 'jitnox86hwintrinsic':
1538 case 'jitincompletehwintrinsic':
1539 case 'jitx86hwintrinsicnoavx':
1540 case 'jitx86hwintrinsicnoavx2':
1541 case 'jitx86hwintrinsicnosimd':
1542 case 'corefx_baseline':
1543 case 'corefx_minopts':
1544 case 'corefx_tieredcompilation':
1545 case 'corefx_jitstress1':
1546 case 'corefx_jitstress2':
1547 case 'corefx_jitstressregs1':
1548 case 'corefx_jitstressregs2':
1549 case 'corefx_jitstressregs3':
1550 case 'corefx_jitstressregs4':
1551 case 'corefx_jitstressregs8':
1552 case 'corefx_jitstressregs0x10':
1553 case 'corefx_jitstressregs0x80':
1554 case 'corefx_jitstressregs0x1000':
1556 if (os == 'CentOS7.1') {
1559 if (os in bidailyCrossList) {
1562 // ARM corefx testing uses non-flow jobs to provide the configuration-specific
1563 // build for the flow job. We don't need cron jobs for these. Note that the
1564 // Windows ARM jobs depend on a Windows "build only" job that exits the trigger
1565 // function very early, so only non-Windows gets here.
1566 if ((architecture == 'arm') && isCoreFxScenario(scenario) && !isFlowJob) {
1569 if ((architecture == 'arm64') && isCoreFxScenario(scenario) && !isFlowJob) {
1572 assert (os == 'Windows_NT') || (os in Constants.crossList)
1573 if (jobRequiresLimitedHardware(architecture, os)) {
1574 addPeriodicTriggerHelper(job, '@weekly')
1577 addPeriodicTriggerHelper(job, '@daily')
1582 if (os == 'CentOS7.1') {
1585 if (os in bidailyCrossList) {
1588 if ((architecture == 'arm64') && (os != 'Windows_NT')) {
1589 // TODO: should we have cron jobs for arm64 Linux GCStress?
1592 assert (os == 'Windows_NT') || (os in Constants.crossList)
1593 addPeriodicTriggerHelper(job, '@weekly')
1596 case 'gcstress0xc_zapdisable':
1597 case 'gcstress0xc_zapdisable_jitstress2':
1598 case 'gcstress0xc_zapdisable_heapverify1':
1599 case 'gcstress0xc_jitstress1':
1600 case 'gcstress0xc_jitstress2':
1601 case 'gcstress0xc_minopts_heapverify1':
1602 if (os == 'CentOS7.1') {
1605 if (os == 'OSX10.12') {
1606 // GCStress=C is currently not supported on OS X
1609 if (os in bidailyCrossList) {
1612 if ((architecture == 'arm64') && (os != 'Windows_NT')) {
1613 // TODO: should we have cron jobs for arm64 Linux GCStress?
1616 assert (os == 'Windows_NT') || (os in Constants.crossList)
1617 addPeriodicTriggerHelper(job, '@weekly')
1621 // Testing on other operating systems TBD
1622 assert (os == 'Windows_NT' || os == 'Ubuntu')
1623 if (architecture == 'x64' || architecture == 'x86') {
1624 if (configuration == 'Checked') {
1625 addPeriodicTriggerHelper(job, '@daily')
1631 println("Unknown scenario: ${scenario}");
1638 // **************************
1639 // Define the basic inner loop builds for PR and commit. This is basically just the set
1640 // of coreclr builds over linux/osx 10.12/windows and debug/release/checked. In addition, the windows
1641 // builds will do a couple extra steps.
1642 // **************************
1644 // Adds a trigger for the PR build if one is needed. If isFlowJob is true, then this is the
1645 // flow job that rolls up the build and test for non-windows OS's. // If the job is a windows build only job,
1646 // it's just used for internal builds
1647 // If you add a job with a trigger phrase, please add that phrase to coreclr/Documentation/project-docs/ci-trigger-phrases.md
1648 def static addTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob) {
1649 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1651 if (isWindowsBuildOnlyJob) {
1655 def bidailyCrossList = ['RHEL7.2', 'Debian8.4']
1656 // Non pull request builds.
1658 addNonPRTriggers(job, branch, isPR, architecture, os, configuration, scenario, isFlowJob, isWindowsBuildOnlyJob, bidailyCrossList)
1683 // Pull request builds. Generally these fall into two categories: default triggers and on-demand triggers
1684 // We generally only have a distinct set of default triggers but a bunch of on-demand ones.
1686 def contextString = ""
1687 def triggerString = ""
1688 def needsTrigger = true
1689 def isDefaultTrigger = false
1690 def isArm64PrivateJob = false
1691 def scenarioString = ""
1693 // Set up default context string and trigger phrases. This is overridden in places, sometimes just to keep
1694 // the existing non-standard descriptions and phrases. In some cases, the scenarios are asymmetric, as for
1695 // some jobs where the Debug configuration just does builds, no tests.
1697 // Some configurations, like arm32/arm64, always use the exact scenario name as part of the context string.
1698 // This makes it possible to copy/paste the displayed context string as "@dotnet-bot test <context-string>"
1699 // to invoke the trigger. Any "fancy" context string makes that impossible, requiring the user to either
1700 // remember the mapping from context string to trigger string, or use "@dotnet-bot help" to look it up.
1702 if (architecture == 'armem') {
1703 assert os == 'Tizen'
1704 architecture = 'armel'
1707 switch (architecture) {
1708 case 'x64_arm64_altjit':
1709 case 'x86_arm_altjit':
1710 // TODO: for consistency, add "Build and Test" at end.
1711 contextString = "${os} ${architecture} ${configuration} ${scenario}"
1712 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*"
1718 contextString = "${os} ${architecture} Cross ${configuration}"
1719 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}"
1721 if (scenario == 'innerloop') {
1722 contextString += " Innerloop"
1723 triggerString += "\\W+Innerloop"
1726 contextString += " ${scenario}"
1727 triggerString += "\\W+${scenario}"
1730 if (configuration == 'Debug') {
1731 contextString += " Build"
1732 triggerString += "\\W+Build"
1735 contextString += " Build and Test"
1736 triggerString += "\\W+Build and Test"
1739 triggerString += ".*"
1743 scenarioString = getScenarioDisplayString(scenario)
1744 contextString = "${os} ${architecture} ${configuration} ${scenarioString}"
1745 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}"
1749 triggerString += "\\W+Build and Test.*"
1752 case 'corefx_innerloop': // maintain this asymmetry
1753 triggerString += "\\W+CoreFX Tests.*"
1757 triggerString += "\\W+${scenario}.*"
1761 triggerString += ".*"
1765 // Now determine what kind of trigger this job needs, if any. Any job should be triggerable, except for
1766 // non-flow jobs that are only used as part of flow jobs.
1768 switch (architecture) {
1769 case 'x64': // editor brace matching: {
1770 if (scenario == 'formatting') {
1771 assert configuration == 'Checked'
1772 if (os == 'Windows_NT' || os == 'Ubuntu') {
1773 isDefaultTrigger = true
1774 contextString = "${os} ${architecture} Formatting"
1780 // OpenSUSE, Debian & RedHat get trigger phrases for pri 0 build, and pri 1 build & test
1783 if (scenario == 'innerloop') {
1785 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1786 isDefaultTrigger = true
1796 assert scenario != 'innerloop'
1797 contextString = "${os} ${architecture} ${configuration} Build"
1798 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+Build.*"
1802 if (scenario == 'illink') {
1805 else if (scenario == 'corefx_innerloop') {
1806 if (configuration == 'Checked') {
1807 isDefaultTrigger = true
1815 // Triggers on the non-flow jobs aren't necessary here
1816 // Corefx testing uses non-flow jobs.
1817 if (!isFlowJob && !isCoreFxScenario(scenario)) {
1818 needsTrigger = false
1823 isDefaultTrigger = true
1826 case 'no_tiered_compilation_innerloop':
1827 if (os == 'Ubuntu') {
1828 isDefaultTrigger = true
1840 // CentOS uses checked for default PR tests while debug is build only
1841 if (configuration == 'Debug') {
1842 isDefaultTrigger = true
1843 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1847 // Make sure this is a flow job to get build and test.
1849 needsTrigger = false
1853 if (configuration == 'Checked') {
1854 assert job.name.contains("flow")
1855 isDefaultTrigger = true
1856 contextString = "${os} ${architecture} ${configuration} Innerloop Build and Test"
1861 // Make sure this is a flow job to get build and test.
1863 needsTrigger = false
1876 case 'no_tiered_compilation_innerloop':
1877 isDefaultTrigger = true
1880 case 'corefx_innerloop':
1881 if (configuration == 'Checked' || configuration == 'Release') {
1882 isDefaultTrigger = true
1892 println("Unknown os: ${os}");
1899 // editor brace matching: }
1901 case 'armel': // editor brace matching: {
1904 azureVMAgentPostBuildAction {
1905 agentPostBuildAction('Delete agent if the build was not successful (when idle).')
1912 if (scenario == 'innerloop') {
1913 if (configuration == 'Checked') {
1914 isDefaultTrigger = true
1921 // editor brace matching: }
1924 case 'arm64': // editor brace matching: {
1928 // TODO: make arm and arm64 Ubuntu more alike
1930 if (architecture == 'arm') {
1931 // Triggers on the non-flow jobs aren't necessary
1933 needsTrigger = false
1939 case 'no_tiered_compilation_innerloop':
1940 if (configuration == 'Checked') {
1941 isDefaultTrigger = true
1947 assert architecture == 'arm64'
1951 if (configuration == 'Debug' && !isFlowJob) {
1952 isDefaultTrigger = true
1960 assert isArmWindowsScenario(scenario)
1962 // For Debug normal/innerloop scenario, we don't do test runs, so we don't use flow jobs. That means we need a trigger for
1963 // the non-flow Build job. All others need a trigger on the flow job.
1964 def needsFlowJobTrigger = !(isNormalOrInnerloop && (configuration == 'Debug'))
1965 if (isFlowJob != needsFlowJobTrigger) {
1966 needsTrigger = false
1972 if (configuration == 'Debug') {
1973 // Add default PR trigger for Windows arm64 Debug builds. This is a build only -- no tests are run --
1974 // so the private test hardware is not used. Thus, it can be run by all users, not just arm64Users.
1975 // People in arm64Users will get both this and the Checked Build and Test job.
1976 isDefaultTrigger = true
1977 } else if (configuration == 'Checked') {
1978 isDefaultTrigger = true
1979 isArm64PrivateJob = true
1983 isArm64PrivateJob = true
1988 println("NYI os: ${os}");
1994 // editor brace matching: }
1995 case 'x86': // editor brace matching: {
1996 assert ((os == 'Windows_NT') || ((os == 'Ubuntu') && isNormalOrInnerloop))
1997 if (os == 'Ubuntu') {
1998 // Triggers on the non-flow jobs aren't necessary here
2000 needsTrigger = false
2004 // on-demand only for ubuntu x86
2005 contextString = "${os} ${architecture} ${configuration} Build"
2006 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}.*"
2011 case 'no_tiered_compilation_innerloop':
2012 isDefaultTrigger = true
2019 // editor brace matching: }
2020 case 'x64_arm64_altjit':
2021 case 'x86_arm_altjit':
2022 // Everything default
2026 println("Unknown architecture: ${architecture}");
2032 if (isArm64PrivateJob) {
2033 if (isDefaultTrigger) {
2034 Utilities.addDefaultPrivateGithubPRTriggerForBranch(job, branch, contextString, null, arm64Users)
2037 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
2041 if (isDefaultTrigger) {
2042 Utilities.addGithubPRTriggerForBranch(job, branch, contextString)
2045 Utilities.addGithubPRTriggerForBranch(job, branch, contextString, triggerString)
2051 def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR, def architecture, def configuration, def os, def isBuildOnly) {
2052 def buildCommands = []
2053 def osGroup = getOSGroup(os)
2054 def lowerConfiguration = configuration.toLowerCase()
2057 if (isPri0TestScenario(scenario)) {
2061 def doCoreFxTesting = isCoreFxScenario(scenario)
2063 // Calculate the build steps, archival, and xunit results
2065 case 'Windows_NT': // editor brace matching: {
2066 switch (architecture) {
2069 case 'x86_arm_altjit':
2070 case 'x64_arm64_altjit':
2071 def arch = architecture
2073 if (architecture == 'x86_arm_altjit') {
2076 else if (architecture == 'x64_arm64_altjit') {
2080 if (scenario == 'formatting') {
2081 buildCommands += "python -u tests\\scripts\\format.py -c %WORKSPACE% -o Windows_NT -a ${arch}"
2082 Utilities.addArchival(newJob, "format.patch", "", true, false)
2086 if (scenario == 'illink') {
2087 buildCommands += "tests\\scripts\\build_illink.cmd clone ${arch}"
2090 // If it is a release build for Windows, ensure PGO is used, else fail the build.
2091 if ((lowerConfiguration == 'release') &&
2092 (scenario in Constants.basicScenarios) &&
2093 (architecture != 'x86_arm_altjit') &&
2094 (architecture != 'x64_arm64_altjit')) {
2096 buildOpts += ' -enforcepgo'
2099 if (doCoreFxTesting) {
2100 buildOpts += ' skiptests';
2102 buildOpts += " -priority=${priority}"
2105 // Set __TestIntermediateDir to something short. If __TestIntermediateDir is already set, build-test.cmd will
2106 // output test binaries to that directory. If it is not set, the binaries are sent to a default directory whose name is about
2107 // 35 characters long.
2109 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts}"
2112 def runtestArguments = ''
2113 def testOpts = 'collectdumps'
2115 if (isR2RScenario(scenario)) {
2117 // If this is a ReadyToRun scenario, pass 'crossgen' or 'crossgenaltjit'
2118 // to cause framework assemblies to be crossgen'ed. Pass 'runcrossgentests'
2119 // to cause the tests to be crossgen'ed.
2121 if ((architecture == 'x86_arm_altjit') || (architecture == 'x64_arm64_altjit')) {
2122 testOpts += ' crossgenaltjit protononjit.dll'
2124 testOpts += ' crossgen'
2127 testOpts += ' runcrossgentests'
2129 else if (scenario == 'jitdiff') {
2130 testOpts += ' jitdisasm crossgen'
2132 else if (scenario == 'ilrt') {
2133 testOpts += ' ilasmroundtrip'
2135 else if (isLongGc(scenario)) {
2136 testOpts += " ${scenario} sequential"
2138 else if (scenario == 'standalone_gc') {
2139 testOpts += ' gcname clrgc.dll'
2141 else if (scenario == 'illink') {
2142 testOpts += " link %WORKSPACE%\\linker\\linker\\bin\\netcore_Release\\netcoreapp2.0\\win10-${arch}\\publish\\illink.exe"
2145 // Default per-test timeout is 10 minutes. For stress modes and Debug scenarios, increase this
2146 // to 30 minutes (30 * 60 * 1000 = 180000). The "timeout" argument to runtest.cmd sets this, by
2147 // taking a timeout value in milliseconds. (Note that it sets the __TestTimeout environment variable,
2148 // which is read by the xunit harness.)
2149 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario) || (lowerConfiguration == 'debug'))
2151 def timeout = 1800000
2152 testOpts += " timeout ${timeout}"
2155 // If we are running a stress mode, we should write out the set of key
2156 // value env pairs to a file at this point and then we'll pass that to runtest.cmd
2158 def envScriptPath = ''
2159 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2160 def buildCommandsStr = ''
2161 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2162 buildCommandsStr += envScriptCreate(os, envScriptPath)
2164 if (isJitStressScenario(scenario)) {
2165 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2167 else if (isR2RStressScenario(scenario)) {
2168 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.r2rStressScenarios[scenario], envScriptPath)
2171 if (architecture == 'x86_arm_altjit') {
2172 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x86_arm_altjit.cmd", envScriptPath)
2174 else if (architecture == 'x64_arm64_altjit') {
2175 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd", envScriptPath)
2178 envScriptFinalize(os, envScriptPath)
2180 // Note that buildCommands is an array of individually executed commands; we want all the commands used to
2181 // create the SetStressModes.bat script to be executed together, hence we accumulate them as strings
2182 // into a single script.
2183 buildCommands += buildCommandsStr
2185 else if (architecture == 'x86_arm_altjit') {
2186 envScriptPath = "%WORKSPACE%\\tests\\x86_arm_altjit.cmd"
2188 else if (architecture == 'x64_arm64_altjit') {
2189 envScriptPath = "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd"
2191 if (envScriptPath != '') {
2192 testOpts += " TestEnv ${envScriptPath}"
2195 runtestArguments = "${lowerConfiguration} ${arch} ${testOpts}"
2197 if (doCoreFxTesting) {
2198 if (scenario == 'corefx_innerloop') {
2199 // Create CORE_ROOT and testhost
2200 buildCommands += "build-test.cmd ${lowerConfiguration} ${arch} buildtesthostonly"
2201 buildCommands += "tests\\runtest.cmd ${runtestArguments} CoreFXTestsAll"
2203 // Archive and process (only) the test results
2204 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2205 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2208 def workspaceRelativeFxRoot = "_/fx"
2209 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2210 def fxBranch = getFxBranch(branch)
2212 buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${arch} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${envScriptPath}"
2214 // Archive and process (only) the test results
2215 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2216 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2218 //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
2219 Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
2220 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
2223 else if (isGcReliabilityFramework(scenario)) {
2224 buildCommands += "tests\\runtest.cmd ${runtestArguments} GenerateLayoutOnly"
2225 buildCommands += "tests\\scripts\\run-gc-reliability-framework.cmd ${arch} ${configuration}"
2228 buildCommands += "tests\\runtest.cmd ${runtestArguments}"
2230 } // end if (!isBuildOnly)
2232 if (!doCoreFxTesting) {
2233 // Run the rest of the build
2234 // Build the mscorlib for the other OS's
2235 buildCommands += "build.cmd ${lowerConfiguration} ${arch} linuxmscorlib"
2236 buildCommands += "build.cmd ${lowerConfiguration} ${arch} osxmscorlib"
2238 if (arch == 'x64') {
2239 buildCommands += "build.cmd ${lowerConfiguration} arm64 linuxmscorlib"
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}.${arch}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
2246 if (!isJitStressScenario(scenario)) {
2247 // For Windows, pull full test results and test drops for x86/x64.
2248 // No need to pull for stress mode scenarios (downstream builds use the default scenario)
2249 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2252 if (scenario == 'jitdiff') {
2253 // retrieve jit-dasm output for base commit, and run jit-diff
2255 // if this is a build only job, we want to keep the default (build) artifacts for the flow job
2256 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${arch}.${configuration}/dasm/**")
2261 Utilities.addXUnitDotNETResults(newJob, 'bin/**/TestRun*.xml', true)
2267 assert isArmWindowsScenario(scenario)
2271 if (doCoreFxTesting) {
2272 buildOpts += ' skiptests'
2274 buildOpts += " -priority=${priority}"
2277 // This is now a build only job. Do not run tests. Use the flow job.
2278 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} ${buildOpts}"
2280 if (doCoreFxTesting) {
2283 // Set the stress mode variables; this is incorporated into the generated CoreFx RunTests.cmd files.
2284 def envScriptPath = ''
2285 def buildCommandsStr = ''
2286 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2287 buildCommandsStr += envScriptCreate(os, envScriptPath)
2288 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2289 envScriptFinalize(os, envScriptPath)
2290 buildCommands += buildCommandsStr
2292 def workspaceRelativeFxRootLinux = "_/fx"
2293 def workspaceRelativeFxRootWin = "_\\fx"
2294 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2295 def fxBranch = getFxBranch(branch)
2297 buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${envScriptPath} -no_run_tests"
2299 // Zip up the CoreFx runtime and tests. We don't need the CoreCLR binaries; they have been copied to the CoreFX tree.
2300 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}', '${workspaceRelativeFxRootWin}\\fxruntime.zip')\"";
2301 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\tests', '${workspaceRelativeFxRootWin}\\fxtests.zip')\"";
2303 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2304 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2306 // Zip up the tests directory so that we don't use so much space/time copying
2307 // 10s of thousands of files around.
2308 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')\"";
2311 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2315 println("Unknown architecture: ${architecture}");
2320 // end case 'Windows_NT'; editor brace matching: }
2329 case 'Fedora24': // editor brace matching: {
2330 switch (architecture) {
2333 if (architecture == 'x86' && os == 'Ubuntu') {
2334 // build and PAL test
2335 def dockerImage = getDockerImageName(architecture, os, true)
2336 buildCommands += "docker run -i --rm -v \${WORKSPACE}:/opt/code -w /opt/code -e ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} ./build.sh ${architecture} cross ${lowerConfiguration}"
2337 dockerImage = getDockerImageName(architecture, os, false)
2338 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"
2339 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2340 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2344 if (scenario == 'formatting') {
2345 buildCommands += "python tests/scripts/format.py -c \${WORKSPACE} -o Linux -a ${architecture}"
2346 Utilities.addArchival(newJob, "format.patch", "", true, false)
2350 if (scenario == 'illink') {
2351 assert(os == 'Ubuntu')
2352 buildCommands += "./tests/scripts/build_illink.sh --clone --arch=${architecture}"
2355 if (!doCoreFxTesting) {
2356 // We run pal tests on all OS but generate mscorlib (and thus, nuget packages)
2357 // only on supported OS platforms.
2358 def bootstrapRid = Utilities.getBoostrapPublishRid(os)
2359 def bootstrapRidEnv = bootstrapRid != null ? "__PUBLISH_RID=${bootstrapRid} " : ''
2361 buildCommands += "${bootstrapRidEnv}./build.sh ${lowerConfiguration} ${architecture}"
2362 buildCommands += "src/pal/tests/palsuite/runpaltests.sh \${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration} \${WORKSPACE}/bin/paltestout"
2364 // Basic archiving of the build
2365 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2367 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2370 if (scenario == 'corefx_innerloop') {
2371 assert os == 'Ubuntu' || 'OSX10.12'
2372 assert architecture == 'x64'
2374 buildCommands += "./build.sh ${lowerConfiguration} ${architecture} skiptests"
2375 buildCommands += "./build-test.sh ${lowerConfiguration} ${architecture} generatetesthostonly"
2376 buildCommands += "./tests/runtest.sh --corefxtestsall --testHostDir=\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/testhost/ --coreclr-src=\${WORKSPACE}"
2379 // Archive and process (only) the test results
2380 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2381 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2384 // Corefx stress testing
2385 assert os == 'Ubuntu'
2386 assert architecture == 'x64'
2387 assert lowerConfiguration == 'checked'
2388 assert isJitStressScenario(scenario)
2391 buildCommands += "./build.sh ${lowerConfiguration} ${architecture}"
2393 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2395 def envScriptCmds = envScriptCreate(os, scriptFileName)
2396 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2397 envScriptCmds += envScriptFinalize(os, scriptFileName)
2398 buildCommands += envScriptCmds
2400 // Build and text corefx
2401 def workspaceRelativeFxRoot = "_/fx"
2402 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRoot}"
2403 def fxBranch = getFxBranch(branch)
2405 buildCommands += "python -u \$WORKSPACE/tests/scripts/run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${scriptFileName}"
2407 // Archive and process (only) the test results
2408 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2409 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2414 // Emulator cross builds for ARM runs on Tizen currently
2415 assert os == 'Tizen'
2417 def arm_abi = "armel"
2418 def linuxCodeName = "tizen"
2420 // Unzip the Windows test binaries first. Exit with 0
2421 buildCommands += "unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.x64.${configuration} || exit 0"
2423 // Unpack the corefx binaries
2424 buildCommands += "mkdir ./bin/CoreFxBinDir"
2425 buildCommands += "tar -xf ./bin/build.tar.gz -C ./bin/CoreFxBinDir"
2427 // Call the ARM CI script to cross build and test using docker
2428 buildCommands += """./tests/scripts/arm32_ci_script.sh \\
2431 --linuxCodeName=${linuxCodeName} \\
2432 --buildConfig=${lowerConfiguration} \\
2433 --testRootDir=./bin/tests/Windows_NT.x64.${configuration} \\
2434 --coreFxBinDir=./bin/CoreFxBinDir \\
2435 --testDirFile=./tests/testsRunningInsideARM.txt"""
2437 // Basic archiving of the build, no pal tests
2438 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2442 // Non-Windows ARM cross builds on hardware run on Ubuntu only
2443 assert (os == 'Ubuntu')
2445 // Add some useful information to the log file. Ignore return codes.
2446 buildCommands += "uname -a || true"
2448 def additionalOpts = ""
2449 if (architecture == 'arm') {
2450 additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86"
2453 // Cross build the Ubuntu/arm product using docker with a docker image that contains the correct
2454 // Ubuntu cross-compilation toolset (running on a Ubuntu x64 host).
2455 // For CoreFX testing, we only need the product build; we don't need to generate the layouts. The product
2456 // build is then copied into the corefx layout by the run-corefx-test.py script. For CoreFX testing, we
2457 // ZIP up the generated CoreFX runtime and tests.
2459 def dockerImage = getDockerImageName(architecture, os, true)
2460 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} "
2462 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh ${lowerConfiguration} ${architecture} cross crosscomponent"
2464 if (doCoreFxTesting) {
2465 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2467 def envScriptCmds = envScriptCreate(os, scriptFileName)
2468 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2469 envScriptCmds += envScriptFinalize(os, scriptFileName)
2470 buildCommands += envScriptCmds
2472 // Build and text corefx
2473 def workspaceRelativeFxRootLinux = "_/fx"
2474 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRootLinux}"
2475 def fxBranch = getFxBranch(branch)
2477 buildCommands += "${dockerCmd}python -u \$WORKSPACE/tests/scripts/run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${scriptFileName} -no_run_tests"
2479 // Docker creates files with root permission, so we need to zip in docker also, or else we'll get permission errors.
2480 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxruntime.zip ${workspaceRelativeFxRootLinux}/bin/testhost/netcoreapp-Linux-Release-${architecture}"
2481 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxtests.zip ${workspaceRelativeFxRootLinux}/bin/tests"
2483 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2484 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2485 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/run-test.sh")
2488 // Then, using the same docker image, generate the CORE_ROOT layout using build-test.sh to
2489 // download the appropriate CoreFX packages.
2490 // Note that docker should not be necessary here, for the "generatelayoutonly" case, but we use it
2491 // just to be consistent with the "build.sh" case -- so both are run with the same environment.
2493 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2495 // ZIP up for the test job (created in the flow job code):
2496 // (1) the built CORE_ROOT, /home/user/coreclr/bin/tests/Linux.arm.Checked/Tests/Core_Root,
2497 // used by runtest.sh as the "--coreOverlayDir" argument.
2498 // (2) the native parts of the test build: /home/user/coreclr/bin/obj/Linux.arm.Checked/tests,
2499 // used by runtest.sh as the "--testNativeBinDir" argument.
2501 // These commands are assumed to be run from the root of the workspace.
2502 buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root"
2503 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2505 Utilities.addArchival(newJob, "coreroot.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2508 // We need to clean up the build machines; the docker build leaves newly built files with root permission, which
2509 // the cleanup task in Jenkins can't remove.
2512 azureVMAgentPostBuildAction {
2513 agentPostBuildAction('Delete agent after build execution (when idle).')
2519 println("Unknown architecture: ${architecture}");
2524 // editor brace matching: }
2526 println("Unknown os: ${os}");
2531 return buildCommands
2534 // Determine if we should generate a job for the given parameters. This is for non-flow jobs: either build and test, or build only.
2535 // Returns true if the job should be generated.
2536 def static shouldGenerateJob(def scenario, def isPR, def architecture, def configuration, def os, def isBuildOnly)
2538 // The "innerloop" (Pri-0 testing) scenario is only available as PR triggered.
2539 if (scenario == 'innerloop' && !isPR) {
2543 // Run basic corefx tests only on PR-triggered jobs
2544 // Runs under Release and Checked
2545 if (scenario == 'corefx_innerloop' && !isPR) {
2549 // Tizen is only supported for armem architecture
2550 if (os == 'Tizen' && architecture != 'armem') {
2554 // Filter based on architecture.
2556 switch (architecture) {
2559 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2564 if (os != 'Tizen') {
2568 case 'x86_arm_altjit':
2569 case 'x64_arm64_altjit':
2570 if (os != 'Windows_NT') {
2575 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2580 // Everything implemented
2583 println("Unknown architecture: ${architecture}")
2588 // Which (Windows) build only jobs are required?
2590 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
2593 switch (architecture) {
2596 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2597 if (!isCoreFxScenario(scenario)) {
2603 if (!isNormalOrInnerloop) {
2612 // Filter based on scenario.
2614 if (isJitStressScenario(scenario)) {
2615 if (configuration != 'Checked') {
2619 def isEnabledOS = (os == 'Windows_NT') || (os == 'Ubuntu' && (isCoreFxScenario(scenario) || architecture == 'arm' || architecture == 'arm64'))
2624 switch (architecture) {
2626 case 'x86_arm_altjit':
2627 case 'x64_arm64_altjit':
2631 // x86 ubuntu: no stress modes
2632 if (os == 'Ubuntu') {
2638 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2639 // No "regular" Windows arm corefx jobs, e.g.
2640 // For Ubuntu arm corefx testing, we use regular jobs (not "build only" since only Windows has "build only", and
2641 // the Ubuntu arm "regular" jobs don't run tests anyway).
2642 if (os == 'Windows_NT') {
2643 if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
2648 if (!isCoreFxScenario(scenario)) {
2655 if (os == 'Windows_NT') {
2656 if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
2661 if (!isCoreFxScenario(scenario)) {
2668 // arm64: stress is handled through flow jobs.
2669 // armem: no stress jobs for ARM emulator.
2673 else if (isR2RScenario(scenario)) {
2674 if (os != 'Windows_NT') {
2678 if (isR2RBaselineScenario(scenario)) {
2679 // no need for Debug scenario; Checked is sufficient
2680 if (configuration != 'Checked' && configuration != 'Release') {
2684 else if (isR2RStressScenario(scenario)) {
2685 // Stress scenarios only run with Checked builds, not Release (they would work with Debug, but be slow).
2686 if (configuration != 'Checked') {
2691 switch (architecture) {
2694 // Windows arm/arm64 ready-to-run jobs use flow jobs and test jobs, but depend on "normal" (not R2R specific) build jobs.
2705 // The ilrt build isn't necessary except for Windows_NT2003. Non-Windows NT uses
2706 // the default scenario build
2707 if (os != 'Windows_NT') {
2711 if (architecture != 'x64') {
2715 if (configuration != 'Release') {
2720 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2723 if (architecture != 'x64') {
2726 if (configuration != 'Checked') {
2732 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2735 if (architecture != 'x64') {
2738 if (configuration != 'Release') {
2742 case 'gc_reliability_framework':
2743 case 'standalone_gc':
2744 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2748 if (architecture != 'x64') {
2752 if (configuration != 'Release' && configuration != 'Checked') {
2756 // We only run Windows and Ubuntu x64 Checked for formatting right now
2758 if (os != 'Windows_NT' && os != 'Ubuntu') {
2761 if (architecture != 'x64') {
2764 if (configuration != 'Checked') {
2769 if (os != 'Windows_NT' && (os != 'Ubuntu' || architecture != 'x64')) {
2772 if (architecture != 'x64' && architecture != 'x86') {
2780 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly)) {
2784 case 'corefx_innerloop':
2785 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2788 if (architecture != 'x64') {
2793 println("Unknown scenario: ${scenario}")
2799 // For altjit, don't do any scenarios that don't change compilation. That is, scenarios that only change
2800 // runtime behavior, not compile-time behavior, are not interesting.
2801 switch (architecture) {
2802 case 'x86_arm_altjit':
2803 case 'x64_arm64_altjit':
2804 if (isGCStressRelatedTesting(scenario)) {
2812 // The job was not filtered out, so we should generate it!
2816 Constants.allScenarios.each { scenario ->
2817 [true, false].each { isPR ->
2818 Constants.architectureList.each { architecture ->
2819 Constants.configurationList.each { configuration ->
2820 Constants.osList.each { os ->
2821 // If the OS is Windows_NT_BuildOnly, set the isBuildOnly flag to true
2822 // and reset the os to Windows_NT
2823 def isBuildOnly = false
2824 if (os == 'Windows_NT_BuildOnly') {
2829 if (!shouldGenerateJob(scenario, isPR, architecture, configuration, os, isBuildOnly)) {
2834 def jobName = getJobName(configuration, architecture, os, scenario, isBuildOnly)
2835 def folderName = getJobFolder(scenario)
2837 // Create the new job
2838 def newJob = job(Utilities.getFullJobName(project, jobName, isPR, folderName)) {}
2840 // We don't want to include in view any job that is only used by a flow job (because we want the views to have only the
2841 // "top-level" jobs. Build only jobs are such jobs.
2844 addToViews(newJob, isPR, architecture, os)
2847 setJobMachineAffinity(architecture, os, true, false, false, newJob) // isBuildJob = true, isTestJob = false, isFlowJob = false
2849 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
2850 addTriggers(newJob, branch, isPR, architecture, os, configuration, scenario, false, isBuildOnly) // isFlowJob==false
2851 setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly)
2853 // Copy Windows build test binaries and corefx build artifacts for Linux cross build for armem.
2854 // We don't use a flow job for this, but we do depend on there being existing builds with these
2855 // artifacts produced.
2856 if ((architecture == 'armem') && (os == 'Tizen')) {
2857 // Define the Windows Tests and Corefx build job names
2858 def lowerConfiguration = configuration.toLowerCase()
2859 def WindowsTestsName = projectFolder + '/' +
2860 Utilities.getFullJobName(project,
2861 getJobName(lowerConfiguration, 'x64' , 'windows_nt', 'normal', true),
2863 def fxBranch = getFxBranch(branch)
2864 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' +
2865 Utilities.getFolderName(fxBranch)
2867 def arm_abi = 'armel'
2868 def corefx_os = 'tizen'
2870 // Let's use release CoreFX to test checked CoreCLR,
2871 // because we do not generate checked CoreFX in CoreFX CI yet.
2872 def corefx_lowerConfiguration = lowerConfiguration
2873 if (lowerConfiguration == 'checked') {
2874 corefx_lowerConfiguration = 'release'
2877 // Copy the Windows test binaries and the Corefx build binaries
2880 copyArtifacts(WindowsTestsName) {
2881 includePatterns('bin/tests/tests.zip')
2883 latestSuccessful(true)
2886 copyArtifacts("${corefxFolder}/${corefx_os}_${arm_abi}_cross_${corefx_lowerConfiguration}") {
2887 includePatterns('bin/build.tar.gz')
2889 latestSuccessful(true)
2896 def buildCommands = calculateBuildCommands(newJob, scenario, branch, isPR, architecture, configuration, os, isBuildOnly)
2900 if (os == 'Windows_NT') {
2901 buildCommands.each { buildCommand ->
2902 batchFile(buildCommand)
2906 buildCommands.each { buildCommand ->
2919 // Create a Windows ARM/ARM64 test job that will be used by a flow job.
2920 // Returns the newly created job.
2921 def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
2923 def osGroup = getOSGroup(os)
2924 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
2926 def jobFolder = getJobFolder(scenario)
2927 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
2929 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
2933 // Set up the copies
2935 // Coreclr build we are trying to test
2937 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
2939 copyArtifacts(inputCoreCLRBuildName) {
2940 excludePatterns('**/testResults.xml', '**/*.ni.dll')
2942 buildNumber('${CORECLR_BUILD}')
2946 if (isCoreFxScenario(scenario)) {
2948 // Only arm/arm64 supported for corefx testing now.
2949 assert architecture == 'arm' || architecture == 'arm64'
2951 // Unzip CoreFx runtime
2952 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-${architecture}')\"")
2954 // Unzip CoreFx tests.
2955 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxtests.zip', '_\\fx\\bin\\tests')\"")
2957 // Add the script to run the corefx tests
2958 def corefx_runtime_path = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}"
2959 def corefx_tests_dir = "%WORKSPACE%\\_\\fx\\bin\\tests"
2960 def corefx_exclusion_file = "%WORKSPACE%\\tests\\${architecture}\\corefx_test_exclusions.txt"
2961 batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file} ${architecture}")
2963 } else { // !isCoreFxScenario(scenario)
2966 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}')\"")
2968 def buildCommands = ""
2970 def coreRootLocation = "%WORKSPACE%\\bin\\tests\\Windows_NT.${architecture}.${configuration}\\Tests\\Core_Root"
2971 def addEnvVariable = { variable, value -> buildCommands += "set ${variable}=${value}\r\n"}
2972 def addCommand = { cmd -> buildCommands += "${cmd}\r\n"}
2974 // Make sure Command Extensions are enabled. Used so %ERRORLEVEL% is available.
2975 addCommand("SETLOCAL ENABLEEXTENSIONS")
2978 addEnvVariable("CORE_ROOT", coreRootLocation)
2979 addEnvVariable("COMPlus_NoGuiOnAssert", "1")
2980 addEnvVariable("COMPlus_ContinueOnAssert", "0")
2982 // If we are running a stress mode, we'll set those variables as well
2983 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2984 def stressValues = null
2985 if (isJitStressScenario(scenario)) {
2986 stressValues = Constants.jitStressModeScenarios[scenario]
2989 stressValues = Constants.r2rStressScenarios[scenario]
2992 stressValues.each { key, value ->
2993 addEnvVariable(key, value)
2997 if (isR2RScenario(scenario)) {
2998 // Crossgen the framework assemblies.
2999 buildCommands += """
3000 @for %%F in (%CORE_ROOT%\\*.dll) do @call :PrecompileAssembly "%CORE_ROOT%" "%%F" %%~nxF
3001 @goto skip_PrecompileAssembly
3004 @REM Skip mscorlib since it is already precompiled.
3005 @if /I "%3" == "mscorlib.dll" exit /b 0
3006 @if /I "%3" == "mscorlib.ni.dll" exit /b 0
3008 "%CORE_ROOT%\\crossgen.exe" /Platform_Assemblies_Paths "%CORE_ROOT%" %2 >nul 2>nul
3009 @if "%errorlevel%" == "-2146230517" (
3010 echo %2 is not a managed assembly.
3011 ) else if "%errorlevel%" == "-2146234344" (
3012 echo %2 is not a managed assembly.
3013 ) else if %errorlevel% neq 0 (
3014 echo Unable to precompile %2
3020 :skip_PrecompileAssembly
3023 // Set RunCrossGen variable to cause test wrappers to invoke their logic to run
3024 // crossgen on tests before running them.
3025 addEnvVariable("RunCrossGen", "true")
3026 } // isR2RScenario(scenario)
3028 // Create the smarty command
3029 def smartyCommand = "C:\\Tools\\Smarty.exe /noecid /noie /workers 9 /inc EXPECTED_PASS "
3030 def addSmartyFlag = { flag -> smartyCommand += flag + " "}
3031 def addExclude = { exclude -> addSmartyFlag("/exc " + exclude)}
3032 def addArchSpecificExclude = { architectureToExclude, exclude -> addExclude(exclude) }
3034 // Exclude tests based on scenario.
3035 Constants.validArmWindowsScenarios[scenario].each { excludeTag ->
3036 addArchSpecificExclude(architecture, excludeTag)
3039 if (isPri0TestScenario(scenario)) {
3043 // Exclude any test marked LONG_RUNNING; these often exceed the standard timeout and fail as a result.
3044 // TODO: We should create a "long running" job that runs these with a longer timeout.
3045 addExclude("LONG_RUNNING")
3047 smartyCommand += "/lstFile Tests.lst"
3049 def testListArch = [
3054 def archLocation = testListArch[architecture]
3056 addCommand("copy %WORKSPACE%\\tests\\${archLocation}\\Tests.lst bin\\tests\\${osGroup}.${architecture}.${configuration}")
3057 addCommand("pushd bin\\tests\\${osGroup}.${architecture}.${configuration}")
3058 addCommand("${smartyCommand}")
3060 // Save the errorlevel from the smarty command to be used as the errorlevel of this batch file.
3061 // However, we also need to remove all the variables that were set during this batch file, so we
3062 // can run the ZIP powershell command (below) in a clean environment. (We can't run the powershell
3063 // command with the COMPlus_AltJit variables set, for example.) To do that, we do ENDLOCAL as well
3064 // as save the current errorlevel on the same line. This works because CMD evaluates the %errorlevel%
3065 // variable expansion (or any variable expansion on the line) BEFORE it executes the ENDLOCAL command.
3066 // Note that the ENDLOCAL also undoes the pushd command, but we add the popd here for clarity.
3067 addCommand("popd & ENDLOCAL & set __save_smarty_errorlevel=%errorlevel%")
3069 // ZIP up the smarty output, no matter what the smarty result.
3070 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')\"")
3072 addCommand("echo %errorlevel%")
3073 addCommand("dir .\\bin\\tests\\${osGroup}.${architecture}.${configuration}")
3075 // Use the smarty errorlevel as the script errorlevel.
3076 addCommand("exit /b %__save_smarty_errorlevel%")
3078 batchFile(buildCommands)
3079 } // non-corefx testing
3083 if (!isCoreFxScenario(scenario)) {
3084 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0/*.smrt", '', true, false)
3086 // Archive a ZIP file of the entire Smarty.run.0 directory. This is possibly a little too much,
3087 // but there is no easy way to only archive the HTML/TXT files of the failing tests, so we get
3088 // all the passing test info as well. Not necessarily a bad thing, but possibly somewhat large.
3089 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0.zip", '', true, false)
3095 // Create a test job not covered by the "Windows ARM" case that will be used by a flow job.
3096 // E.g., non-Windows tests.
3097 // Returns the newly created job.
3098 def static CreateOtherTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3100 def isUbuntuArmJob = (os == "Ubuntu") && ((architecture == 'arm') || (architecture == 'arm64')) // ARM Ubuntu running on hardware (not emulator)
3101 def doCoreFxTesting = isCoreFxScenario(scenario)
3103 def workspaceRelativeFxRootLinux = "_/fx" // only used for CoreFX testing
3105 def osGroup = getOSGroup(os)
3106 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3109 def useServerGC = false
3111 // Enable Server GC for Ubuntu PR builds
3112 // REVIEW: why? Does this apply to all architectures? Why only PR?
3113 if (os == 'Ubuntu' && isPR) {
3114 testOpts += ' --useServerGC'
3118 if (isR2RScenario(scenario)) {
3120 testOpts += ' --crossgen --runcrossgentests'
3122 if (scenario == 'r2r_jitstress1') {
3123 testOpts += ' --jitstress=1'
3125 else if (scenario == 'r2r_jitstress2') {
3126 testOpts += ' --jitstress=2'
3128 else if (scenario == 'r2r_jitstress1_tiered') {
3129 testOpts += ' --jitstress=1'
3131 else if (scenario == 'r2r_jitstress2_tiered') {
3132 testOpts += ' --jitstress=2'
3134 else if (scenario == 'r2r_jitstressregs1') {
3135 testOpts += ' --jitstressregs=1'
3137 else if (scenario == 'r2r_jitstressregs2') {
3138 testOpts += ' --jitstressregs=2'
3140 else if (scenario == 'r2r_jitstressregs3') {
3141 testOpts += ' --jitstressregs=3'
3143 else if (scenario == 'r2r_jitstressregs4') {
3144 testOpts += ' --jitstressregs=4'
3146 else if (scenario == 'r2r_jitstressregs8') {
3147 testOpts += ' --jitstressregs=8'
3149 else if (scenario == 'r2r_jitstressregs0x10') {
3150 testOpts += ' --jitstressregs=0x10'
3152 else if (scenario == 'r2r_jitstressregs0x80') {
3153 testOpts += ' --jitstressregs=0x80'
3155 else if (scenario == 'r2r_jitstressregs0x1000') {
3156 testOpts += ' --jitstressregs=0x1000'
3158 else if (scenario == 'r2r_jitminopts') {
3159 testOpts += ' --jitminopts'
3161 else if (scenario == 'r2r_jitforcerelocs') {
3162 testOpts += ' --jitforcerelocs'
3164 else if (scenario == 'r2r_gcstress15') {
3165 testOpts += ' --gcstresslevel=0xF'
3168 else if (scenario == 'jitdiff') {
3169 testOpts += ' --jitdisasm --crossgen'
3171 else if (scenario == 'illink') {
3172 testOpts += ' --link=\$WORKSPACE/linker/linker/bin/netcore_Release/netcoreapp2.0/ubuntu-x64/publish/illink'
3174 else if (isLongGc(scenario)) {
3175 // Long GC tests behave very poorly when they are not
3176 // the only test running (many of them allocate until OOM).
3177 testOpts += ' --sequential'
3179 // A note - runtest.sh does have "--long-gc" and "--gcsimulator" options
3180 // for running long GC and GCSimulator tests, respectively. We don't use them
3181 // here because using a playlist file produces much more readable output on the CI machines
3182 // and reduces running time.
3184 // The Long GC playlist contains all of the tests that are
3185 // going to be run. The GCSimulator playlist contains all of
3186 // the GC simulator tests.
3187 if (scenario == 'longgc') {
3188 testOpts += ' --long-gc --playlist=./tests/longRunningGcTests.txt'
3190 else if (scenario == 'gcsimulator') {
3191 testOpts += ' --gcsimulator --playlist=./tests/gcSimulatorTests.txt'
3194 else if (isGcReliabilityFramework(scenario)) {
3195 testOpts += ' --build-overlay-only'
3197 else if (scenario == 'standalone_gc') {
3198 if (osGroup == 'OSX') {
3199 testOpts += ' --gcname=libclrgc.dylib'
3201 else if (osGroup == 'Linux') {
3202 testOpts += ' --gcname=libclrgc.so'
3205 println("Unexpected OS group: ${osGroup} for os ${os}")
3210 // The ARM Ubuntu corefx test job doesn't depend on a Windows test build, and hence inputTestsBuildName
3211 // will be null in this case.
3213 def jobFolder = getJobFolder(scenario)
3214 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3216 if (inputTestsBuildName != null) {
3217 stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR Windows test binaries from')
3219 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3223 // Set up the copies
3225 // Coreclr build containing the tests and mscorlib
3226 // pri1 jobs still need to copy windows_nt built tests
3227 if (inputTestsBuildName != null) {
3228 copyArtifacts(inputTestsBuildName) {
3229 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3231 buildNumber('${CORECLR_WINDOWS_BUILD}')
3236 // Coreclr build we are trying to test
3238 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
3240 copyArtifacts(inputCoreCLRBuildName) {
3241 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3243 buildNumber('${CORECLR_BUILD}')
3247 if (isUbuntuArmJob) {
3248 // Add some useful information to the log file. Ignore return codes.
3249 shell("uname -a || true")
3252 if (architecture == 'x86') {
3253 shell("mkdir ./bin/CoreFxNative")
3255 def fxBranch = getFxBranch(branch)
3256 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' + Utilities.getFolderName(fxBranch)
3258 copyArtifacts("${corefxFolder}/ubuntu16.04_x86_release") {
3259 includePatterns('bin/build.tar.gz')
3260 targetDirectory('bin/CoreFxNative')
3262 latestSuccessful(true)
3266 shell("mkdir ./bin/CoreFxBinDir")
3267 shell("tar -xf ./bin/CoreFxNative/bin/build.tar.gz -C ./bin/CoreFxBinDir")
3270 // CoreFX testing downloads the CoreFX tests, not the coreclr tests. Also, unzip the built CoreFX layout/runtime directories.
3271 if (doCoreFxTesting) {
3272 shell("unzip -o ${workspaceRelativeFxRootLinux}/fxtests.zip || exit 0")
3273 shell("unzip -o ${workspaceRelativeFxRootLinux}/fxruntime.zip || exit 0")
3276 // Unzip the tests first. Exit with 0
3277 shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/${osGroup}.${architecture}.${configuration} || exit 0")
3278 shell("rm -r ./bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root || exit 0")
3281 // For arm Ubuntu (on hardware), we do the "build-test" step on the build machine, not on the test
3282 // machine. The arm Ubuntu test machines do no building -- they have no CLI, for example.
3283 // We should probably do the "generatelayoutonly" step on the build machine for all architectures.
3284 // However, it's believed that perhaps there's an issue with executable permission bits not getting
3285 // copied correctly.
3286 if (!doCoreFxTesting) {
3287 if (isUbuntuArmJob) {
3288 def lowerConfiguration = configuration.toLowerCase()
3289 shell("unzip -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root
3290 shell("unzip -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3293 shell("./build-test.sh ${architecture} ${configuration} generatelayoutonly")
3297 // Execute the tests
3298 def runDocker = isNeedDocker(architecture, os, false)
3299 def dockerPrefix = ""
3302 def dockerImage = getDockerImageName(architecture, os, false)
3303 dockerPrefix = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} "
3304 dockerCmd = dockerPrefix + "${dockerImage} "
3307 // If we are running a stress mode, we'll set those variables first.
3308 // For CoreFX, the stress variables are already built into the CoreFX test build per-test wrappers.
3309 if (!doCoreFxTesting && isJitStressScenario(scenario)) {
3310 def scriptFileName = "\${WORKSPACE}/set_stress_test_env.sh"
3311 def envScriptCmds = envScriptCreate(os, scriptFileName)
3312 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
3313 envScriptCmds += envScriptFinalize(os, scriptFileName)
3314 shell("${envScriptCmds}")
3315 testOpts += " --test-env=${scriptFileName}"
3318 // setup-stress-dependencies.sh, invoked by runtest.sh to download the coredistools package, depends on the "dotnet"
3319 // tool downloaded by the "init-tools.sh" script. However, it only invokes setup-stress-dependencies.sh for x64. The
3320 // coredistools package is used by GCStress on x86 and x64 to disassemble code to determine instruction boundaries.
3321 // On arm/arm64, it is not required as determining instruction boundaries is trivial.
3322 if (isGCStressRelatedTesting(scenario)) {
3323 if (architecture == 'x64') {
3324 shell('./init-tools.sh')
3328 if (doCoreFxTesting) {
3330 \${WORKSPACE}/${workspaceRelativeFxRootLinux}/run-test.sh --sequential --test-exclude-file \${WORKSPACE}/tests/${architecture}/corefx_linux_test_exclusions.txt --runtime \${WORKSPACE}/${workspaceRelativeFxRootLinux}/bin/testhost/netcoreapp-Linux-Release-${architecture} --arch ${architecture} --corefx-tests \${WORKSPACE}/${workspaceRelativeFxRootLinux}/bin --configurationGroup Release""")
3333 def runScript = "${dockerCmd}./tests/runtest.sh"
3337 --testRootDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}\" \\
3338 --coreOverlayDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root\" \\
3339 --testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
3340 --copyNativeTestBin --limitedDumpGeneration ${testOpts}""")
3343 if (isGcReliabilityFramework(scenario)) {
3344 // runtest.sh doesn't actually execute the reliability framework - do it here.
3347 dockerCmd = dockerPrefix + "-e COMPlus_gcServer=1 ${dockerImage} "
3350 shell("export COMPlus_gcServer=1")
3354 shell("${dockerCmd}./tests/scripts/run-gc-reliability-framework.sh ${architecture} ${configuration}")
3359 // Experimental: If on Ubuntu 14.04, then attempt to pull in crash dump links
3360 if (os in ['Ubuntu']) {
3361 SummaryBuilder summaries = new SummaryBuilder()
3362 summaries.addLinksSummaryFromFile('Crash dumps from this run:', 'dumplings.txt')
3363 summaries.emit(newJob)
3366 if (doCoreFxTesting) {
3367 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3368 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3371 Utilities.addXUnitDotNETResults(newJob, '**/coreclrtests.xml')
3377 // Create a test job that will be used by a flow job.
3378 // Returns the newly created job.
3379 // Note that we don't add tests jobs to the various views, since they are always used by a flow job, which is in the views,
3380 // and we want the views to be the minimal set of "top-level" jobs that represent all work.
3381 def static CreateTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3383 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3386 if (windowsArmJob) {
3387 assert inputTestsBuildName == null
3388 newJob = CreateWindowsArmTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3390 newJob = CreateOtherTestJob(dslFactory, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3393 setJobMachineAffinity(architecture, os, false, true, false, newJob) // isBuildJob = false, isTestJob = true, isFlowJob = false
3395 if (scenario == 'jitdiff') {
3396 def osGroup = getOSGroup(os)
3397 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/dasm/**")
3400 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
3401 setJobTimeout(newJob, isPR, architecture, configuration, scenario, false)
3406 // Create a flow job to tie together a build job with the given test job.
3407 // The 'inputTestsBuildName' argument might be null if the flow job doesn't depend on a Windows build job.
3408 // Returns the new flow job.
3409 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)
3411 // Windows CoreCLR build and Linux CoreCLR build (in parallel) ->
3412 // Linux CoreCLR test
3413 def flowJobName = getJobName(configuration, architecture, os, scenario, false) + "_flow"
3414 def jobFolder = getJobFolder(scenario)
3416 def newFlowJob = null
3418 if (inputTestsBuildName == null) {
3419 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3421 coreclrBuildJob = build(params, '${inputCoreCLRBuildName}')
3423 // And then build the test build
3424 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number], '${fullTestJobName}')
3427 JobReport.Report.addReference(inputCoreCLRBuildName)
3428 JobReport.Report.addReference(fullTestJobName)
3431 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3433 // Build the input jobs in parallel
3435 { coreclrBuildJob = build(params, '${inputCoreCLRBuildName}') },
3436 { windowsBuildJob = build(params, '${inputTestsBuildName}') }
3439 // And then build the test build
3440 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number,
3441 CORECLR_WINDOWS_BUILD: windowsBuildJob.build.number], '${fullTestJobName}')
3444 JobReport.Report.addReference(inputCoreCLRBuildName)
3445 JobReport.Report.addReference(inputTestsBuildName)
3446 JobReport.Report.addReference(fullTestJobName)
3449 addToViews(newFlowJob, isPR, architecture, os)
3451 setJobMachineAffinity(architecture, os, false, false, true, newFlowJob) // isBuildJob = false, isTestJob = false, isFlowJob = true
3453 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
3454 addTriggers(newFlowJob, branch, isPR, architecture, os, configuration, scenario, true, false) // isFlowJob==true, isWindowsBuildOnlyJob==false
3459 // Determine if we should generate a flow job for the given parameters.
3460 // Returns true if the job should be generated.
3461 def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def configuration, def os)
3463 // The "innerloop" (Pri-0 testing) scenario is only available as PR triggered.
3464 if (scenario == 'innerloop' && !isPR) {
3468 if (scenario == 'corefx_innerloop') {
3472 // Filter based on OS and architecture.
3474 switch (architecture) {
3477 if (os != "Ubuntu" && os != "Windows_NT") {
3482 if (os != "Ubuntu") {
3487 if (!(os in Constants.crossList)) {
3490 if (os == "Windows_NT") {
3495 case 'x86_arm_altjit':
3496 case 'x64_arm64_altjit':
3500 println("Unknown architecture: ${architecture}")
3505 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
3507 // Filter based on scenario in OS.
3509 if (os == 'Windows_NT') {
3510 assert architecture == 'arm' || architecture == 'arm64'
3511 if (!isArmWindowsScenario(scenario)) {
3514 if (isNormalOrInnerloop && (configuration == 'Debug')) {
3515 // The arm32/arm64 Debug configuration for innerloop/normal scenario is a special case: it does a build only, and no test run.
3516 // To do that, it doesn't require a flow job.
3522 if (architecture == 'arm64') {
3523 if (!(scenario in Constants.validLinuxArm64Scenarios)) {
3527 if (isNormalOrInnerloop && (configuration == 'Debug')) {
3528 // The arm32/arm64 Debug configuration for innerloop/normal scenario is a special case: it does a build only, and no test run.
3529 // To do that, it doesn't require a flow job.
3533 else if (architecture == 'arm') {
3534 if (!(scenario in Constants.validLinuxArmScenarios)) {
3538 else if (architecture == 'x86') {
3539 // Linux/x86 only want innerloop and default test
3540 if (!isNormalOrInnerloop) {
3544 else if (architecture == 'x64') {
3545 // Linux/x64 corefx testing doesn't need a flow job; the "build" job runs run-corefx-tests.py which
3546 // builds and runs the corefx tests. Other Linux/x64 flow jobs are required to get the test
3547 // build from a Windows machine.
3548 if (isCoreFxScenario(scenario)) {
3554 // For CentOS, we only want Checked/Release builds.
3555 if (os == 'CentOS7.1') {
3556 if (configuration != 'Checked' && configuration != 'Release') {
3559 if (!isNormalOrInnerloop && !isR2RScenario(scenario)) {
3564 // For RedHat and Debian, we only do Release builds.
3565 else if (os == 'RHEL7.2' || os == 'Debian8.4') {
3566 if (configuration != 'Release') {
3569 if (!isNormalOrInnerloop) {
3574 // Next, filter based on scenario.
3576 if (isJitStressScenario(scenario)) {
3577 if (configuration != 'Checked') {
3581 else if (isR2RBaselineScenario(scenario)) {
3582 if (configuration != 'Checked' && configuration != 'Release') {
3586 else if (isR2RStressScenario(scenario)) {
3587 if (configuration != 'Checked') {
3597 // Long GC tests take a long time on non-Release builds
3598 // ilrt is also Release only
3599 if (configuration != 'Release') {
3605 if (configuration != 'Checked') {
3610 case 'gc_reliability_framework':
3611 case 'standalone_gc':
3612 if (configuration != 'Release' && configuration != 'Checked') {
3621 if (os != 'Windows_NT' && os != 'Ubuntu') {
3631 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, false)) {
3637 println("Unknown scenario: ${scenario}")
3643 // The job was not filtered out, so we should generate it!
3647 // Create jobs requiring flow jobs. This includes x64 non-Windows, arm/arm64 Ubuntu, and arm/arm64 Windows.
3648 Constants.allScenarios.each { scenario ->
3649 [true, false].each { isPR ->
3650 Constants.architectureList.each { architecture ->
3651 Constants.configurationList.each { configuration ->
3652 Constants.osList.each { os ->
3654 if (!shouldGenerateFlowJob(scenario, isPR, architecture, configuration, os)) {
3658 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3659 def doCoreFxTesting = isCoreFxScenario(scenario)
3661 // Figure out the job name of the CoreCLR build the test will depend on.
3663 def inputCoreCLRBuildScenario = isPri0TestScenario(scenario) ? 'innerloop' : 'normal'
3664 def inputCoreCLRBuildIsBuildOnly = false
3665 if (doCoreFxTesting) {
3666 // Every CoreFx test depends on its own unique build.
3667 inputCoreCLRBuildScenario = scenario
3668 if (windowsArmJob) {
3669 // Only Windows ARM corefx jobs use "build only" jobs. Others, such as Ubuntu ARM corefx, use "regular" jobs.
3670 inputCoreCLRBuildIsBuildOnly = true
3673 def inputCoreCLRFolderName = getJobFolder(inputCoreCLRBuildScenario)
3674 def inputCoreCLRBuildName = projectFolder + '/' +
3675 Utilities.getFullJobName(project, getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, inputCoreCLRBuildIsBuildOnly), isPR, inputCoreCLRFolderName)
3677 // Figure out the name of the build job that the test job will depend on.
3678 // For Windows ARM tests, this is not used, as the CoreCLR build creates the tests. For other
3679 // tests (e.g., Linux ARM), we depend on a Windows build to get the tests.
3680 // For CoreFX tests, however, Linux doesn't need the Windows build for the tests, since the
3681 // CoreFX build creates the tests.
3683 def inputTestsBuildName = null
3685 if (!windowsArmJob && !doCoreFxTesting) {
3686 def testBuildScenario = isPri0TestScenario(scenario) ? 'innerloop' : 'normal'
3688 def inputTestsBuildArch = architecture
3689 if (architecture == "arm64") {
3690 // Use the x64 test build for arm64 unix
3691 inputTestsBuildArch = "x64"
3693 else if (architecture == "arm") {
3694 // Use the x86 test build for arm unix
3695 inputTestsBuildArch = "x86"
3698 def inputTestsBuildIsBuildOnly = true
3700 inputTestsBuildName = projectFolder + '/' +
3701 Utilities.getFullJobName(project, getJobName(configuration, inputTestsBuildArch, 'windows_nt', testBuildScenario, inputTestsBuildIsBuildOnly), isPR)
3704 // =============================================================================================
3705 // Create the test job
3706 // =============================================================================================
3708 def testJob = CreateTestJob(this, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3710 // =============================================================================================
3711 // Create a build flow to join together the build and tests required to run this test.
3712 // =============================================================================================
3714 if (os == 'RHEL7.2' || os == 'Debian8.4') {
3715 // Do not create the flow job for RHEL jobs.
3719 def fullTestJobName = projectFolder + '/' + testJob.name
3720 def flowJob = CreateFlowJob(this, project, branch, architecture, os, configuration, scenario, isPR, fullTestJobName, inputCoreCLRBuildName, inputTestsBuildName)
3728 JobReport.Report.generateJobReport(out)
3730 // Make the call to generate the help job
3731 Utilities.createHelperJob(this, project, branch,
3732 "Welcome to the ${project} Repository", // This is prepended to the help message
3733 "Have a nice day!") // This is appended to the help message. You might put known issues here.
3735 Utilities.addCROSSCheck(this, project, branch)