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',
21 'Ubuntu16.04' : 'Linux',
22 'Ubuntu16.10' : 'Linux',
24 'Debian8.4' : 'Linux',
26 'CentOS7.1' : 'Linux',
29 'Windows_NT' : 'Windows_NT']
30 def osGroup = osGroupMap.get(os, null)
31 assert osGroup != null : "Could not find os group for ${os}"
35 def static getCrossArchitectures(def os, def architecture, def scenario) {
36 switch (architecture) {
47 // We use this class (vs variables) so that the static functions can access data here.
50 // We have very limited Windows ARM64 hardware (used for ARM/ARM64 testing) and Linux/arm32 and Linux/arm64 hardware.
51 // So only allow certain branches to use it.
52 def static LimitedHardwareBranches = [
55 // Innerloop build OS's
56 // The Windows_NT_BuildOnly OS is a way to speed up the Non-Windows builds by avoiding
57 // test execution in the build flow runs. It generates the exact same build
58 // as Windows_NT but without running the tests.
64 'Windows_NT_BuildOnly',
72 def static crossList = [
80 // This is a set of JIT stress modes combined with the set of variables that
81 // need to be set to actually enable that stress mode. The key of the map is the stress mode and
82 // the values are the environment variables
83 def static jitStressModeScenarios = [
84 'minopts' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JITMinOpts' : '1'],
85 'tieredcompilation' : ['COMPlus_TieredCompilation' : '1'], // this can be removed once tiered compilation is on by default
86 'no_tiered_compilation' : ['COMPlus_TieredCompilation' : '0'],
87 'no_tiered_compilation_innerloop': ['COMPlus_TieredCompilation' : '0'],
88 'forcerelocs' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_ForceRelocs' : '1'],
89 'jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '1'],
90 'jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2'],
91 'jitstress1_tiered' : ['COMPlus_TieredCompilation' : '1', 'COMPlus_JitStress' : '1'],
92 'jitstress2_tiered' : ['COMPlus_TieredCompilation' : '1', 'COMPlus_JitStress' : '2'],
93 'jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '1'],
94 'jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '2'],
95 'jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '3'],
96 'jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '4'],
97 'jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '8'],
98 'jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x10'],
99 'jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x80'],
100 'jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x1000'],
101 'jitstress2_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '1'],
102 'jitstress2_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '2'],
103 'jitstress2_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '3'],
104 'jitstress2_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '4'],
105 'jitstress2_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '8'],
106 'jitstress2_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x10'],
107 'jitstress2_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x80'],
108 'jitstress2_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x1000'],
109 'tailcallstress' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_TailcallStress' : '1'],
110 'jitsse2only' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableAVX' : '0', 'COMPlus_EnableSSE3_4' : '0'],
111 'jitnosimd' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_FeatureSIMD' : '0'],
112 'jitincompletehwintrinsic' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1'],
113 'jitx86hwintrinsicnoavx' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX' : '0'], // testing the legacy SSE encoding
114 'jitx86hwintrinsicnoavx2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX2' : '0'], // testing SNB/IVB
115 'jitx86hwintrinsicnosimd' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_FeatureSIMD' : '0'], // match "jitnosimd", may need to remove after decoupling HW intrinsic from FeatureSIMD
116 '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'],
117 'corefx_baseline' : ['COMPlus_TieredCompilation' : '0'], // corefx baseline
118 'corefx_minopts' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JITMinOpts' : '1'],
119 'corefx_tieredcompilation' : ['COMPlus_TieredCompilation' : '1'], // this can be removed once tiered compilation is on by default
120 'corefx_jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '1'],
121 'corefx_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2'],
122 'corefx_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '1'],
123 'corefx_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '2'],
124 'corefx_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '3'],
125 'corefx_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '4'],
126 'corefx_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '8'],
127 'corefx_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x10'],
128 'corefx_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x80'],
129 'corefx_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x1000'],
130 'gcstress0x3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0x3'],
131 'gcstress0xc' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC'],
132 'zapdisable' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
133 'heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_HeapVerify' : '1'],
134 'gcstress0xc_zapdisable' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
135 'gcstress0xc_zapdisable_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_JitStress' : '2'],
136 'gcstress0xc_zapdisable_heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_HeapVerify' : '1'],
137 'gcstress0xc_jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '1'],
138 'gcstress0xc_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '2'],
139 'gcstress0xc_minopts_heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JITMinOpts' : '1', 'COMPlus_HeapVerify' : '1']
142 // This is a set of ReadyToRun stress scenarios
143 def static r2rStressScenarios = [
144 'r2r_jitstress1' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStress": "1"],
145 'r2r_jitstress2' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStress": "2"],
146 'r2r_jitstress1_tiered' : ['COMPlus_TieredCompilation' : '1', "COMPlus_JitStress": "1"],
147 'r2r_jitstress2_tiered' : ['COMPlus_TieredCompilation' : '1', "COMPlus_JitStress": "2"],
148 'r2r_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "1"],
149 'r2r_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "2"],
150 'r2r_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "3"],
151 'r2r_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "4"],
152 'r2r_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "8"],
153 'r2r_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x10"],
154 'r2r_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x80"],
155 'r2r_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x1000"],
156 'r2r_jitminopts' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JITMinOpts": "1"],
157 'r2r_jitforcerelocs' : ['COMPlus_TieredCompilation' : '0', "COMPlus_ForceRelocs": "1"],
158 'r2r_gcstress15' : ['COMPlus_TieredCompilation' : '0', "COMPlus_GCStress": "0xF"],
159 'r2r_no_tiered_compilation' : ['COMPlus_TieredCompilation' : '0'],
162 // This is the basic set of scenarios
163 def static basicScenarios = [
171 // 'jitdiff', // jitdiff is currently disabled, until someone spends the effort to make it fully work
173 'gc_reliability_framework',
176 'crossgen_comparison']
178 def static allScenarios = basicScenarios + r2rStressScenarios.keySet() + jitStressModeScenarios.keySet()
180 // Valid PR trigger combinations.
181 def static prTriggeredValidInnerLoopCombos = [
199 'Windows_NT_BuildOnly': [
243 // A set of scenarios that are valid for arm/arm64 tests run on hardware. This is a map from valid scenario name
244 // to Tests.lst file categories to exclude.
246 // This list should contain a subset of the scenarios from `allScenarios`. Please keep this in the same order as that,
247 // and with the same values, with some commented out, for easier maintenance.
249 // Note that some scenarios that are commented out should be enabled, but haven't yet been.
251 def static validArmWindowsScenarios = [
255 'r2r': ["R2R_FAIL", "R2R_EXCLUDE"],
261 // 'gc_reliability_framework'
263 // 'corefx_innerloop'
264 // 'crossgen_comparison'
265 'r2r_jitstress1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
266 'r2r_jitstress2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
267 'r2r_jitstress1_tiered': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
268 'r2r_jitstress2_tiered': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
269 'r2r_jitstressregs1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
270 'r2r_jitstressregs2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
271 'r2r_jitstressregs3': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
272 'r2r_jitstressregs4': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
273 'r2r_jitstressregs8': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
274 'r2r_jitstressregs0x10': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
275 'r2r_jitstressregs0x80': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
276 'r2r_jitstressregs0x1000': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
277 'r2r_jitminopts': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
278 'r2r_jitforcerelocs': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
279 'r2r_gcstress15': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
280 'r2r_no_tiered_compilation': ["R2R_FAIL", "R2R_EXCLUDE"],
281 'minopts': ["MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
282 'tieredcompilation': [],
283 'no_tiered_compilation': [],
284 'no_tiered_compilation_innerloop': [],
286 'jitstress1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
287 'jitstress2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
288 'jitstress1_tiered': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
289 'jitstress2_tiered': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
290 'jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
291 'jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
292 'jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
293 'jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
294 'jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
295 'jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
296 'jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
297 'jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
298 'jitstress2_jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
299 'jitstress2_jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
300 'jitstress2_jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
301 'jitstress2_jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
302 'jitstress2_jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
303 'jitstress2_jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
304 'jitstress2_jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
305 'jitstress2_jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
306 'tailcallstress': ["TAILCALLSTRESS_FAIL", "TAILCALLSTRESS_EXCLUDE"],
307 // 'jitsse2only' // Only relevant to xarch
308 'jitnosimd': [], // Only interesting on platforms where SIMD support exists.
309 // 'jitincompletehwintrinsic'
310 // 'jitx86hwintrinsicnoavx'
311 // 'jitx86hwintrinsicnoavx2'
312 // 'jitx86hwintrinsicnosimd'
313 // 'jitnox86hwintrinsic'
314 'corefx_baseline': [], // corefx tests don't use smarty
315 'corefx_minopts': [], // corefx tests don't use smarty
316 'corefx_tieredcompilation': [], // corefx tests don't use smarty
317 'corefx_jitstress1': [], // corefx tests don't use smarty
318 'corefx_jitstress2': [], // corefx tests don't use smarty
319 'corefx_jitstressregs1': [], // corefx tests don't use smarty
320 'corefx_jitstressregs2': [], // corefx tests don't use smarty
321 'corefx_jitstressregs3': [], // corefx tests don't use smarty
322 'corefx_jitstressregs4': [], // corefx tests don't use smarty
323 'corefx_jitstressregs8': [], // corefx tests don't use smarty
324 'corefx_jitstressregs0x10': [], // corefx tests don't use smarty
325 'corefx_jitstressregs0x80': [], // corefx tests don't use smarty
326 'corefx_jitstressregs0x1000': [], // corefx tests don't use smarty
327 'gcstress0x3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
328 'gcstress0xc': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
329 'zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
331 'gcstress0xc_zapdisable': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
332 'gcstress0xc_zapdisable_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
333 'gcstress0xc_zapdisable_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
334 'gcstress0xc_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
335 'gcstress0xc_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
336 'gcstress0xc_minopts_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
339 // NOTE: the following scenarios are not defined in the 'allScenarios' list! Is this a bug?
342 'minopts_zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
343 'gcstress0x3_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
344 'gcstress0x3_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
345 'gcstress0x3_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
346 'gcstress0x3_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
347 'gcstress0x3_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
348 'gcstress0x3_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
349 'gcstress0x3_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
350 'gcstress0x3_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
351 'gcstress0x3_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
352 'gcstress0x3_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
353 'gcstress0xc_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
354 'gcstress0xc_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
355 'gcstress0xc_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
356 'gcstress0xc_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
357 'gcstress0xc_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
358 'gcstress0xc_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
359 'gcstress0xc_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
360 'gcstress0xc_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"]
363 def static validLinuxArmScenarios = [
373 // 'gc_reliability_framework'
375 // 'corefx_innerloop'
376 'crossgen_comparison',
379 'r2r_jitstress1_tiered',
380 'r2r_jitstress2_tiered',
381 'r2r_jitstressregs1',
382 'r2r_jitstressregs2',
383 'r2r_jitstressregs3',
384 'r2r_jitstressregs4',
385 'r2r_jitstressregs8',
386 'r2r_jitstressregs0x10',
387 'r2r_jitstressregs0x80',
388 'r2r_jitstressregs0x1000',
390 'r2r_jitforcerelocs',
392 'r2r_no_tiered_compilation',
395 'no_tiered_compilation',
396 'no_tiered_compilation_innerloop',
409 'jitstressregs0x1000',
410 'jitstress2_jitstressregs1',
411 'jitstress2_jitstressregs2',
412 'jitstress2_jitstressregs3',
413 'jitstress2_jitstressregs4',
414 'jitstress2_jitstressregs8',
415 'jitstress2_jitstressregs0x10',
416 'jitstress2_jitstressregs0x80',
417 'jitstress2_jitstressregs0x1000',
419 // 'jitsse2only' // Only relevant to xarch
420 // 'jitnosimd' // Only interesting on platforms where SIMD support exists.
421 // 'jitincompletehwintrinsic'
422 // 'jitx86hwintrinsicnoavx'
423 // 'jitx86hwintrinsicnoavx2'
424 // 'jitx86hwintrinsicnosimd'
425 // 'jitnox86hwintrinsic'
428 'corefx_tieredcompilation',
431 'corefx_jitstressregs1',
432 'corefx_jitstressregs2',
433 'corefx_jitstressregs3',
434 'corefx_jitstressregs4',
435 'corefx_jitstressregs8',
436 'corefx_jitstressregs0x10',
437 'corefx_jitstressregs0x80',
438 'corefx_jitstressregs0x1000',
443 'gcstress0xc_zapdisable',
444 'gcstress0xc_zapdisable_jitstress2',
445 'gcstress0xc_zapdisable_heapverify1',
446 'gcstress0xc_jitstress1',
447 'gcstress0xc_jitstress2',
448 'gcstress0xc_minopts_heapverify1'
451 def static validLinuxArm64Scenarios = [
461 // 'gc_reliability_framework'
463 // 'corefx_innerloop'
464 // 'crossgen_comparison'
467 'r2r_jitstress1_tiered',
468 'r2r_jitstress2_tiered',
469 'r2r_jitstressregs1',
470 'r2r_jitstressregs2',
471 'r2r_jitstressregs3',
472 'r2r_jitstressregs4',
473 'r2r_jitstressregs8',
474 'r2r_jitstressregs0x10',
475 'r2r_jitstressregs0x80',
476 'r2r_jitstressregs0x1000',
478 'r2r_jitforcerelocs',
480 'r2r_no_tiered_compilation',
483 'no_tiered_compilation',
484 'no_tiered_compilation_innerloop',
497 'jitstressregs0x1000',
498 'jitstress2_jitstressregs1',
499 'jitstress2_jitstressregs2',
500 'jitstress2_jitstressregs3',
501 'jitstress2_jitstressregs4',
502 'jitstress2_jitstressregs8',
503 'jitstress2_jitstressregs0x10',
504 'jitstress2_jitstressregs0x80',
505 'jitstress2_jitstressregs0x1000',
507 // 'jitsse2only' // Only relevant to xarch
508 'jitnosimd', // Only interesting on platforms where SIMD support exists.
509 // 'jitincompletehwintrinsic'
510 // 'jitx86hwintrinsicnoavx'
511 // 'jitx86hwintrinsicnoavx2'
512 // 'jitx86hwintrinsicnosimd'
513 // 'jitnox86hwintrinsic'
516 'corefx_tieredcompilation',
519 'corefx_jitstressregs1',
520 'corefx_jitstressregs2',
521 'corefx_jitstressregs3',
522 'corefx_jitstressregs4',
523 'corefx_jitstressregs8',
524 'corefx_jitstressregs0x10',
525 'corefx_jitstressregs0x80',
526 'corefx_jitstressregs0x1000',
531 'gcstress0xc_zapdisable',
532 'gcstress0xc_zapdisable_jitstress2',
533 'gcstress0xc_zapdisable_heapverify1',
534 'gcstress0xc_jitstress1',
535 'gcstress0xc_jitstress2',
536 'gcstress0xc_minopts_heapverify1'
539 def static configurationList = ['Debug', 'Checked', 'Release']
541 // This is the set of architectures
542 // Some of these are pseudo-architectures:
543 // armem -- ARM builds/runs using an emulator. Used for Tizen runs.
544 // x86_arm_altjit -- ARM runs on x86 using the ARM altjit
545 // x64_arm64_altjit -- ARM64 runs on x64 using the ARM64 altjit
546 def static architectureList = ['arm', 'armem', 'x86_arm_altjit', 'x64_arm64_altjit', 'arm64', 'x64', 'x86']
548 // This set of architectures that cross build on Windows and run on Windows ARM64 hardware.
549 def static armWindowsCrossArchitectureList = ['arm', 'arm64']
552 // **************************************************************
553 // Create some specific views
555 // These aren't using the Utilities.addStandardFolderView() function, because that creates
556 // views based on a single regular expression. These views will be generated by adding a
557 // specific set of jobs to them.
559 // Utilities.addStandardFolderView() also creates a lot of additional stuff around the
560 // view, like "Build Statistics", "Job Statistics", "Unstable Jobs". Until it is determined
561 // those are required, don't add them (which simplifies the view pages, as well).
562 // **************************************************************
565 def static MergeJobView = null
566 def static PeriodicJobView = null
567 def static ArchitectureViews = [:]
568 def static OSViews = [:]
571 // MergeJobView: include all jobs that execute when a PR change is merged.
572 Views.MergeJobView = listView('Merge') {
585 // PeriodicJobView: include all jobs that execute on a schedule
586 Views.PeriodicJobView = listView('Periodic') {
599 // Create a view for non-PR jobs for each architecture.
600 Constants.architectureList.each { architecture ->
601 Views.ArchitectureViews[architecture] = listView(architecture) {
615 // Create a view for non-PR jobs for each OS.
616 Constants.osList.each { os ->
617 // Don't create one for the special 'Windows_NT_BuildOnly'
618 if (os == 'Windows_NT_BuildOnly') {
621 Views.OSViews[os] = listView(os) {
635 def static addToMergeView(def job) {
636 Views.MergeJobView.with {
643 def static addToPeriodicView(def job) {
644 Views.PeriodicJobView.with {
651 def static addToViews(def job, def isFlowJob, def isPR, def architecture, def os, def configuration, def scenario) {
653 // No views want PR jobs currently.
657 // 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
658 // "top-level" jobs. Build only jobs are such jobs.
659 if (os == 'Windows_NT_BuildOnly') {
664 // For non-flow jobs, which ones are only used by flow jobs?
665 if ((architecture == 'arm') || (architecture == 'arm64')) {
666 if (isCoreFxScenario(scenario)) {
667 // We have corefx-specific scenario builds for each of the runs, but these are driven by flow jobs.
671 // We're left with the basic normal/innerloop builds. We might want to remove these from the views also, if desired.
672 // However, there are a few, like the Debug Build, that is build only, not "Build and Test", that we should leave.
676 // Add to architecture view.
677 Views.ArchitectureViews[architecture].with {
684 Views.OSViews[os].with {
691 def static addPeriodicTriggerHelper(def job, String cronString, boolean alwaysRuns = false) {
692 addToPeriodicView(job)
693 Utilities.addPeriodicTrigger(job, cronString, alwaysRuns)
696 def static addGithubPushTriggerHelper(def job) {
698 Utilities.addGithubPushTrigger(job)
702 def static setMachineAffinity(def job, def os, def architecture, def options = null) {
703 assert os instanceof String
704 assert architecture instanceof String
706 def armArches = ['arm', 'armem', 'arm64']
708 if (!(architecture in armArches)) {
709 assert options == null
710 Utilities.setMachineAffinity(job, os, 'latest-or-auto')
715 // This is an arm(64) job.
717 // There are several options.
721 // Arm32 (Build) -> latest-arm64
722 // |-> os == "Windows_NT" && (architecture == "arm") && options['use_arm64_build_machine'] == true
723 // Arm32 (Test) -> arm64-windows_nt
724 // |-> os == "Windows_NT" && (architecture == "arm") && options['use_arm64_build_machine'] == false
726 // Arm64 (Build) -> latest-arm64
727 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == true
728 // Arm64 (Test) -> arm64-windows_nt
729 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == false
733 // Arm32 emulator (Build, Test) -> arm-cross-latest
734 // |-> os == "Tizen" && (architecture == "armem")
736 // Arm32 hardware (Flow) -> Ubuntu 16.04 latest-or-auto (don't use limited arm hardware)
737 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_flow_job'] == true
738 // Arm32 hardware (Build) -> Ubuntu 16.04 latest-or-auto
739 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_build_job'] == true
740 // Arm32 hardware (Test) -> Helix ubuntu.1404.arm32.open queue
741 // |-> os == "Ubuntu" && (architecture == "arm")
743 // Arm64 (Build) -> arm64-cross-latest
744 // |-> os != "Windows_NT" && architecture == "arm64" && options['is_build_job'] == true
745 // Arm64 (Test) -> Helix Ubuntu.1604.Arm64.Open queue
746 // |-> os != "Windows_NT" && architecture == "arm64"
748 // Note: we are no longer using Jenkins tags "arm64-huge-page-size", "arm64-small-page-size".
749 // Support for Linux arm64 large page size has been removed for now, as it wasn't being used.
751 // Note: we are no longer using Jenkins tag 'latest-arm64' for arm/arm64 Windows build machines. Instead,
752 // we are using public VS2017 arm/arm64 tools in a VM from Helix.
754 // This has to be a arm arch
755 assert architecture in armArches
756 if (os == "Windows_NT") {
757 // arm32/arm64 Windows jobs share the same machines for now
758 def isBuild = options['use_arm64_build_machine'] == true
760 if (isBuild == true) {
762 label('Windows.10.Amd64.ClientRS4.DevEx.Open')
765 Utilities.setMachineAffinity(job, os, 'arm64-windows_nt')
768 assert os != 'Windows_NT'
770 if (architecture == 'armem') {
771 // arm emulator (Tizen). Build and test on same machine,
774 Utilities.setMachineAffinity(job, 'Ubuntu', 'arm-cross-latest')
777 // arm/arm64 Ubuntu on hardware.
778 assert architecture == 'arm' || architecture == 'arm64'
779 def isFlow = (options != null) && (options['is_flow_job'] == true)
780 def isBuild = (options != null) && (options['is_build_job'] == true)
781 if (isFlow || isBuild) {
782 // arm/arm64 Ubuntu build machine. Build uses docker, so the actual host OS is not
783 // very important. Therefore, use latest or auto. Flow jobs don't need to use arm hardware.
784 Utilities.setMachineAffinity(job, 'Ubuntu16.04', 'latest-or-auto')
786 // arm/arm64 Ubuntu test machine. Specify the Helix queue name here.
787 if (architecture == 'arm64') {
788 assert os == 'Ubuntu16.04'
790 label('Ubuntu.1604.Arm64.Open')
794 assert os == 'Ubuntu'
796 label('ubuntu.1404.arm32.open')
804 // setJobMachineAffinity: compute the machine affinity options for a job,
805 // then set the job with those affinity options.
806 def static setJobMachineAffinity(def architecture, def os, def isBuildJob, def isTestJob, def isFlowJob, def job)
808 assert (isBuildJob && !isTestJob && !isFlowJob) ||
809 (!isBuildJob && isTestJob && !isFlowJob) ||
810 (!isBuildJob && !isTestJob && isFlowJob)
812 def affinityOptions = null
813 def affinityArchitecture = architecture
815 if (os == "Windows_NT") {
816 if (architecture in Constants.armWindowsCrossArchitectureList) {
818 affinityOptions = [ "use_arm64_build_machine" : true ]
819 } else if (isTestJob) {
820 affinityOptions = [ "use_arm64_build_machine" : false ]
821 } else if (isFlowJob) {
822 // For the flow jobs set the machine affinity as x64
823 affinityArchitecture = 'x64'
828 if ((architecture == 'arm64') || (architecture == 'arm')) {
830 affinityOptions = ['is_build_job': true]
831 } else if (isFlowJob) {
832 affinityOptions = ['is_flow_job': true]
837 setMachineAffinity(job, os, affinityArchitecture, affinityOptions)
840 def static isGCStressRelatedTesting(def scenario) {
841 // The 'r2r_gcstress15' scenario is a basic scenario.
842 // Detect it and make it a GCStress related.
843 if (scenario == 'r2r_gcstress15')
848 def gcStressTestEnvVars = [ 'COMPlus_GCStress', 'COMPlus_ZapDisable', 'COMPlus_HeapVerify']
849 def scenarioName = scenario.toLowerCase()
850 def isGCStressTesting = false
851 Constants.jitStressModeScenarios[scenario].each{ k, v ->
852 if (k in gcStressTestEnvVars) {
853 isGCStressTesting = true;
856 return isGCStressTesting
859 def static isCoreFxScenario(def scenario) {
860 def corefx_prefix = 'corefx_'
861 if (scenario.length() < corefx_prefix.length()) {
864 return scenario.substring(0,corefx_prefix.length()) == corefx_prefix
867 def static isR2RBaselineScenario(def scenario) {
868 return (scenario == 'r2r')
871 def static isR2RStressScenario(def scenario) {
872 return Constants.r2rStressScenarios.containsKey(scenario)
875 def static isR2RScenario(def scenario) {
876 return isR2RBaselineScenario(scenario) || isR2RStressScenario(scenario)
879 def static isJitStressScenario(def scenario) {
880 return Constants.jitStressModeScenarios.containsKey(scenario)
883 def static isLongGc(def scenario) {
884 return (scenario == 'longgc' || scenario == 'gcsimulator')
887 def static isJitDiff(def scenario) {
888 return (scenario == 'jitdiff')
891 def static isGcReliabilityFramework(def scenario) {
892 return (scenario == 'gc_reliability_framework')
895 def static isArmWindowsScenario(def scenario) {
896 return Constants.validArmWindowsScenarios.containsKey(scenario)
899 def static isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly) {
900 if (isBuildOnly == true) {
901 os = 'Windows_NT_BuildOnly'
904 def validOsPrTriggerArchConfigs = Constants.prTriggeredValidInnerLoopCombos[os]
905 if (validOsPrTriggerArchConfigs != null) {
906 def validOsPrTriggerConfigs = validOsPrTriggerArchConfigs[architecture]
907 if (validOsPrTriggerConfigs != null) {
908 if (configuration in validOsPrTriggerConfigs) {
917 // This means the job builds and runs the 'innerloop' test set. This does not mean the job is
918 // scheduled with a default PR trigger despite the correlation being true at the moment.
919 def static isInnerloopTestScenario(def scenario) {
920 return (scenario == 'innerloop' || scenario == 'no_tiered_compilation_innerloop')
923 def static isCrossGenComparisonScenario(def scenario) {
924 return (scenario == 'crossgen_comparison')
927 def static shouldGenerateCrossGenComparisonJob(def os, def architecture, def configuration, def scenario) {
928 assert isCrossGenComparisonScenario(scenario)
929 return (os == 'Ubuntu' && architecture == 'arm' && configuration == 'Checked')
932 def static getFxBranch(def branch) {
933 def fxBranch = branch
934 // Map 'dev/unix_test_workflow' to 'master' so we can test CoreFX jobs in the CoreCLR dev/unix_test_workflow
935 // branch even though CoreFX doesn't have such a branch.
936 if (branch == 'dev/unix_test_workflow') {
942 def static setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly) {
943 // 2 hours (120 minutes) is the default timeout
946 if (!isInnerloopTestScenario(scenario)) {
947 // Pri-1 test builds take a long time (see calculateBuildCommands()). So up the Pri-1 build jobs timeout.
952 // Note that these can only increase, never decrease, the Pri-1 timeout possibly set above.
953 if (isGCStressRelatedTesting(scenario)) {
956 else if (isCoreFxScenario(scenario)) {
959 else if (isJitStressScenario(scenario)) {
962 else if (isR2RBaselineScenario(scenario)) {
965 else if (isLongGc(scenario)) {
968 else if (isJitDiff(scenario)) {
971 else if (isGcReliabilityFramework(scenario)) {
974 else if (architecture == 'armem' || architecture == 'arm64') {
978 if (architecture == 'arm') {
979 // ARM32 machines are particularly slow.
984 if (configuration == 'Debug') {
985 // Debug runs can be very slow. Add an hour.
989 if (architecture == 'x86_arm_altjit' || architecture == 'x64_arm64_altjit') {
990 // AltJit runs compile all methods twice.
994 // If we've changed the timeout from the default, set it in the job.
996 if (timeout != 120) {
997 Utilities.setJobTimeout(newJob, timeout)
1001 def static getJobFolder(def scenario) {
1002 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
1005 if (scenario == 'illink') {
1011 def static getStressModeDisplayName(def scenario) {
1013 Constants.jitStressModeScenarios[scenario].each{ k, v ->
1014 def prefixLength = 'COMPlus_'.length()
1015 if (k.length() >= prefixLength) {
1016 def modeName = k.substring(prefixLength, k.length())
1017 if (displayStr != '') {
1018 // Separate multiple variables with a space.
1021 displayStr += modeName + '=' + v
1025 if (isCoreFxScenario(scenario)) {
1026 displayStr = ('CoreFx ' + displayStr).trim()
1032 def static getR2RDisplayName(def scenario) {
1033 // Assume the scenario name is one from the r2rStressScenarios dict, and remove its "r2r_" prefix.
1034 def displayStr = scenario
1035 def prefixLength = 'r2r_'.length()
1036 if (displayStr.length() >= prefixLength) {
1037 displayStr = "R2R " + displayStr.substring(prefixLength, displayStr.length())
1038 } else if (scenario == 'r2r') {
1044 def static getScenarioDisplayString(def scenario) {
1047 return "Innerloop Build and Test"
1049 case 'no_tiered_compilation_innerloop':
1050 def displayStr = getStressModeDisplayName(scenario)
1051 return "Innerloop Build and Test (Jit - ${displayStr})"
1053 case 'corefx_innerloop':
1054 return "CoreFX Tests"
1057 return "Build and Test"
1060 return "Jit Diff Build and Test"
1063 return "IL RoundTrip Build and Test"
1066 return "Long-Running GC Build & Test"
1069 return "GC Simulator"
1071 case 'standalone_gc':
1072 return "Standalone GC"
1074 case 'gc_reliability_framework':
1075 return "GC Reliability Framework"
1081 if (isJitStressScenario(scenario)) {
1082 def displayStr = getStressModeDisplayName(scenario)
1083 return "Build and Test (Jit - ${displayStr})"
1085 else if (isR2RScenario(scenario)) {
1086 def displayStr = getR2RDisplayName(scenario)
1087 return "${displayStr} Build and Test"
1090 return "${scenario}"
1095 println("Unknown scenario: ${scenario}");
1100 // Functions to create an environment script.
1101 // envScriptCreate -- initialize the script (call first)
1102 // envScriptFinalize -- finalize the script (call last)
1103 // envScriptSetStressModeVariables -- set stress mode variables in the env script
1104 // envScriptAppendExistingScript -- append an existing script to the generated script
1106 // Each script returns a string of commands. Concatenate all the strings together before
1107 // adding them to the builds commands, to make sure they get executed as one Jenkins script.
1110 // Initialize the environment setting script.
1111 def static envScriptCreate(def os, def stepScriptLocation) {
1113 if (os == 'Windows_NT') {
1114 stepScript += "echo Creating TestEnv script\r\n"
1115 stepScript += "if exist ${stepScriptLocation} del ${stepScriptLocation}\r\n"
1117 // Create at least an empty script.
1118 stepScript += "echo. > ${stepScriptLocation}\r\n"
1121 stepScript += "echo Creating environment setting script\n"
1122 stepScript += "echo \\#\\!/usr/bin/env bash > ${stepScriptLocation}\n"
1128 // Generates the string for setting stress mode variables.
1129 def static envScriptSetStressModeVariables(def os, def stressModeVars, def stepScriptLocation) {
1131 if (os == 'Windows_NT') {
1132 stressModeVars.each{ k, v ->
1133 // Write out what we are writing to the script file
1134 stepScript += "echo Setting ${k}=${v}\r\n"
1135 // Write out the set itself to the script file`
1136 stepScript += "echo set ${k}=${v} >> ${stepScriptLocation}\r\n"
1140 stressModeVars.each{ k, v ->
1141 // Write out what we are writing to the script file
1142 stepScript += "echo Setting ${k}=${v}\n"
1143 // Write out the set itself to the script file`
1144 stepScript += "echo export ${k}=${v} >> ${stepScriptLocation}\n"
1151 // Append an existing script to an environment script.
1152 // Returns string of commands to do this.
1153 def static envScriptAppendExistingScript(def os, def appendScript, def stepScriptLocation) {
1154 assert (os == 'Windows_NT')
1157 stepScript += "echo Appending ${appendScript} to ${stepScriptLocation}\r\n"
1158 stepScript += "type ${appendScript} >> ${stepScriptLocation}\r\n"
1163 // Finalize an environment setting script.
1164 // Returns string of commands to do this.
1165 def static envScriptFinalize(def os, def stepScriptLocation) {
1168 if (os == 'Windows_NT') {
1169 // Display the resulting script. This is useful when looking at the output log file.
1170 stepScript += "echo Display the total script ${stepScriptLocation}\r\n"
1171 stepScript += "type ${stepScriptLocation}\r\n"
1174 stepScript += "chmod +x ${stepScriptLocation}\n"
1180 def static isNeedDocker(def architecture, def os, def isBuild) {
1182 if (architecture == 'x86' && os == 'Ubuntu') {
1185 else if (architecture == 'armem') {
1188 else if (architecture == 'arm') {
1189 if (os == 'Ubuntu') {
1193 else if (architecture == 'arm64') {
1194 if (os == 'Ubuntu16.04') {
1200 if (architecture == 'x86' && os == 'Ubuntu') {
1207 def static getDockerImageName(def architecture, def os, def isBuild) {
1208 // We must change some docker private images to official later
1210 if (architecture == 'x86' && os == 'Ubuntu') {
1211 return "hseok82/dotnet-buildtools-prereqs:ubuntu-16.04-crossx86-ef0ac75-20175511035548"
1213 else if (architecture == 'armem') {
1214 if (os == 'Tizen') {
1215 return "tizendotnet/dotnet-buildtools-prereqs:ubuntu-16.04-cross-e435274-20180426002255-tizen-rootfs-5.0m1"
1218 else if (architecture == 'arm') {
1219 if (os == 'Ubuntu') {
1220 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420"
1223 else if (architecture == 'arm64') {
1224 if (os == 'Ubuntu16.04') {
1225 return "microsoft/dotnet-buildtools-prereqs:ubuntu-16.04-cross-arm64-a3ae44b-20180315221921"
1230 if (architecture == 'x86' && os == 'Ubuntu') {
1231 return "hseok82/dotnet-buildtools-prereqs:ubuntu1604_x86_test"
1234 println("Unknown architecture to use docker: ${architecture} ${os}");
1239 // We have a limited amount of some hardware. For these, scale back the periodic testing we do,
1240 // and only allowing using this hardware in some specific branches.
1241 def static jobRequiresLimitedHardware(def architecture, def os) {
1242 if (architecture == 'arm') {
1243 // arm Windows and Linux hardware is limited.
1246 else if (architecture == 'arm64') {
1247 // arm64 Windows and Linux hardware is limited.
1255 // Calculates the name of the build job based on some typical parameters.
1257 def static getJobName(def configuration, def architecture, def os, def scenario, def isBuildOnly) {
1258 // If the architecture is x64, do not add that info into the build name.
1259 // Need to change around some systems and other builds to pick up the right builds
1262 def suffix = scenario != 'normal' ? "_${scenario}" : '';
1267 switch (architecture) {
1269 if (scenario == 'normal') {
1270 // For now we leave x64 off of the name for compatibility with other jobs
1271 baseName = configuration.toLowerCase() + '_' + os.toLowerCase()
1273 else if (scenario == 'formatting') {
1274 // we don't care about the configuration for the formatting job. It runs all configs
1275 baseName = architecture.toLowerCase() + '_' + os.toLowerCase()
1278 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1282 // These are cross builds
1283 assert os == 'Tizen'
1284 baseName = 'armel_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1288 // These are cross builds
1289 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1292 case 'x86_arm_altjit':
1293 case 'x64_arm64_altjit':
1294 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1297 println("Unknown architecture: ${architecture}");
1302 return baseName + suffix
1305 def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob, def bidailyCrossList) {
1306 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1308 // Limited hardware is restricted for non-PR triggers to certain branches.
1309 if (jobRequiresLimitedHardware(architecture, os) && (!(branch in Constants.LimitedHardwareBranches))) {
1313 // Ubuntu x86 CI jobs are failing. Disable non-PR triggered jobs to avoid these constant failures
1314 // until this is fixed. Tracked by https://github.com/dotnet/coreclr/issues/19003.
1315 if (architecture == 'x86' && os == 'Ubuntu') {
1322 case 'no_tiered_compilation_innerloop':
1323 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
1324 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
1325 // We should never get here (in the "innerloop cases) for non-PR jobs, except for this TEMPORARY exception.
1326 // Only trigger the flow job, not the build job.
1327 assert (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked'))
1329 addGithubPushTriggerHelper(job)
1333 case 'crossgen_comparison':
1336 switch (architecture) {
1339 if (isFlowJob && architecture == 'x86' && os == 'Ubuntu') {
1340 addPeriodicTriggerHelper(job, '@daily')
1342 else if (isFlowJob || os == 'Windows_NT' || (architecture == 'x64' && !(os in Constants.crossList))) {
1343 addGithubPushTriggerHelper(job)
1347 if (os == 'Windows_NT') {
1348 if (isFlowJob || (isNormalOrInnerloop && (configuration == 'Debug'))) {
1349 // We would normally want a per-push trigger, but with limited hardware we can't keep up.
1350 // Do the builds daily.
1351 addPeriodicTriggerHelper(job, '@daily')
1355 // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job.
1357 addPeriodicTriggerHelper(job, '@daily')
1362 if (os == 'Windows_NT') {
1363 if (isFlowJob || (isNormalOrInnerloop && (configuration == 'Debug'))) {
1364 // We would normally want a push trigger, but with limited hardware we can't keep up.
1365 // Do the builds daily.
1366 addPeriodicTriggerHelper(job, '@daily')
1370 assert os == 'Ubuntu'
1371 // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job.
1373 // Currently no push triggers, with limited arm Linux hardware.
1374 // TODO: If we have enough machine capacity, add some arm Linux push triggers.
1375 addPeriodicTriggerHelper(job, '@daily')
1380 addGithubPushTriggerHelper(job)
1382 case 'x86_arm_altjit':
1383 case 'x64_arm64_altjit':
1384 // Only do altjit push triggers for Checked; don't waste time on Debug or Release.
1385 if (configuration == 'Checked') {
1386 addGithubPushTriggerHelper(job)
1390 println("Unknown architecture: ${architecture}");
1396 assert !(os in bidailyCrossList)
1397 // r2r gets a push trigger for checked/release
1398 if (configuration == 'Checked' || configuration == 'Release') {
1399 if (architecture == 'x64' && os != 'OSX10.12') {
1400 //Flow jobs should be Windows, Ubuntu, OSX0.12, or CentOS
1401 if (isFlowJob || os == 'Windows_NT') {
1402 addGithubPushTriggerHelper(job)
1404 // OSX10.12 r2r jobs should only run every 12 hours, not daily.
1405 } else if (architecture == 'x64' && os == 'OSX10.12'){
1407 addPeriodicTriggerHelper(job, 'H H/12 * * *')
1410 // For x86, only add per-commit jobs for Windows
1411 else if (architecture == 'x86') {
1412 if (os == 'Windows_NT') {
1413 addGithubPushTriggerHelper(job)
1416 // arm r2r jobs should only run weekly.
1417 else if (architecture == 'arm') {
1419 addPeriodicTriggerHelper(job, '@weekly')
1422 // arm64 r2r jobs should only run weekly.
1423 else if (architecture == 'arm64') {
1425 addPeriodicTriggerHelper(job, '@weekly')
1430 case 'r2r_jitstress1':
1431 case 'r2r_jitstress2':
1432 case 'r2r_jitstress1_tiered':
1433 case 'r2r_jitstress2_tiered':
1434 case 'r2r_jitstressregs1':
1435 case 'r2r_jitstressregs2':
1436 case 'r2r_jitstressregs3':
1437 case 'r2r_jitstressregs4':
1438 case 'r2r_jitstressregs8':
1439 case 'r2r_jitstressregs0x10':
1440 case 'r2r_jitstressregs0x80':
1441 case 'r2r_jitstressregs0x1000':
1442 case 'r2r_jitminopts':
1443 case 'r2r_jitforcerelocs':
1444 case 'r2r_gcstress15':
1445 case 'r2r_no_tiered_compilation':
1446 assert !(os in bidailyCrossList)
1448 // GCStress=C is currently not supported on OS X
1449 if (os == 'OSX10.12' && isGCStressRelatedTesting(scenario)) {
1453 if (configuration == 'Checked' || configuration == 'Release') {
1454 if (architecture == 'x64') {
1455 //Flow jobs should be Windows, Ubuntu, OSX10.12, or CentOS
1456 if (isFlowJob || os == 'Windows_NT') {
1457 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1460 // For x86, only add periodic jobs for Windows
1461 else if (architecture == 'x86') {
1462 if (os == 'Windows_NT') {
1463 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1466 else if (architecture == 'arm') {
1468 addPeriodicTriggerHelper(job, '@weekly')
1471 else if (architecture == 'arm64') {
1473 addPeriodicTriggerHelper(job, '@weekly')
1479 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1480 assert configuration == 'Release'
1481 assert architecture == 'x64'
1482 addPeriodicTriggerHelper(job, '@daily')
1483 // TODO: Add once external email sending is available again
1484 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1487 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1488 assert configuration == 'Release'
1489 assert architecture == 'x64'
1490 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1491 // TODO: Add once external email sending is available again
1492 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1494 case 'standalone_gc':
1495 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1496 assert (configuration == 'Release' || configuration == 'Checked')
1497 // TODO: Add once external email sending is available again
1498 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1499 addPeriodicTriggerHelper(job, '@daily')
1501 case 'gc_reliability_framework':
1502 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1503 assert (configuration == 'Release' || configuration == 'Checked')
1504 // Only triggered by phrase.
1507 assert !(os in bidailyCrossList)
1508 // ILASM/ILDASM roundtrip one gets a daily build, and only for release
1509 if (architecture == 'x64' && configuration == 'Release') {
1510 if (isFlowJob || os == 'Windows_NT') {
1511 addPeriodicTriggerHelper(job, '@daily')
1516 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1517 assert configuration == 'Checked'
1518 assert (architecture == 'x64' || architecture == 'x86')
1519 addGithubPushTriggerHelper(job)
1522 assert (os == 'Windows_NT' || os == "Ubuntu")
1523 assert architecture == 'x64'
1524 addGithubPushTriggerHelper(job)
1526 case 'jitstressregs1':
1527 case 'jitstressregs2':
1528 case 'jitstressregs3':
1529 case 'jitstressregs4':
1530 case 'jitstressregs8':
1531 case 'jitstressregs0x10':
1532 case 'jitstressregs0x80':
1533 case 'jitstressregs0x1000':
1535 case 'tieredcompilation':
1536 case 'no_tiered_compilation':
1540 case 'jitstress1_tiered':
1541 case 'jitstress2_tiered':
1542 case 'jitstress2_jitstressregs1':
1543 case 'jitstress2_jitstressregs2':
1544 case 'jitstress2_jitstressregs3':
1545 case 'jitstress2_jitstressregs4':
1546 case 'jitstress2_jitstressregs8':
1547 case 'jitstress2_jitstressregs0x10':
1548 case 'jitstress2_jitstressregs0x80':
1549 case 'jitstress2_jitstressregs0x1000':
1550 case 'tailcallstress':
1553 case 'jitnox86hwintrinsic':
1554 case 'jitincompletehwintrinsic':
1555 case 'jitx86hwintrinsicnoavx':
1556 case 'jitx86hwintrinsicnoavx2':
1557 case 'jitx86hwintrinsicnosimd':
1558 case 'corefx_baseline':
1559 case 'corefx_minopts':
1560 case 'corefx_tieredcompilation':
1561 case 'corefx_jitstress1':
1562 case 'corefx_jitstress2':
1563 case 'corefx_jitstressregs1':
1564 case 'corefx_jitstressregs2':
1565 case 'corefx_jitstressregs3':
1566 case 'corefx_jitstressregs4':
1567 case 'corefx_jitstressregs8':
1568 case 'corefx_jitstressregs0x10':
1569 case 'corefx_jitstressregs0x80':
1570 case 'corefx_jitstressregs0x1000':
1572 if (os == 'CentOS7.1') {
1575 if (os in bidailyCrossList) {
1578 // ARM corefx testing uses non-flow jobs to provide the configuration-specific
1579 // build for the flow job. We don't need cron jobs for these. Note that the
1580 // Windows ARM jobs depend on a Windows "build only" job that exits the trigger
1581 // function very early, so only non-Windows gets here.
1582 if ((architecture == 'arm') && isCoreFxScenario(scenario) && !isFlowJob) {
1585 if ((architecture == 'arm64') && isCoreFxScenario(scenario) && !isFlowJob) {
1588 if (jobRequiresLimitedHardware(architecture, os)) {
1589 if ((architecture == 'arm64') && (os == 'Ubuntu16.04')) {
1590 // These jobs are very fast on Linux/arm64 hardware, so run them daily.
1591 addPeriodicTriggerHelper(job, '@daily')
1594 addPeriodicTriggerHelper(job, '@weekly')
1598 addPeriodicTriggerHelper(job, '@daily')
1603 if (os == 'CentOS7.1') {
1606 if (os in bidailyCrossList) {
1609 addPeriodicTriggerHelper(job, '@weekly')
1612 case 'gcstress0xc_zapdisable':
1613 case 'gcstress0xc_zapdisable_jitstress2':
1614 case 'gcstress0xc_zapdisable_heapverify1':
1615 case 'gcstress0xc_jitstress1':
1616 case 'gcstress0xc_jitstress2':
1617 case 'gcstress0xc_minopts_heapverify1':
1618 if (os == 'OSX10.12') {
1619 // GCStress=C is currently not supported on OS X
1622 if (os == 'CentOS7.1') {
1625 if (os in bidailyCrossList) {
1628 addPeriodicTriggerHelper(job, '@weekly')
1632 // Testing on other operating systems TBD
1633 assert (os == 'Windows_NT' || os == 'Ubuntu')
1634 if (architecture == 'x64' || architecture == 'x86') {
1635 if (configuration == 'Checked') {
1636 addPeriodicTriggerHelper(job, '@daily')
1642 println("Unknown scenario: ${scenario}");
1649 // **************************
1650 // Define the basic inner loop builds for PR and commit. This is basically just the set
1651 // of coreclr builds over linux/osx 10.12/windows and debug/release/checked. In addition, the windows
1652 // builds will do a couple extra steps.
1653 // **************************
1655 // Adds a trigger for the PR build if one is needed. If isFlowJob is true, then this is the
1656 // flow job that rolls up the build and test for non-windows OS's. // If the job is a windows build only job,
1657 // it's just used for internal builds
1658 // If you add a job with a trigger phrase, please add that phrase to coreclr/Documentation/project-docs/ci-trigger-phrases.md
1659 def static addTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob) {
1660 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1662 if (isWindowsBuildOnlyJob) {
1666 def bidailyCrossList = ['RHEL7.2', 'Debian8.4']
1667 // Non pull request builds.
1669 addNonPRTriggers(job, branch, isPR, architecture, os, configuration, scenario, isFlowJob, isWindowsBuildOnlyJob, bidailyCrossList)
1694 // Pull request builds. Generally these fall into two categories: default triggers and on-demand triggers
1695 // We generally only have a distinct set of default triggers but a bunch of on-demand ones.
1697 def contextString = ""
1698 def triggerString = ""
1699 def needsTrigger = true
1700 def isDefaultTrigger = false
1701 def isArm64PrivateJob = false
1702 def scenarioString = ""
1704 // Set up default context string and trigger phrases. This is overridden in places, sometimes just to keep
1705 // the existing non-standard descriptions and phrases. In some cases, the scenarios are asymmetric, as for
1706 // some jobs where the Debug configuration just does builds, no tests.
1708 // Some configurations, like arm32/arm64, always use the exact scenario name as part of the context string.
1709 // This makes it possible to copy/paste the displayed context string as "@dotnet-bot test <context-string>"
1710 // to invoke the trigger. Any "fancy" context string makes that impossible, requiring the user to either
1711 // remember the mapping from context string to trigger string, or use "@dotnet-bot help" to look it up.
1713 if (architecture == 'armem') {
1714 assert os == 'Tizen'
1715 architecture = 'armel'
1718 switch (architecture) {
1719 case 'x64_arm64_altjit':
1720 case 'x86_arm_altjit':
1721 // TODO: for consistency, add "Build and Test" at end.
1722 contextString = "${os} ${architecture} ${configuration} ${scenario}"
1723 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*"
1729 contextString = "${os} ${architecture} Cross ${configuration}"
1730 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}"
1732 if (scenario == 'innerloop') {
1733 contextString += " Innerloop"
1734 triggerString += "\\W+Innerloop"
1737 contextString += " ${scenario}"
1738 triggerString += "\\W+${scenario}"
1741 if (configuration == 'Debug') {
1742 contextString += " Build"
1743 triggerString += "\\W+Build"
1746 contextString += " Build and Test"
1747 triggerString += "\\W+Build and Test"
1750 triggerString += ".*"
1754 scenarioString = getScenarioDisplayString(scenario)
1755 contextString = "${os} ${architecture} ${configuration} ${scenarioString}"
1756 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}"
1760 triggerString += "\\W+Build and Test.*"
1763 case 'corefx_innerloop': // maintain this asymmetry
1764 triggerString += "\\W+CoreFX Tests.*"
1768 triggerString += "\\W+${scenario}.*"
1772 triggerString += ".*"
1776 // Now determine what kind of trigger this job needs, if any. Any job should be triggerable, except for
1777 // non-flow jobs that are only used as part of flow jobs.
1779 switch (architecture) {
1780 case 'x64': // editor brace matching: {
1781 if (scenario == 'formatting') {
1782 assert configuration == 'Checked'
1783 if (os == 'Windows_NT' || os == 'Ubuntu') {
1784 isDefaultTrigger = true
1785 contextString = "${os} ${architecture} Formatting"
1791 // OpenSUSE, Debian & RedHat get trigger phrases for pri 0 build, and pri 1 build & test
1794 if (scenario == 'innerloop') {
1796 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1797 isDefaultTrigger = true
1807 assert scenario != 'innerloop'
1808 contextString = "${os} ${architecture} ${configuration} Build"
1809 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+Build.*"
1813 if (scenario == 'illink') {
1816 else if (scenario == 'corefx_innerloop') {
1817 if (configuration == 'Checked') {
1818 isDefaultTrigger = true
1826 // Triggers on the non-flow jobs aren't necessary here
1827 // Corefx testing uses non-flow jobs.
1828 if (!isFlowJob && !isCoreFxScenario(scenario)) {
1829 needsTrigger = false
1834 isDefaultTrigger = true
1837 case 'no_tiered_compilation_innerloop':
1838 if (os == 'Ubuntu') {
1839 isDefaultTrigger = true
1851 // CentOS uses checked for default PR tests while debug is build only
1852 if (configuration == 'Debug') {
1853 isDefaultTrigger = true
1854 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1858 // Make sure this is a flow job to get build and test.
1860 needsTrigger = false
1864 if (configuration == 'Checked') {
1865 assert job.name.contains("flow")
1866 isDefaultTrigger = true
1867 contextString = "${os} ${architecture} ${configuration} Innerloop Build and Test"
1872 // Make sure this is a flow job to get build and test.
1874 needsTrigger = false
1887 case 'no_tiered_compilation_innerloop':
1888 isDefaultTrigger = true
1891 case 'corefx_innerloop':
1892 if (configuration == 'Checked' || configuration == 'Release') {
1893 isDefaultTrigger = true
1903 println("Unknown os: ${os}");
1910 // editor brace matching: }
1912 case 'armel': // editor brace matching: {
1915 azureVMAgentPostBuildAction {
1916 agentPostBuildAction('Delete agent if the build was not successful (when idle).')
1923 if (scenario == 'innerloop') {
1924 if (configuration == 'Checked') {
1925 isDefaultTrigger = true
1932 // editor brace matching: }
1935 case 'arm64': // editor brace matching: {
1941 // Triggers on the non-flow jobs aren't necessary
1943 needsTrigger = false
1949 case 'no_tiered_compilation_innerloop':
1950 if (configuration == 'Checked') {
1951 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
1952 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
1953 if (architecture == 'arm64') {
1956 isDefaultTrigger = true
1963 assert isArmWindowsScenario(scenario)
1965 // 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
1966 // the non-flow Build job. All others need a trigger on the flow job.
1967 def needsFlowJobTrigger = !(isNormalOrInnerloop && (configuration == 'Debug'))
1968 if (isFlowJob != needsFlowJobTrigger) {
1969 needsTrigger = false
1975 if (configuration == 'Debug') {
1976 // Add default PR trigger for Windows arm64 Debug builds. This is a build only -- no tests are run --
1977 // so the private test hardware is not used. Thus, it can be run by all users, not just arm64Users.
1978 // People in arm64Users will get both this and the Checked Build and Test job.
1979 isDefaultTrigger = true
1980 } else if (configuration == 'Checked') {
1981 isDefaultTrigger = true
1982 isArm64PrivateJob = true
1986 isArm64PrivateJob = true
1991 println("NYI os: ${os}");
1997 // editor brace matching: }
1998 case 'x86': // editor brace matching: {
1999 assert ((os == 'Windows_NT') || ((os == 'Ubuntu') && isNormalOrInnerloop))
2000 if (os == 'Ubuntu') {
2001 // Triggers on the non-flow jobs aren't necessary here
2003 needsTrigger = false
2007 // on-demand only for ubuntu x86
2008 contextString = "${os} ${architecture} ${configuration} Build"
2009 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}.*"
2014 case 'no_tiered_compilation_innerloop':
2015 isDefaultTrigger = true
2022 // editor brace matching: }
2023 case 'x64_arm64_altjit':
2024 case 'x86_arm_altjit':
2025 // Everything default
2029 println("Unknown architecture: ${architecture}");
2035 if (isArm64PrivateJob) {
2036 if (isDefaultTrigger) {
2037 Utilities.addDefaultPrivateGithubPRTriggerForBranch(job, branch, contextString, null, arm64Users)
2040 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
2044 if (isDefaultTrigger) {
2045 Utilities.addGithubPRTriggerForBranch(job, branch, contextString)
2048 Utilities.addGithubPRTriggerForBranch(job, branch, contextString, triggerString)
2054 def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR, def architecture, def configuration, def os, def isBuildOnly) {
2055 def buildCommands = []
2056 def osGroup = getOSGroup(os)
2057 def lowerConfiguration = configuration.toLowerCase()
2060 if (isInnerloopTestScenario(scenario)) {
2064 def doCoreFxTesting = isCoreFxScenario(scenario)
2066 // Calculate the build steps, archival, and xunit results
2068 case 'Windows_NT': // editor brace matching: {
2069 switch (architecture) {
2072 case 'x86_arm_altjit':
2073 case 'x64_arm64_altjit':
2074 def arch = architecture
2076 if (architecture == 'x86_arm_altjit') {
2079 else if (architecture == 'x64_arm64_altjit') {
2083 if (scenario == 'formatting') {
2084 buildCommands += "python -u tests\\scripts\\format.py -c %WORKSPACE% -o Windows_NT -a ${arch}"
2085 Utilities.addArchival(newJob, "format.patch", "", true, false)
2089 if (scenario == 'illink') {
2090 buildCommands += "tests\\scripts\\build_illink.cmd clone ${arch}"
2093 // If it is a release build for Windows, ensure PGO is used, else fail the build.
2094 if ((lowerConfiguration == 'release') &&
2095 (scenario in Constants.basicScenarios) &&
2096 (architecture != 'x86_arm_altjit') &&
2097 (architecture != 'x64_arm64_altjit')) {
2099 buildOpts += ' -enforcepgo'
2102 if (doCoreFxTesting) {
2103 buildOpts += ' skiptests';
2105 buildOpts += " -priority=${priority}"
2108 // Set __TestIntermediateDir to something short. If __TestIntermediateDir is already set, build-test.cmd will
2109 // output test binaries to that directory. If it is not set, the binaries are sent to a default directory whose name is about
2110 // 35 characters long.
2112 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts}"
2115 def runtestArguments = ''
2116 def testOpts = 'collectdumps'
2118 if (isR2RScenario(scenario)) {
2120 // If this is a ReadyToRun scenario, pass 'crossgen' or 'crossgenaltjit'
2121 // to cause framework assemblies to be crossgen'ed. Pass 'runcrossgentests'
2122 // to cause the tests to be crossgen'ed.
2124 if ((architecture == 'x86_arm_altjit') || (architecture == 'x64_arm64_altjit')) {
2125 testOpts += ' crossgenaltjit protononjit.dll'
2127 testOpts += ' crossgen'
2130 testOpts += ' runcrossgentests'
2132 else if (scenario == 'jitdiff') {
2133 testOpts += ' jitdisasm crossgen'
2135 else if (scenario == 'ilrt') {
2136 testOpts += ' ilasmroundtrip'
2138 else if (isLongGc(scenario)) {
2139 testOpts += " ${scenario} sequential"
2141 else if (scenario == 'standalone_gc') {
2142 testOpts += ' gcname clrgc.dll'
2144 else if (scenario == 'illink') {
2145 testOpts += " link %WORKSPACE%\\linker\\linker\\bin\\netcore_Release\\netcoreapp2.0\\win10-${arch}\\publish\\illink.exe"
2148 // Default per-test timeout is 10 minutes. For stress modes and Debug scenarios, increase this
2149 // to 30 minutes (30 * 60 * 1000 = 180000). The "timeout" argument to runtest.cmd sets this, by
2150 // taking a timeout value in milliseconds. (Note that it sets the __TestTimeout environment variable,
2151 // which is read by the xunit harness.)
2152 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario) || (lowerConfiguration == 'debug'))
2154 def timeout = 1800000
2155 testOpts += " timeout ${timeout}"
2158 // If we are running a stress mode, we should write out the set of key
2159 // value env pairs to a file at this point and then we'll pass that to runtest.cmd
2161 def envScriptPath = ''
2162 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2163 def buildCommandsStr = ''
2164 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2165 buildCommandsStr += envScriptCreate(os, envScriptPath)
2167 if (isJitStressScenario(scenario)) {
2168 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2170 else if (isR2RStressScenario(scenario)) {
2171 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.r2rStressScenarios[scenario], envScriptPath)
2174 if (architecture == 'x86_arm_altjit') {
2175 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x86_arm_altjit.cmd", envScriptPath)
2177 else if (architecture == 'x64_arm64_altjit') {
2178 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd", envScriptPath)
2181 envScriptFinalize(os, envScriptPath)
2183 // Note that buildCommands is an array of individually executed commands; we want all the commands used to
2184 // create the SetStressModes.bat script to be executed together, hence we accumulate them as strings
2185 // into a single script.
2186 buildCommands += buildCommandsStr
2188 else if (architecture == 'x86_arm_altjit') {
2189 envScriptPath = "%WORKSPACE%\\tests\\x86_arm_altjit.cmd"
2191 else if (architecture == 'x64_arm64_altjit') {
2192 envScriptPath = "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd"
2194 if (envScriptPath != '') {
2195 testOpts += " TestEnv ${envScriptPath}"
2198 runtestArguments = "${lowerConfiguration} ${arch} ${testOpts}"
2200 if (doCoreFxTesting) {
2201 if (scenario == 'corefx_innerloop') {
2202 // Create CORE_ROOT and testhost
2203 buildCommands += "build-test.cmd ${lowerConfiguration} ${arch} buildtesthostonly"
2204 buildCommands += "tests\\runtest.cmd ${runtestArguments} CoreFXTestsAll"
2206 // Archive and process (only) the test results
2207 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2208 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2211 def workspaceRelativeFxRoot = "_/fx"
2212 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2213 def fxBranch = getFxBranch(branch)
2215 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}"
2217 // Archive and process (only) the test results
2218 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2219 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2221 //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
2222 Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
2223 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
2226 else if (isGcReliabilityFramework(scenario)) {
2227 buildCommands += "tests\\runtest.cmd ${runtestArguments} GenerateLayoutOnly"
2228 buildCommands += "tests\\scripts\\run-gc-reliability-framework.cmd ${arch} ${configuration}"
2231 buildCommands += "tests\\runtest.cmd ${runtestArguments}"
2233 } // end if (!isBuildOnly)
2235 if (!doCoreFxTesting) {
2236 // Run the rest of the build
2237 // Build the mscorlib for the other OS's
2238 buildCommands += "build.cmd ${lowerConfiguration} ${arch} linuxmscorlib"
2239 buildCommands += "build.cmd ${lowerConfiguration} ${arch} osxmscorlib"
2241 if (arch == 'x64') {
2242 buildCommands += "build.cmd ${lowerConfiguration} arm64 linuxmscorlib"
2245 // Zip up the tests directory so that we don't use so much space/time copying
2246 // 10s of thousands of files around.
2247 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')\"";
2249 if (!isJitStressScenario(scenario)) {
2250 // For Windows, pull full test results and test drops for x86/x64.
2251 // No need to pull for stress mode scenarios (downstream builds use the default scenario)
2252 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2255 if (scenario == 'jitdiff') {
2256 // retrieve jit-dasm output for base commit, and run jit-diff
2258 // if this is a build only job, we want to keep the default (build) artifacts for the flow job
2259 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${arch}.${configuration}/dasm/**")
2264 Utilities.addXUnitDotNETResults(newJob, 'bin/**/TestRun*.xml', true)
2270 assert isArmWindowsScenario(scenario)
2274 if (doCoreFxTesting) {
2275 buildOpts += ' skiptests'
2277 buildOpts += " -priority=${priority}"
2280 // This is now a build only job. Do not run tests. Use the flow job.
2281 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} ${buildOpts}"
2283 if (doCoreFxTesting) {
2286 // Set the stress mode variables; this is incorporated into the generated CoreFx RunTests.cmd files.
2287 def envScriptPath = ''
2288 def buildCommandsStr = ''
2289 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2290 buildCommandsStr += envScriptCreate(os, envScriptPath)
2291 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2292 envScriptFinalize(os, envScriptPath)
2293 buildCommands += buildCommandsStr
2295 def workspaceRelativeFxRootLinux = "_/fx"
2296 def workspaceRelativeFxRootWin = "_\\fx"
2297 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2298 def fxBranch = getFxBranch(branch)
2300 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"
2302 // Zip up the CoreFx runtime and tests. We don't need the CoreCLR binaries; they have been copied to the CoreFX tree.
2303 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')\"";
2304 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\tests', '${workspaceRelativeFxRootWin}\\fxtests.zip')\"";
2306 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2307 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2309 // Zip up the tests directory so that we don't use so much space/time copying
2310 // 10s of thousands of files around.
2311 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')\"";
2314 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2318 println("Unknown architecture: ${architecture}");
2323 // end case 'Windows_NT'; editor brace matching: }
2332 case 'Fedora24': // editor brace matching: {
2333 switch (architecture) {
2336 if (architecture == 'x86' && os == 'Ubuntu') {
2337 // build and PAL test
2338 def dockerImage = getDockerImageName(architecture, os, true)
2339 buildCommands += "docker run -i --rm -v \${WORKSPACE}:/opt/code -w /opt/code -e ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} ./build.sh ${architecture} cross ${lowerConfiguration}"
2340 dockerImage = getDockerImageName(architecture, os, false)
2341 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"
2342 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2343 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2347 if (scenario == 'formatting') {
2348 buildCommands += "python tests/scripts/format.py -c \${WORKSPACE} -o Linux -a ${architecture}"
2349 Utilities.addArchival(newJob, "format.patch", "", true, false)
2353 if (scenario == 'illink') {
2354 assert(os == 'Ubuntu')
2355 buildCommands += "./tests/scripts/build_illink.sh --clone --arch=${architecture}"
2358 if (!doCoreFxTesting) {
2359 // We run pal tests on all OS but generate mscorlib (and thus, nuget packages)
2360 // only on supported OS platforms.
2361 def bootstrapRid = Utilities.getBoostrapPublishRid(os)
2362 def bootstrapRidEnv = bootstrapRid != null ? "__PUBLISH_RID=${bootstrapRid} " : ''
2364 buildCommands += "${bootstrapRidEnv}./build.sh ${lowerConfiguration} ${architecture}"
2365 buildCommands += "src/pal/tests/palsuite/runpaltests.sh \${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration} \${WORKSPACE}/bin/paltestout"
2367 // Basic archiving of the build
2368 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2370 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2373 if (scenario == 'corefx_innerloop') {
2374 assert os == 'Ubuntu' || 'OSX10.12'
2375 assert architecture == 'x64'
2377 buildCommands += "./build.sh ${lowerConfiguration} ${architecture} skiptests"
2378 buildCommands += "./build-test.sh ${lowerConfiguration} ${architecture} generatetesthostonly"
2379 buildCommands += "./tests/runtest.sh --corefxtestsall --testHostDir=\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/testhost/ --coreclr-src=\${WORKSPACE}"
2382 // Archive and process (only) the test results
2383 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2384 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2387 // Corefx stress testing
2388 assert os == 'Ubuntu'
2389 assert architecture == 'x64'
2390 assert lowerConfiguration == 'checked'
2391 assert isJitStressScenario(scenario)
2394 buildCommands += "./build.sh ${lowerConfiguration} ${architecture}"
2396 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2398 def envScriptCmds = envScriptCreate(os, scriptFileName)
2399 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2400 envScriptCmds += envScriptFinalize(os, scriptFileName)
2401 buildCommands += envScriptCmds
2403 // Build and text corefx
2404 def workspaceRelativeFxRoot = "_/fx"
2405 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRoot}"
2406 def fxBranch = getFxBranch(branch)
2408 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}"
2410 // Archive and process (only) the test results
2411 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2412 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2417 // Emulator cross builds for ARM runs on Tizen currently
2418 assert os == 'Tizen'
2420 def arm_abi = "armel"
2421 def linuxCodeName = "tizen"
2423 // Unzip the Windows test binaries first. Exit with 0
2424 buildCommands += "unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.x64.${configuration} || exit 0"
2426 // Unpack the corefx binaries
2427 buildCommands += "mkdir ./bin/CoreFxBinDir"
2428 buildCommands += "tar -xf ./bin/build.tar.gz -C ./bin/CoreFxBinDir"
2430 // Call the ARM CI script to cross build and test using docker
2431 buildCommands += """./tests/scripts/arm32_ci_script.sh \\
2434 --linuxCodeName=${linuxCodeName} \\
2435 --buildConfig=${lowerConfiguration} \\
2436 --testRootDir=./bin/tests/Windows_NT.x64.${configuration} \\
2437 --coreFxBinDir=./bin/CoreFxBinDir \\
2438 --testDirFile=./tests/testsRunningInsideARM.txt"""
2440 // Basic archiving of the build, no pal tests
2441 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2445 // Non-Windows ARM cross builds on hardware run on Ubuntu only
2446 assert (os == 'Ubuntu') || (os == 'Ubuntu16.04')
2448 // Add some useful information to the log file. Ignore return codes.
2449 buildCommands += "uname -a || true"
2451 def additionalOpts = ""
2452 if (architecture == 'arm') {
2453 additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86"
2456 // Cross build the Ubuntu/arm product using docker with a docker image that contains the correct
2457 // Ubuntu cross-compilation toolset (running on a Ubuntu x64 host).
2458 // For CoreFX testing, we only need the product build; we don't need to generate the layouts. The product
2459 // build is then copied into the corefx layout by the run-corefx-test.py script. For CoreFX testing, we
2460 // ZIP up the generated CoreFX runtime and tests.
2462 def dockerImage = getDockerImageName(architecture, os, true)
2463 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} "
2465 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh ${lowerConfiguration} ${architecture} cross crosscomponent"
2467 if (doCoreFxTesting) {
2468 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2470 def envScriptCmds = envScriptCreate(os, scriptFileName)
2471 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2472 envScriptCmds += envScriptFinalize(os, scriptFileName)
2473 buildCommands += envScriptCmds
2475 // Build and text corefx
2476 def workspaceRelativeFxRootLinux = "_/fx"
2477 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRootLinux}"
2478 def fxBranch = getFxBranch(branch)
2480 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"
2482 // Docker creates files with root permission, so we need to zip in docker also, or else we'll get permission errors.
2483 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxruntime.zip ${workspaceRelativeFxRootLinux}/bin/testhost/netcoreapp-Linux-Release-${architecture}"
2484 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxtests.zip ${workspaceRelativeFxRootLinux}/bin/tests"
2486 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2487 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2489 else if (isCrossGenComparisonScenario(scenario)) {
2490 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2492 def workspaceRelativeProductBinDir = "bin/Product/${osGroup}.${architecture}.${configuration}"
2493 def workspaceRelativeCoreLib = "${workspaceRelativeProductBinDir}/IL/System.Private.CoreLib.dll"
2494 def workspaceRelativeCoreRootDir = "bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root"
2495 def workspaceRelativeCrossGenComparisonScript = "tests/scripts/crossgen_comparison.py"
2496 def workspaceRelativeResultsDir = "_"
2497 def workspaceRelativeArtifactsArchive = "${os}.${architecture}.${configuration}.${scenario}.zip"
2498 def crossGenComparisonCmd = "python -u \${WORKSPACE}/${workspaceRelativeCrossGenComparisonScript} "
2499 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
2500 def crossGenExecutable = "\${WORKSPACE}/${workspaceRelativeProductBinDir}/${crossArch}/crossgen"
2501 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
2503 buildCommands += "${dockerCmd}mkdir -p \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2504 buildCommands += "${dockerCmd}${crossGenComparisonCmd}crossgen_corelib --crossgen ${crossGenExecutable} --il_corelib \${WORKSPACE}/${workspaceRelativeCoreLib} --result_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2505 buildCommands += "${dockerCmd}${crossGenComparisonCmd}crossgen_framework --crossgen ${crossGenExecutable} --core_root \${WORKSPACE}/${workspaceRelativeCoreRootDir} --result_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2507 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeArtifactsArchive} ${workspaceRelativeCoreLib} ${workspaceRelativeCoreRootDir} ${workspaceRelativeCrossGenComparisonScript} ${workspaceRelativeResultsDir}"
2508 Utilities.addArchival(newJob, "${workspaceRelativeArtifactsArchive}")
2510 else if (architecture == 'arm') {
2511 // Then, using the same docker image, generate the CORE_ROOT layout using build-test.sh to
2512 // download the appropriate CoreFX packages.
2513 // Note that docker should not be necessary here, for the "generatelayoutonly" case, but we use it
2514 // just to be consistent with the "build.sh" case -- so both are run with the same environment.
2516 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2518 // ZIP up for the test job (created in the flow job code):
2519 // (1) the built CORE_ROOT, /home/user/coreclr/bin/tests/Linux.arm.Checked/Tests/Core_Root,
2520 // used by runtest.sh as the "--coreOverlayDir" argument.
2521 // (2) the native parts of the test build: /home/user/coreclr/bin/obj/Linux.arm.Checked/tests,
2522 // used by runtest.sh as the "--testNativeBinDir" argument.
2524 // These commands are assumed to be run from the root of the workspace.
2525 buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root"
2526 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2528 Utilities.addArchival(newJob, "coreroot.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2531 assert architecture == 'arm64'
2533 // Then, using the same docker image, build the tests and generate the CORE_ROOT layout.
2534 // Linux/arm64 does not use Windows-built tests.
2536 def testBuildOpts = ""
2537 if (priority == '1') {
2538 testBuildOpts = "priority1"
2541 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross ${testBuildOpts}"
2543 // ZIP up the built tests (including CORE_ROOT and native test components copied to the CORE_ROOT) for the test job (created in the flow job code)
2544 buildCommands += "zip -r tests.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}"
2546 // We still use the testnativebin files until they get placed properly in the tests directory (next to their respective tests).
2547 // With https://github.com/dotnet/coreclr/pull/19918 this shouldn't be needed anymore.
2548 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2550 Utilities.addArchival(newJob, "tests.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2553 // Archive the build logs from both product and test builds.
2554 Utilities.addArchival(newJob, "bin/Logs/*.log,bin/Logs/*.wrn,bin/Logs/*.err", "")
2556 // We need to clean up the build machines; the docker build leaves newly built files with root permission, which
2557 // the cleanup task in Jenkins can't remove.
2560 azureVMAgentPostBuildAction {
2561 agentPostBuildAction('Delete agent after build execution (when idle).')
2567 println("Unknown architecture: ${architecture}");
2572 // editor brace matching: }
2574 println("Unknown os: ${os}");
2579 return buildCommands
2582 // Determine if we should generate a job for the given parameters. This is for non-flow jobs: either build and test, or build only.
2583 // Returns true if the job should be generated.
2584 def static shouldGenerateJob(def scenario, def isPR, def architecture, def configuration, def os, def isBuildOnly)
2586 // The various "innerloop" jobs are only available as PR triggered.
2589 if (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked')) {
2590 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
2591 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
2595 if (isInnerloopTestScenario(scenario)) {
2599 if (scenario == 'corefx_innerloop') {
2604 // Tizen is only supported for armem architecture
2605 if (os == 'Tizen' && architecture != 'armem') {
2609 // Filter based on architecture.
2611 switch (architecture) {
2613 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2618 if ((os != 'Windows_NT') && (os != 'Ubuntu16.04')) {
2623 if (os != 'Tizen') {
2627 case 'x86_arm_altjit':
2628 case 'x64_arm64_altjit':
2629 if (os != 'Windows_NT') {
2634 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2639 // Everything implemented
2642 println("Unknown architecture: ${architecture}")
2647 // Which (Windows) build only jobs are required?
2649 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
2652 switch (architecture) {
2655 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2656 if (!isCoreFxScenario(scenario)) {
2662 if (!isNormalOrInnerloop) {
2671 // Filter based on scenario.
2673 if (isJitStressScenario(scenario)) {
2674 if (configuration != 'Checked') {
2678 def isEnabledOS = (os == 'Windows_NT') ||
2679 (os == 'Ubuntu' && (architecture == 'x64') && isCoreFxScenario(scenario)) ||
2680 (os == 'Ubuntu' && architecture == 'arm') ||
2681 (os == 'Ubuntu16.04' && architecture == 'arm64')
2686 switch (architecture) {
2688 case 'x86_arm_altjit':
2689 case 'x64_arm64_altjit':
2693 // x86 ubuntu: no stress modes
2694 if (os == 'Ubuntu') {
2701 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2702 // No "regular" Windows arm corefx jobs, e.g.
2703 // For Ubuntu arm corefx testing, we use regular jobs (not "build only" since only Windows has "build only", and
2704 // the Ubuntu arm "regular" jobs don't run tests anyway).
2705 if (os == 'Windows_NT') {
2706 if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
2711 if (!isCoreFxScenario(scenario)) {
2718 // armem: no stress jobs for ARM emulator.
2722 else if (isR2RScenario(scenario)) {
2723 if (os != 'Windows_NT') {
2727 if (isR2RBaselineScenario(scenario)) {
2728 // no need for Debug scenario; Checked is sufficient
2729 if (configuration != 'Checked' && configuration != 'Release') {
2733 else if (isR2RStressScenario(scenario)) {
2734 // Stress scenarios only run with Checked builds, not Release (they would work with Debug, but be slow).
2735 if (configuration != 'Checked') {
2740 switch (architecture) {
2743 // Windows arm/arm64 ready-to-run jobs use flow jobs and test jobs, but depend on "normal" (not R2R specific) build jobs.
2750 else if (isCrossGenComparisonScenario(scenario)) {
2751 return shouldGenerateCrossGenComparisonJob(os, architecture, configuration, scenario)
2757 // The ilrt build isn't necessary except for Windows_NT2003. Non-Windows NT uses
2758 // the default scenario build
2759 if (os != 'Windows_NT') {
2763 if (architecture != 'x64') {
2767 if (configuration != 'Release') {
2772 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2775 if (architecture != 'x64') {
2778 if (configuration != 'Checked') {
2784 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2787 if (architecture != 'x64') {
2790 if (configuration != 'Release') {
2794 case 'gc_reliability_framework':
2795 case 'standalone_gc':
2796 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2800 if (architecture != 'x64') {
2804 if (configuration != 'Release' && configuration != 'Checked') {
2808 // We only run Windows and Ubuntu x64 Checked for formatting right now
2810 if (os != 'Windows_NT' && os != 'Ubuntu') {
2813 if (architecture != 'x64') {
2816 if (configuration != 'Checked') {
2821 if (os != 'Windows_NT' && (os != 'Ubuntu' || architecture != 'x64')) {
2824 if (architecture != 'x64' && architecture != 'x86') {
2832 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly)) {
2836 case 'corefx_innerloop':
2837 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2840 if (architecture != 'x64') {
2845 println("Unknown scenario: ${scenario}")
2851 // For altjit, don't do any scenarios that don't change compilation. That is, scenarios that only change
2852 // runtime behavior, not compile-time behavior, are not interesting.
2853 switch (architecture) {
2854 case 'x86_arm_altjit':
2855 case 'x64_arm64_altjit':
2856 if (isGCStressRelatedTesting(scenario)) {
2864 // The job was not filtered out, so we should generate it!
2868 Constants.allScenarios.each { scenario ->
2869 [true, false].each { isPR ->
2870 Constants.architectureList.each { architecture ->
2871 Constants.configurationList.each { configuration ->
2872 Constants.osList.each { os ->
2873 // If the OS is Windows_NT_BuildOnly, set the isBuildOnly flag to true
2874 // and reset the os to Windows_NT
2875 def isBuildOnly = false
2876 if (os == 'Windows_NT_BuildOnly') {
2881 if (!shouldGenerateJob(scenario, isPR, architecture, configuration, os, isBuildOnly)) {
2886 def jobName = getJobName(configuration, architecture, os, scenario, isBuildOnly)
2887 def folderName = getJobFolder(scenario)
2889 // Create the new job
2890 def newJob = job(Utilities.getFullJobName(project, jobName, isPR, folderName)) {}
2892 addToViews(newJob, false, isPR, architecture, os, configuration, scenario) // isFlowJob == false
2894 setJobMachineAffinity(architecture, os, true, false, false, newJob) // isBuildJob = true, isTestJob = false, isFlowJob = false
2896 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
2897 addTriggers(newJob, branch, isPR, architecture, os, configuration, scenario, false, isBuildOnly) // isFlowJob==false
2898 setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly)
2900 // Copy Windows build test binaries and corefx build artifacts for Linux cross build for armem.
2901 // We don't use a flow job for this, but we do depend on there being existing builds with these
2902 // artifacts produced.
2903 if ((architecture == 'armem') && (os == 'Tizen')) {
2904 // Define the Windows Tests and Corefx build job names
2905 def lowerConfiguration = configuration.toLowerCase()
2906 def WindowsTestsName = projectFolder + '/' +
2907 Utilities.getFullJobName(project,
2908 getJobName(lowerConfiguration, 'x64' , 'windows_nt', 'normal', true),
2910 def fxBranch = getFxBranch(branch)
2911 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' +
2912 Utilities.getFolderName(fxBranch)
2914 def arm_abi = 'armel'
2915 def corefx_os = 'tizen'
2917 // Let's use release CoreFX to test checked CoreCLR,
2918 // because we do not generate checked CoreFX in CoreFX CI yet.
2919 def corefx_lowerConfiguration = lowerConfiguration
2920 if (lowerConfiguration == 'checked') {
2921 corefx_lowerConfiguration = 'release'
2924 // Copy the Windows test binaries and the Corefx build binaries
2927 copyArtifacts(WindowsTestsName) {
2928 includePatterns('bin/tests/tests.zip')
2930 latestSuccessful(true)
2933 copyArtifacts("${corefxFolder}/${corefx_os}_${arm_abi}_cross_${corefx_lowerConfiguration}") {
2934 includePatterns('bin/build.tar.gz')
2936 latestSuccessful(true)
2943 def buildCommands = calculateBuildCommands(newJob, scenario, branch, isPR, architecture, configuration, os, isBuildOnly)
2947 if (os == 'Windows_NT') {
2948 buildCommands.each { buildCommand ->
2949 batchFile(buildCommand)
2953 buildCommands.each { buildCommand ->
2966 // Create a Windows ARM/ARM64 test job that will be used by a flow job.
2967 // Returns the newly created job.
2968 def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
2970 def osGroup = getOSGroup(os)
2971 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
2973 def jobFolder = getJobFolder(scenario)
2974 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
2976 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
2980 // Set up the copies
2982 // Coreclr build we are trying to test
2984 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
2986 copyArtifacts(inputCoreCLRBuildName) {
2987 excludePatterns('**/testResults.xml', '**/*.ni.dll')
2989 buildNumber('${CORECLR_BUILD}')
2993 if (isCoreFxScenario(scenario)) {
2995 // Only arm/arm64 supported for corefx testing now.
2996 assert architecture == 'arm' || architecture == 'arm64'
2998 // Unzip CoreFx runtime
2999 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}')\"")
3001 // Unzip CoreFx tests.
3002 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxtests.zip', '_\\fx\\bin\\tests')\"")
3004 // Add the script to run the corefx tests
3005 def corefx_runtime_path = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}"
3006 def corefx_tests_dir = "%WORKSPACE%\\_\\fx\\bin\\tests"
3007 def corefx_exclusion_file = "%WORKSPACE%\\tests\\${architecture}\\corefx_test_exclusions.txt"
3008 batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file} ${architecture}")
3010 } else { // !isCoreFxScenario(scenario)
3013 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}')\"")
3015 def buildCommands = ""
3017 def coreRootLocation = "%WORKSPACE%\\bin\\tests\\Windows_NT.${architecture}.${configuration}\\Tests\\Core_Root"
3018 def addEnvVariable = { variable, value -> buildCommands += "set ${variable}=${value}\r\n"}
3019 def addCommand = { cmd -> buildCommands += "${cmd}\r\n"}
3021 // Make sure Command Extensions are enabled. Used so %ERRORLEVEL% is available.
3022 addCommand("SETLOCAL ENABLEEXTENSIONS")
3025 addEnvVariable("CORE_ROOT", coreRootLocation)
3026 addEnvVariable("COMPlus_NoGuiOnAssert", "1")
3027 addEnvVariable("COMPlus_ContinueOnAssert", "0")
3029 // If we are running a stress mode, we'll set those variables as well
3030 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
3031 def stressValues = null
3032 if (isJitStressScenario(scenario)) {
3033 stressValues = Constants.jitStressModeScenarios[scenario]
3036 stressValues = Constants.r2rStressScenarios[scenario]
3039 stressValues.each { key, value ->
3040 addEnvVariable(key, value)
3044 if (isR2RScenario(scenario)) {
3045 // Crossgen the framework assemblies.
3046 buildCommands += """
3047 @for %%F in (%CORE_ROOT%\\*.dll) do @call :PrecompileAssembly "%CORE_ROOT%" "%%F" %%~nxF
3048 @goto skip_PrecompileAssembly
3051 @REM Skip mscorlib since it is already precompiled.
3052 @if /I "%3" == "mscorlib.dll" exit /b 0
3053 @if /I "%3" == "mscorlib.ni.dll" exit /b 0
3055 "%CORE_ROOT%\\crossgen.exe" /Platform_Assemblies_Paths "%CORE_ROOT%" %2 >nul 2>nul
3056 @if "%errorlevel%" == "-2146230517" (
3057 echo %2 is not a managed assembly.
3058 ) else if "%errorlevel%" == "-2146234344" (
3059 echo %2 is not a managed assembly.
3060 ) else if %errorlevel% neq 0 (
3061 echo Unable to precompile %2
3067 :skip_PrecompileAssembly
3070 // Set RunCrossGen variable to cause test wrappers to invoke their logic to run
3071 // crossgen on tests before running them.
3072 addEnvVariable("RunCrossGen", "true")
3073 } // isR2RScenario(scenario)
3075 // Create the smarty command
3076 def smartyCommand = "C:\\Tools\\Smarty.exe /noecid /noie /workers 9 /inc EXPECTED_PASS "
3077 def addSmartyFlag = { flag -> smartyCommand += flag + " "}
3078 def addExclude = { exclude -> addSmartyFlag("/exc " + exclude)}
3079 def addArchSpecificExclude = { architectureToExclude, exclude -> addExclude(exclude) }
3081 // Exclude tests based on scenario.
3082 Constants.validArmWindowsScenarios[scenario].each { excludeTag ->
3083 addArchSpecificExclude(architecture, excludeTag)
3086 if (isInnerloopTestScenario(scenario)) {
3090 // Exclude any test marked LONG_RUNNING; these often exceed the standard timeout and fail as a result.
3091 // TODO: We should create a "long running" job that runs these with a longer timeout.
3092 addExclude("LONG_RUNNING")
3094 smartyCommand += "/lstFile Tests.lst"
3096 def testListArch = [
3101 def archLocation = testListArch[architecture]
3103 addCommand("copy %WORKSPACE%\\tests\\${archLocation}\\Tests.lst bin\\tests\\${osGroup}.${architecture}.${configuration}")
3104 addCommand("pushd bin\\tests\\${osGroup}.${architecture}.${configuration}")
3105 addCommand("${smartyCommand}")
3107 // Save the errorlevel from the smarty command to be used as the errorlevel of this batch file.
3108 // However, we also need to remove all the variables that were set during this batch file, so we
3109 // can run the ZIP powershell command (below) in a clean environment. (We can't run the powershell
3110 // command with the COMPlus_AltJit variables set, for example.) To do that, we do ENDLOCAL as well
3111 // as save the current errorlevel on the same line. This works because CMD evaluates the %errorlevel%
3112 // variable expansion (or any variable expansion on the line) BEFORE it executes the ENDLOCAL command.
3113 // Note that the ENDLOCAL also undoes the pushd command, but we add the popd here for clarity.
3114 addCommand("popd & ENDLOCAL & set __save_smarty_errorlevel=%errorlevel%")
3116 // ZIP up the smarty output, no matter what the smarty result.
3117 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')\"")
3119 addCommand("echo %errorlevel%")
3120 addCommand("dir .\\bin\\tests\\${osGroup}.${architecture}.${configuration}")
3122 // Use the smarty errorlevel as the script errorlevel.
3123 addCommand("exit /b %__save_smarty_errorlevel%")
3125 batchFile(buildCommands)
3126 } // non-corefx testing
3130 if (!isCoreFxScenario(scenario)) {
3131 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0/*.smrt", '', true, false)
3133 // Archive a ZIP file of the entire Smarty.run.0 directory. This is possibly a little too much,
3134 // but there is no easy way to only archive the HTML/TXT files of the failing tests, so we get
3135 // all the passing test info as well. Not necessarily a bad thing, but possibly somewhat large.
3136 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0.zip", '', true, false)
3142 // Create a test job not covered by the "Windows ARM" case that will be used by a flow job.
3143 // E.g., non-Windows tests.
3144 // Returns the newly created job.
3145 def static CreateOtherTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3147 def lowerConfiguration = configuration.toLowerCase()
3149 def isUbuntuArm64Job = ((os == "Ubuntu16.04") && (architecture == 'arm64'))
3150 def isUbuntuArm32Job = ((os == "Ubuntu") && (architecture == 'arm'))
3151 def isUbuntuArmJob = isUbuntuArm32Job || isUbuntuArm64Job
3153 def doCoreFxTesting = isCoreFxScenario(scenario)
3155 def workspaceRelativeFxRootLinux = "_/fx" // only used for CoreFX testing
3157 def osGroup = getOSGroup(os)
3158 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3161 def useServerGC = false
3163 // Enable Server GC for Ubuntu PR builds
3164 // REVIEW: why? Does this apply to all architectures? Why only PR?
3165 if (os == 'Ubuntu' && isPR) {
3166 testOpts += ' --useServerGC'
3170 if (isR2RScenario(scenario)) {
3172 testOpts += ' --crossgen --runcrossgentests'
3174 if (scenario == 'r2r_jitstress1') {
3175 testOpts += ' --jitstress=1'
3177 else if (scenario == 'r2r_jitstress2') {
3178 testOpts += ' --jitstress=2'
3180 else if (scenario == 'r2r_jitstress1_tiered') {
3181 testOpts += ' --jitstress=1'
3183 else if (scenario == 'r2r_jitstress2_tiered') {
3184 testOpts += ' --jitstress=2'
3186 else if (scenario == 'r2r_jitstressregs1') {
3187 testOpts += ' --jitstressregs=1'
3189 else if (scenario == 'r2r_jitstressregs2') {
3190 testOpts += ' --jitstressregs=2'
3192 else if (scenario == 'r2r_jitstressregs3') {
3193 testOpts += ' --jitstressregs=3'
3195 else if (scenario == 'r2r_jitstressregs4') {
3196 testOpts += ' --jitstressregs=4'
3198 else if (scenario == 'r2r_jitstressregs8') {
3199 testOpts += ' --jitstressregs=8'
3201 else if (scenario == 'r2r_jitstressregs0x10') {
3202 testOpts += ' --jitstressregs=0x10'
3204 else if (scenario == 'r2r_jitstressregs0x80') {
3205 testOpts += ' --jitstressregs=0x80'
3207 else if (scenario == 'r2r_jitstressregs0x1000') {
3208 testOpts += ' --jitstressregs=0x1000'
3210 else if (scenario == 'r2r_jitminopts') {
3211 testOpts += ' --jitminopts'
3213 else if (scenario == 'r2r_jitforcerelocs') {
3214 testOpts += ' --jitforcerelocs'
3216 else if (scenario == 'r2r_gcstress15') {
3217 testOpts += ' --gcstresslevel=0xF'
3220 else if (scenario == 'jitdiff') {
3221 testOpts += ' --jitdisasm --crossgen'
3223 else if (scenario == 'illink') {
3224 testOpts += ' --link=\$WORKSPACE/linker/linker/bin/netcore_Release/netcoreapp2.0/ubuntu-x64/publish/illink'
3226 else if (isLongGc(scenario)) {
3227 // Long GC tests behave very poorly when they are not
3228 // the only test running (many of them allocate until OOM).
3229 testOpts += ' --sequential'
3231 // A note - runtest.sh does have "--long-gc" and "--gcsimulator" options
3232 // for running long GC and GCSimulator tests, respectively. We don't use them
3233 // here because using a playlist file produces much more readable output on the CI machines
3234 // and reduces running time.
3236 // The Long GC playlist contains all of the tests that are
3237 // going to be run. The GCSimulator playlist contains all of
3238 // the GC simulator tests.
3239 if (scenario == 'longgc') {
3240 testOpts += ' --long-gc --playlist=./tests/longRunningGcTests.txt'
3242 else if (scenario == 'gcsimulator') {
3243 testOpts += ' --gcsimulator --playlist=./tests/gcSimulatorTests.txt'
3246 else if (isGcReliabilityFramework(scenario)) {
3247 testOpts += ' --build-overlay-only'
3249 else if (scenario == 'standalone_gc') {
3250 if (osGroup == 'OSX') {
3251 testOpts += ' --gcname=libclrgc.dylib'
3253 else if (osGroup == 'Linux') {
3254 testOpts += ' --gcname=libclrgc.so'
3257 println("Unexpected OS group: ${osGroup} for os ${os}")
3262 // The ARM Ubuntu corefx test job doesn't depend on a Windows test build, and hence inputTestsBuildName
3263 // will be null in this case.
3265 def jobFolder = getJobFolder(scenario)
3266 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3268 if (inputTestsBuildName != null) {
3269 stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR Windows test binaries from')
3271 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3275 // Set up the copies
3277 // Coreclr build containing the tests and mscorlib
3278 // pri1 jobs still need to copy windows_nt built tests
3279 if (inputTestsBuildName != null) {
3280 copyArtifacts(inputTestsBuildName) {
3281 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3283 buildNumber('${CORECLR_WINDOWS_BUILD}')
3288 // Coreclr build we are trying to test
3290 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
3292 // HACK: the Ubuntu arm64 copyArtifacts Jenkins plug-in is ridiculously slow (45 minutes to
3293 // 1.5 hours for this step). Instead, directly use wget, which is fast (1 minute).
3295 if (!isUbuntuArm64Job) {
3296 copyArtifacts(inputCoreCLRBuildName) {
3297 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3299 buildNumber('${CORECLR_BUILD}')
3304 if (isUbuntuArmJob) {
3305 // Add some useful information to the log file. Ignore return codes.
3306 shell("uname -a || true")
3309 if (isUbuntuArm64Job) {
3310 // Copy the required artifacts directly, using wget, e.g.:
3312 // https://ci.dot.net/job/dotnet_coreclr/job/master/job/arm64_cross_checked_ubuntu16.04_innerloop_prtest/16/artifact/testnativebin.checked.zip
3313 // https://ci.dot.net/job/dotnet_coreclr/job/master/job/arm64_cross_checked_ubuntu16.04_innerloop_prtest/16/artifact/tests.checked.zip
3315 // parameterized as:
3317 // https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/job/${inputJobName}/${CORECLR_BUILD}/artifact/testnativebin.checked.zip
3318 // https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/job/${inputJobName}/${CORECLR_BUILD}/artifact/tests.checked.zip
3320 // CoreFX example artifact URLs:
3322 // https://ci.dot.net/job/dotnet_coreclr/job/dev_unix_test_workflow/job/jitstress/job/arm64_cross_checked_ubuntu16.04_corefx_baseline_prtest/1/artifact/_/fx/fxruntime.zip
3323 // https://ci.dot.net/job/dotnet_coreclr/job/dev_unix_test_workflow/job/jitstress/job/arm64_cross_checked_ubuntu16.04_corefx_baseline_prtest/1/artifact/_/fx/fxtests.zip
3325 // Note that the source might be in a "jitstress" folder.
3327 // Use `--progress=dot:giga` to display some progress output, but limit it in the log file.
3329 // Use `--directory-prefix=_/fx` to specify where to put the corefx files (to match what other platforms do). Use this instead of `-O`.
3331 shell("echo \"Using wget instead of the Jenkins copy artifacts plug-in to copy artifacts from ${inputCoreCLRBuildName}\"")
3333 def mungedProjectName = Utilities.getFolderName(project)
3334 def mungedBranchName = Utilities.getFolderName(branch)
3336 def doCrossGenComparison = isCrossGenComparisonScenario(scenario)
3337 def inputCoreCLRBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3338 if (doCoreFxTesting || doCrossGenComparison) {
3339 // These depend on unique builds for each scenario
3340 inputCoreCLRBuildScenario = scenario
3342 def sourceJobName = getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, false)
3343 def inputJobName = Utilities.getFullJobName(sourceJobName, isPR)
3345 // Need to add the sub-folder if necessary.
3346 def inputJobPath = "job/${inputJobName}"
3347 def folderName = getJobFolder(inputCoreCLRBuildScenario)
3348 if (folderName != '') {
3349 inputJobPath = "job/${folderName}/job/${inputJobName}"
3352 def inputUrlRoot = "https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/${inputJobPath}/\${CORECLR_BUILD}/artifact"
3354 if (doCoreFxTesting) {
3355 shell("mkdir -p ${workspaceRelativeFxRootLinux}")
3356 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/fxtests.zip")
3357 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/fxruntime.zip")
3360 shell("wget --progress=dot:giga ${inputUrlRoot}/testnativebin.${lowerConfiguration}.zip")
3361 shell("wget --progress=dot:giga ${inputUrlRoot}/tests.${lowerConfiguration}.zip")
3365 if (architecture == 'x86') {
3366 shell("mkdir ./bin/CoreFxNative")
3368 def fxBranch = getFxBranch(branch)
3369 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' + Utilities.getFolderName(fxBranch)
3371 copyArtifacts("${corefxFolder}/ubuntu16.04_x86_release") {
3372 includePatterns('bin/build.tar.gz')
3373 targetDirectory('bin/CoreFxNative')
3375 latestSuccessful(true)
3379 shell("mkdir ./bin/CoreFxBinDir")
3380 shell("tar -xf ./bin/CoreFxNative/bin/build.tar.gz -C ./bin/CoreFxBinDir")
3383 // CoreFX testing downloads the CoreFX tests, not the coreclr tests. Also, unzip the built CoreFX layout/runtime directories.
3384 if (doCoreFxTesting) {
3385 shell("unzip -q -o ${workspaceRelativeFxRootLinux}/fxtests.zip || exit 0")
3386 shell("unzip -q -o ${workspaceRelativeFxRootLinux}/fxruntime.zip || exit 0")
3388 else if (architecture != 'arm64') {
3389 // ARM64 copies the tests from the build machine; this is for unzip'ing tests copied from a Windows build.
3391 // Unzip the tests first. Exit with 0
3392 shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/${osGroup}.${architecture}.${configuration} || exit 0")
3393 shell("rm -r ./bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root || exit 0")
3396 // For arm Ubuntu (on hardware), we do the "build-test" step on the build machine, not on the test
3397 // machine. The arm Ubuntu test machines do no building -- they have no CLI, for example.
3398 // We should probably do the "generatelayoutonly" step on the build machine for all architectures.
3399 // However, it's believed that perhaps there's an issue with executable permission bits not getting
3400 // copied correctly.
3401 if (!doCoreFxTesting) {
3402 if (isUbuntuArmJob) {
3403 if (architecture == 'arm') {
3404 shell("unzip -q -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root
3405 shell("unzip -q -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3408 assert architecture == 'arm64'
3409 shell("unzip -q -o ./tests.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}
3411 // We still the testnativebin files until they get placed properly in the tests directory (next to their respective tests).
3412 shell("unzip -q -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3416 shell("./build-test.sh ${architecture} ${configuration} generatelayoutonly")
3420 // Execute the tests
3421 def runDocker = isNeedDocker(architecture, os, false)
3422 def dockerPrefix = ""
3425 def dockerImage = getDockerImageName(architecture, os, false)
3426 dockerPrefix = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} "
3427 dockerCmd = dockerPrefix + "${dockerImage} "
3430 // If we are running a stress mode, we'll set those variables first.
3431 // For CoreFX, the stress variables are already built into the CoreFX test build per-test wrappers.
3432 if (!doCoreFxTesting && isJitStressScenario(scenario)) {
3433 def scriptFileName = "\${WORKSPACE}/set_stress_test_env.sh"
3434 def envScriptCmds = envScriptCreate(os, scriptFileName)
3435 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
3436 envScriptCmds += envScriptFinalize(os, scriptFileName)
3437 shell("${envScriptCmds}")
3438 testOpts += " --test-env=${scriptFileName}"
3441 // setup-stress-dependencies.sh, invoked by runtest.sh to download the coredistools package, depends on the "dotnet"
3442 // tool downloaded by the "init-tools.sh" script. However, it only invokes setup-stress-dependencies.sh for x64. The
3443 // coredistools package is used by GCStress on x86 and x64 to disassemble code to determine instruction boundaries.
3444 // On arm/arm64, it is not required as determining instruction boundaries is trivial.
3445 if (isGCStressRelatedTesting(scenario)) {
3446 if (architecture == 'x64') {
3447 shell('./init-tools.sh')
3451 if (doCoreFxTesting) {
3453 \${WORKSPACE}/tests/scripts/run-corefx-tests.sh --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""")
3456 def runScript = "${dockerCmd}./tests/runtest.sh"
3458 // TODO: the testNativeBinDir shouldn't be necessary if the native test binaries are placed properly with their corresponding managed test code.
3462 --testRootDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}\" \\
3463 --coreOverlayDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root\" \\
3464 --testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
3465 --copyNativeTestBin --limitedDumpGeneration ${testOpts}""")
3468 if (isGcReliabilityFramework(scenario)) {
3469 // runtest.sh doesn't actually execute the reliability framework - do it here.
3472 dockerCmd = dockerPrefix + "-e COMPlus_gcServer=1 ${dockerImage} "
3475 shell("export COMPlus_gcServer=1")
3479 shell("${dockerCmd}./tests/scripts/run-gc-reliability-framework.sh ${architecture} ${configuration}")
3484 // Experimental: If on Ubuntu 14.04, then attempt to pull in crash dump links
3485 if (os in ['Ubuntu']) {
3486 SummaryBuilder summaries = new SummaryBuilder()
3487 summaries.addLinksSummaryFromFile('Crash dumps from this run:', 'dumplings.txt')
3488 summaries.emit(newJob)
3491 if (doCoreFxTesting) {
3492 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3493 if ((os == "Ubuntu") && (architecture == 'arm')) {
3494 // We have a problem with the xunit plug-in, where it is consistently failing on Ubuntu arm32 test result uploading with this error:
3496 // [xUnit] [ERROR] - The plugin hasn't been performed correctly: remote file operation failed: /ssd/j/workspace/dotnet_coreclr/master/jitstress/arm_cross_checked_ubuntu_corefx_baseline_tst at hudson.remoting.Channel@3697f46d:JNLP4-connect connection from 131.107.159.149/131.107.159.149:58529: java.io.IOException: Remote call on JNLP4-connect connection from 131.107.159.149/131.107.159.149:58529 failed
3498 // We haven't been able to identify the reason. So, do not add xunit parsing of the test data in this scenario.
3499 // This is tracked by: https://github.com/dotnet/coreclr/issues/19447.
3502 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3506 Utilities.addXUnitDotNETResults(newJob, '**/coreclrtests.xml')
3512 def static CreateNonWindowsCrossGenComparisonTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
3514 assert isCrossGenComparisonScenario(scenario)
3516 def osGroup = getOSGroup(os)
3517 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3519 def workspaceRelativeResultsDir = "_"
3520 def workspaceRelativeNativeArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${architecture}_${architecture}.${configuration}"
3522 def jobFolder = getJobFolder(scenario)
3523 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3525 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3528 def workspaceRelativeArtifactsArchive = "${os}.${architecture}.${configuration}.${scenario}.zip"
3531 copyArtifacts(inputCoreCLRBuildName) {
3532 includePatterns("${workspaceRelativeArtifactsArchive}")
3534 buildNumber('${CORECLR_BUILD}')
3538 shell("unzip -o ${workspaceRelativeArtifactsArchive} || exit 0")
3540 def workspaceRelativeCoreLib = "bin/Product/${osGroup}.${architecture}.${configuration}/IL/System.Private.CoreLib.dll"
3541 def workspaceRelativeCoreRootDir = "bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root"
3542 def workspaceRelativeCrossGenComparisonScript = "tests/scripts/crossgen_comparison.py"
3543 def workspaceRelativeCrossGenExecutable = "${workspaceRelativeCoreRootDir}/crossgen"
3545 def crossGenComparisonCmd = "python -u \${WORKSPACE}/${workspaceRelativeCrossGenComparisonScript} "
3546 def crossGenExecutable = "\${WORKSPACE}/${workspaceRelativeCrossGenExecutable}"
3548 shell("mkdir -p ${workspaceRelativeNativeArchResultDir}")
3549 shell("${crossGenComparisonCmd}crossgen_corelib --crossgen ${crossGenExecutable} --il_corelib \${WORKSPACE}/${workspaceRelativeCoreLib} --result_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir}")
3550 shell("${crossGenComparisonCmd}crossgen_framework --crossgen ${crossGenExecutable} --core_root \${WORKSPACE}/${workspaceRelativeCoreRootDir} --result_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir}")
3552 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
3553 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
3554 shell("${crossGenComparisonCmd}compare --base_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir} --diff_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}")
3559 Utilities.addArchival(newJob, "${workspaceRelativeNativeArchResultDir}/**")
3560 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
3561 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
3562 Utilities.addArchival(newJob, "${workspaceRelativeCrossArchResultDir}/**")
3568 // Create a test job that will be used by a flow job.
3569 // Returns the newly created job.
3570 // 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,
3571 // and we want the views to be the minimal set of "top-level" jobs that represent all work.
3572 def static CreateTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3574 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3577 if (windowsArmJob) {
3578 assert inputTestsBuildName == null
3579 newJob = CreateWindowsArmTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3581 else if (isCrossGenComparisonScenario(scenario)) {
3582 assert inputTestsBuildName == null
3583 newJob = CreateNonWindowsCrossGenComparisonTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3586 newJob = CreateOtherTestJob(dslFactory, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3589 setJobMachineAffinity(architecture, os, false, true, false, newJob) // isBuildJob = false, isTestJob = true, isFlowJob = false
3591 if (scenario == 'jitdiff') {
3592 def osGroup = getOSGroup(os)
3593 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/dasm/**")
3596 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
3597 setJobTimeout(newJob, isPR, architecture, configuration, scenario, false)
3602 // Create a flow job to tie together a build job with the given test job.
3603 // The 'inputTestsBuildName' argument might be null if the flow job doesn't depend on a Windows build job.
3604 // Returns the new flow job.
3605 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)
3607 // Windows CoreCLR build and Linux CoreCLR build (in parallel) ->
3608 // Linux CoreCLR test
3609 def flowJobName = getJobName(configuration, architecture, os, scenario, false) + "_flow"
3610 def jobFolder = getJobFolder(scenario)
3612 def newFlowJob = null
3614 if (inputTestsBuildName == null) {
3615 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3617 coreclrBuildJob = build(params, '${inputCoreCLRBuildName}')
3619 // And then build the test build
3620 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number], '${fullTestJobName}')
3623 JobReport.Report.addReference(inputCoreCLRBuildName)
3624 JobReport.Report.addReference(fullTestJobName)
3627 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3629 // Build the input jobs in parallel
3631 { coreclrBuildJob = build(params, '${inputCoreCLRBuildName}') },
3632 { windowsBuildJob = build(params, '${inputTestsBuildName}') }
3635 // And then build the test build
3636 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number,
3637 CORECLR_WINDOWS_BUILD: windowsBuildJob.build.number], '${fullTestJobName}')
3640 JobReport.Report.addReference(inputCoreCLRBuildName)
3641 JobReport.Report.addReference(inputTestsBuildName)
3642 JobReport.Report.addReference(fullTestJobName)
3645 addToViews(newFlowJob, true, isPR, architecture, os, configuration, scenario) // isFlowJob = true
3647 setJobMachineAffinity(architecture, os, false, false, true, newFlowJob) // isBuildJob = false, isTestJob = false, isFlowJob = true
3649 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
3650 addTriggers(newFlowJob, branch, isPR, architecture, os, configuration, scenario, true, false) // isFlowJob==true, isWindowsBuildOnlyJob==false
3655 // Determine if we should generate a flow job for the given parameters.
3656 // Returns true if the job should be generated.
3657 def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def configuration, def os)
3659 // The various "innerloop" jobs are only available as PR triggered.
3662 if (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked')) {
3663 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
3664 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
3668 if (isInnerloopTestScenario(scenario)) {
3672 if (scenario == 'corefx_innerloop') {
3677 // Filter based on OS and architecture.
3679 switch (architecture) {
3681 if (os != "Ubuntu" && os != "Windows_NT") {
3686 if (os != "Ubuntu16.04" && os != "Windows_NT") {
3691 if (os != "Ubuntu") {
3696 if (!(os in Constants.crossList)) {
3699 if (os == "Windows_NT") {
3704 case 'x86_arm_altjit':
3705 case 'x64_arm64_altjit':
3709 println("Unknown architecture: ${architecture}")
3714 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
3716 // Filter based on scenario in OS.
3718 if (os == 'Windows_NT') {
3719 assert architecture == 'arm' || architecture == 'arm64'
3720 if (!isArmWindowsScenario(scenario)) {
3723 if (isNormalOrInnerloop && (configuration == 'Debug')) {
3724 // The arm32/arm64 Debug configuration for innerloop/normal scenario is a special case: it does a build only, and no test run.
3725 // To do that, it doesn't require a flow job.
3731 if (architecture == 'arm') {
3732 if (!(scenario in Constants.validLinuxArmScenarios)) {
3736 else if (architecture == 'arm64') {
3737 if (!(scenario in Constants.validLinuxArm64Scenarios)) {
3741 else if (architecture == 'x86') {
3742 // Linux/x86 only want innerloop and default test
3743 if (!isNormalOrInnerloop) {
3747 else if (architecture == 'x64') {
3748 // Linux/x64 corefx testing doesn't need a flow job; the "build" job runs run-corefx-tests.py which
3749 // builds and runs the corefx tests. Other Linux/x64 flow jobs are required to get the test
3750 // build from a Windows machine.
3751 if (isCoreFxScenario(scenario)) {
3757 // For CentOS, we only want Checked/Release builds.
3758 if (os == 'CentOS7.1') {
3759 if (configuration != 'Checked' && configuration != 'Release') {
3762 if (!isNormalOrInnerloop && !isR2RScenario(scenario)) {
3767 // For RedHat and Debian, we only do Release builds.
3768 else if (os == 'RHEL7.2' || os == 'Debian8.4') {
3769 if (configuration != 'Release') {
3772 if (!isNormalOrInnerloop) {
3777 // Next, filter based on scenario.
3779 if (isJitStressScenario(scenario)) {
3780 if (configuration != 'Checked') {
3784 else if (isR2RBaselineScenario(scenario)) {
3785 if (configuration != 'Checked' && configuration != 'Release') {
3789 else if (isR2RStressScenario(scenario)) {
3790 if (configuration != 'Checked') {
3794 else if (isCrossGenComparisonScenario(scenario)) {
3795 return shouldGenerateCrossGenComparisonJob(os, architecture, configuration, scenario)
3803 // Long GC tests take a long time on non-Release builds
3804 // ilrt is also Release only
3805 if (configuration != 'Release') {
3811 if (configuration != 'Checked') {
3816 case 'gc_reliability_framework':
3817 case 'standalone_gc':
3818 if (configuration != 'Release' && configuration != 'Checked') {
3827 if (os != 'Windows_NT' && os != 'Ubuntu') {
3837 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, false)) {
3842 case 'corefx_innerloop':
3843 // No flow job needed
3847 println("Unknown scenario: ${scenario}")
3853 // The job was not filtered out, so we should generate it!
3857 // Create jobs requiring flow jobs. This includes x64 non-Windows, arm/arm64 Ubuntu, and arm/arm64 Windows.
3858 Constants.allScenarios.each { scenario ->
3859 [true, false].each { isPR ->
3860 Constants.architectureList.each { architecture ->
3861 Constants.configurationList.each { configuration ->
3862 Constants.osList.each { os ->
3864 if (!shouldGenerateFlowJob(scenario, isPR, architecture, configuration, os)) {
3868 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3869 def doCoreFxTesting = isCoreFxScenario(scenario)
3870 def doCrossGenComparison = isCrossGenComparisonScenario(scenario)
3872 // Figure out the job name of the CoreCLR build the test will depend on.
3874 def inputCoreCLRBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3875 def inputCoreCLRBuildIsBuildOnly = false
3876 if (doCoreFxTesting) {
3877 // Every CoreFx test depends on its own unique build.
3878 inputCoreCLRBuildScenario = scenario
3879 if (windowsArmJob) {
3880 // Only Windows ARM corefx jobs use "build only" jobs. Others, such as Ubuntu ARM corefx, use "regular" jobs.
3881 inputCoreCLRBuildIsBuildOnly = true
3884 if (doCrossGenComparison) {
3885 inputCoreCLRBuildScenario = scenario
3888 def inputCoreCLRFolderName = getJobFolder(inputCoreCLRBuildScenario)
3889 def inputCoreCLRBuildName = projectFolder + '/' +
3890 Utilities.getFullJobName(project, getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, inputCoreCLRBuildIsBuildOnly), isPR, inputCoreCLRFolderName)
3892 // Figure out the name of the build job that the test job will depend on.
3893 // For Windows ARM tests, this is not used, as the CoreCLR build creates the tests. For other
3894 // tests (e.g., Linux ARM), we depend on a Windows build to get the tests.
3895 // For CoreFX tests, however, Linux doesn't need the Windows build for the tests, since the
3896 // CoreFX build creates the tests.
3898 def inputTestsBuildName = null
3900 // Ubuntu Arm64 jobs do the test build on the build machine, and thus don't depend on a Windows build.
3901 def isUbuntuArm64Job = ((os == "Ubuntu16.04") && (architecture == 'arm64'))
3903 if (!windowsArmJob && !doCoreFxTesting & !doCrossGenComparison && !isUbuntuArm64Job) {
3904 def testBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3906 def inputTestsBuildArch = architecture
3907 if (architecture == "arm") {
3908 // Use the x86 test build for arm unix
3909 inputTestsBuildArch = "x86"
3912 def inputTestsBuildIsBuildOnly = true
3914 inputTestsBuildName = projectFolder + '/' +
3915 Utilities.getFullJobName(project, getJobName(configuration, inputTestsBuildArch, 'windows_nt', testBuildScenario, inputTestsBuildIsBuildOnly), isPR)
3918 // =============================================================================================
3919 // Create the test job
3920 // =============================================================================================
3922 def testJob = CreateTestJob(this, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3924 // =============================================================================================
3925 // Create a build flow to join together the build and tests required to run this test.
3926 // =============================================================================================
3928 if (os == 'RHEL7.2' || os == 'Debian8.4') {
3929 // Do not create the flow job for RHEL jobs.
3933 def fullTestJobName = projectFolder + '/' + testJob.name
3934 def flowJob = CreateFlowJob(this, project, branch, architecture, os, configuration, scenario, isPR, fullTestJobName, inputCoreCLRBuildName, inputTestsBuildName)
3942 JobReport.Report.generateJobReport(out)
3944 // Make the call to generate the help job
3945 Utilities.createHelperJob(this, project, branch,
3946 "Welcome to the ${project} Repository", // This is prepended to the help message
3947 "Have a nice day!") // This is appended to the help message. You might put known issues here.
3949 Utilities.addCROSSCheck(this, project, branch)