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') && !isCoreFxScenario(scenario)) {
1590 // These jobs are very fast on Linux/arm64 hardware, so run them daily.
1591 // TODO: When the corefx jobs are made to run in parallel, run those
1592 // jobs daily as well.
1593 addPeriodicTriggerHelper(job, '@daily')
1596 addPeriodicTriggerHelper(job, '@weekly')
1600 addPeriodicTriggerHelper(job, '@daily')
1605 if (os == 'CentOS7.1') {
1608 if (os in bidailyCrossList) {
1611 addPeriodicTriggerHelper(job, '@weekly')
1614 case 'gcstress0xc_zapdisable':
1615 case 'gcstress0xc_zapdisable_jitstress2':
1616 case 'gcstress0xc_zapdisable_heapverify1':
1617 case 'gcstress0xc_jitstress1':
1618 case 'gcstress0xc_jitstress2':
1619 case 'gcstress0xc_minopts_heapverify1':
1620 if (os == 'OSX10.12') {
1621 // GCStress=C is currently not supported on OS X
1624 if (os == 'CentOS7.1') {
1627 if (os in bidailyCrossList) {
1630 addPeriodicTriggerHelper(job, '@weekly')
1634 // Testing on other operating systems TBD
1635 assert (os == 'Windows_NT' || os == 'Ubuntu')
1636 if (architecture == 'x64' || architecture == 'x86') {
1637 if (configuration == 'Checked') {
1638 addPeriodicTriggerHelper(job, '@daily')
1644 println("Unknown scenario: ${scenario}");
1651 // **************************
1652 // Define the basic inner loop builds for PR and commit. This is basically just the set
1653 // of coreclr builds over linux/osx 10.12/windows and debug/release/checked. In addition, the windows
1654 // builds will do a couple extra steps.
1655 // **************************
1657 // Adds a trigger for the PR build if one is needed. If isFlowJob is true, then this is the
1658 // flow job that rolls up the build and test for non-windows OS's. // If the job is a windows build only job,
1659 // it's just used for internal builds
1660 // If you add a job with a trigger phrase, please add that phrase to coreclr/Documentation/project-docs/ci-trigger-phrases.md
1661 def static addTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob) {
1662 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1664 if (isWindowsBuildOnlyJob) {
1668 def bidailyCrossList = ['RHEL7.2', 'Debian8.4']
1669 // Non pull request builds.
1671 addNonPRTriggers(job, branch, isPR, architecture, os, configuration, scenario, isFlowJob, isWindowsBuildOnlyJob, bidailyCrossList)
1696 // Pull request builds. Generally these fall into two categories: default triggers and on-demand triggers
1697 // We generally only have a distinct set of default triggers but a bunch of on-demand ones.
1699 def contextString = ""
1700 def triggerString = ""
1701 def needsTrigger = true
1702 def isDefaultTrigger = false
1703 def isArm64PrivateJob = false
1704 def scenarioString = ""
1706 // Set up default context string and trigger phrases. This is overridden in places, sometimes just to keep
1707 // the existing non-standard descriptions and phrases. In some cases, the scenarios are asymmetric, as for
1708 // some jobs where the Debug configuration just does builds, no tests.
1710 // Some configurations, like arm32/arm64, always use the exact scenario name as part of the context string.
1711 // This makes it possible to copy/paste the displayed context string as "@dotnet-bot test <context-string>"
1712 // to invoke the trigger. Any "fancy" context string makes that impossible, requiring the user to either
1713 // remember the mapping from context string to trigger string, or use "@dotnet-bot help" to look it up.
1715 if (architecture == 'armem') {
1716 assert os == 'Tizen'
1717 architecture = 'armel'
1720 switch (architecture) {
1721 case 'x64_arm64_altjit':
1722 case 'x86_arm_altjit':
1723 // TODO: for consistency, add "Build and Test" at end.
1724 contextString = "${os} ${architecture} ${configuration} ${scenario}"
1725 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*"
1731 contextString = "${os} ${architecture} Cross ${configuration}"
1732 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}"
1734 if (scenario == 'innerloop') {
1735 contextString += " Innerloop"
1736 triggerString += "\\W+Innerloop"
1739 contextString += " ${scenario}"
1740 triggerString += "\\W+${scenario}"
1743 if (configuration == 'Debug') {
1744 contextString += " Build"
1745 triggerString += "\\W+Build"
1748 contextString += " Build and Test"
1749 triggerString += "\\W+Build and Test"
1752 triggerString += ".*"
1756 scenarioString = getScenarioDisplayString(scenario)
1757 contextString = "${os} ${architecture} ${configuration} ${scenarioString}"
1758 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}"
1762 triggerString += "\\W+Build and Test.*"
1765 case 'corefx_innerloop': // maintain this asymmetry
1766 triggerString += "\\W+CoreFX Tests.*"
1770 triggerString += "\\W+${scenario}.*"
1774 triggerString += ".*"
1778 // Now determine what kind of trigger this job needs, if any. Any job should be triggerable, except for
1779 // non-flow jobs that are only used as part of flow jobs.
1781 switch (architecture) {
1782 case 'x64': // editor brace matching: {
1783 if (scenario == 'formatting') {
1784 assert configuration == 'Checked'
1785 if (os == 'Windows_NT' || os == 'Ubuntu') {
1786 isDefaultTrigger = true
1787 contextString = "${os} ${architecture} Formatting"
1793 // OpenSUSE, Debian & RedHat get trigger phrases for pri 0 build, and pri 1 build & test
1796 if (scenario == 'innerloop') {
1798 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1799 isDefaultTrigger = true
1809 assert scenario != 'innerloop'
1810 contextString = "${os} ${architecture} ${configuration} Build"
1811 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+Build.*"
1815 if (scenario == 'illink') {
1818 else if (scenario == 'corefx_innerloop') {
1819 if (configuration == 'Checked') {
1820 isDefaultTrigger = true
1828 // Triggers on the non-flow jobs aren't necessary here
1829 // Corefx testing uses non-flow jobs.
1830 if (!isFlowJob && !isCoreFxScenario(scenario)) {
1831 needsTrigger = false
1836 isDefaultTrigger = true
1839 case 'no_tiered_compilation_innerloop':
1840 if (os == 'Ubuntu') {
1841 isDefaultTrigger = true
1853 // CentOS uses checked for default PR tests while debug is build only
1854 if (configuration == 'Debug') {
1855 isDefaultTrigger = true
1856 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1860 // Make sure this is a flow job to get build and test.
1862 needsTrigger = false
1866 if (configuration == 'Checked') {
1867 assert job.name.contains("flow")
1868 isDefaultTrigger = true
1869 contextString = "${os} ${architecture} ${configuration} Innerloop Build and Test"
1874 // Make sure this is a flow job to get build and test.
1876 needsTrigger = false
1889 case 'no_tiered_compilation_innerloop':
1890 isDefaultTrigger = true
1893 case 'corefx_innerloop':
1894 if (configuration == 'Checked' || configuration == 'Release') {
1895 isDefaultTrigger = true
1905 println("Unknown os: ${os}");
1912 // editor brace matching: }
1914 case 'armel': // editor brace matching: {
1917 azureVMAgentPostBuildAction {
1918 agentPostBuildAction('Delete agent if the build was not successful (when idle).')
1925 if (scenario == 'innerloop') {
1926 if (configuration == 'Checked') {
1927 isDefaultTrigger = true
1934 // editor brace matching: }
1937 case 'arm64': // editor brace matching: {
1943 // Triggers on the non-flow jobs aren't necessary
1945 needsTrigger = false
1951 case 'no_tiered_compilation_innerloop':
1952 if (configuration == 'Checked') {
1953 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
1954 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
1955 if (architecture == 'arm64') {
1958 isDefaultTrigger = true
1965 assert isArmWindowsScenario(scenario)
1967 // 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
1968 // the non-flow Build job. All others need a trigger on the flow job.
1969 def needsFlowJobTrigger = !(isNormalOrInnerloop && (configuration == 'Debug'))
1970 if (isFlowJob != needsFlowJobTrigger) {
1971 needsTrigger = false
1977 if (configuration == 'Debug') {
1978 // Add default PR trigger for Windows arm64 Debug builds. This is a build only -- no tests are run --
1979 // so the private test hardware is not used. Thus, it can be run by all users, not just arm64Users.
1980 // People in arm64Users will get both this and the Checked Build and Test job.
1981 isDefaultTrigger = true
1982 } else if (configuration == 'Checked') {
1983 isDefaultTrigger = true
1984 isArm64PrivateJob = true
1988 isArm64PrivateJob = true
1993 println("NYI os: ${os}");
1999 // editor brace matching: }
2000 case 'x86': // editor brace matching: {
2001 assert ((os == 'Windows_NT') || ((os == 'Ubuntu') && isNormalOrInnerloop))
2002 if (os == 'Ubuntu') {
2003 // Triggers on the non-flow jobs aren't necessary here
2005 needsTrigger = false
2009 // on-demand only for ubuntu x86
2010 contextString = "${os} ${architecture} ${configuration} Build"
2011 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}.*"
2016 case 'no_tiered_compilation_innerloop':
2017 isDefaultTrigger = true
2024 // editor brace matching: }
2025 case 'x64_arm64_altjit':
2026 case 'x86_arm_altjit':
2027 // Everything default
2031 println("Unknown architecture: ${architecture}");
2037 if (isArm64PrivateJob) {
2038 if (isDefaultTrigger) {
2039 Utilities.addDefaultPrivateGithubPRTriggerForBranch(job, branch, contextString, null, arm64Users)
2042 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
2046 if (isDefaultTrigger) {
2047 Utilities.addGithubPRTriggerForBranch(job, branch, contextString)
2050 Utilities.addGithubPRTriggerForBranch(job, branch, contextString, triggerString)
2056 def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR, def architecture, def configuration, def os, def isBuildOnly) {
2057 def buildCommands = []
2058 def osGroup = getOSGroup(os)
2059 def lowerConfiguration = configuration.toLowerCase()
2062 if (isInnerloopTestScenario(scenario)) {
2066 def doCoreFxTesting = isCoreFxScenario(scenario)
2068 // Calculate the build steps, archival, and xunit results
2070 case 'Windows_NT': // editor brace matching: {
2071 switch (architecture) {
2074 case 'x86_arm_altjit':
2075 case 'x64_arm64_altjit':
2076 def arch = architecture
2078 if (architecture == 'x86_arm_altjit') {
2081 else if (architecture == 'x64_arm64_altjit') {
2085 if (scenario == 'formatting') {
2086 buildCommands += "python -u tests\\scripts\\format.py -c %WORKSPACE% -o Windows_NT -a ${arch}"
2087 Utilities.addArchival(newJob, "format.patch", "", true, false)
2091 if (scenario == 'illink') {
2092 buildCommands += "tests\\scripts\\build_illink.cmd clone ${arch}"
2095 // If it is a release build for Windows, ensure PGO is used, else fail the build.
2096 if ((lowerConfiguration == 'release') &&
2097 (scenario in Constants.basicScenarios) &&
2098 (architecture != 'x86_arm_altjit') &&
2099 (architecture != 'x64_arm64_altjit')) {
2101 buildOpts += ' -enforcepgo'
2104 if (doCoreFxTesting) {
2105 buildOpts += ' skiptests';
2107 buildOpts += " -priority=${priority}"
2110 // Set __TestIntermediateDir to something short. If __TestIntermediateDir is already set, build-test.cmd will
2111 // output test binaries to that directory. If it is not set, the binaries are sent to a default directory whose name is about
2112 // 35 characters long.
2114 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts}"
2117 def runtestArguments = ''
2118 def testOpts = 'collectdumps'
2120 if (isR2RScenario(scenario)) {
2122 // If this is a ReadyToRun scenario, pass 'crossgen' or 'crossgenaltjit'
2123 // to cause framework assemblies to be crossgen'ed. Pass 'runcrossgentests'
2124 // to cause the tests to be crossgen'ed.
2126 if ((architecture == 'x86_arm_altjit') || (architecture == 'x64_arm64_altjit')) {
2127 testOpts += ' crossgenaltjit protononjit.dll'
2129 testOpts += ' crossgen'
2132 testOpts += ' runcrossgentests'
2134 else if (scenario == 'jitdiff') {
2135 testOpts += ' jitdisasm crossgen'
2137 else if (scenario == 'ilrt') {
2138 testOpts += ' ilasmroundtrip'
2140 else if (isLongGc(scenario)) {
2141 testOpts += " ${scenario} sequential"
2143 else if (scenario == 'standalone_gc') {
2144 testOpts += ' gcname clrgc.dll'
2146 else if (scenario == 'illink') {
2147 testOpts += " link %WORKSPACE%\\linker\\linker\\bin\\netcore_Release\\netcoreapp2.0\\win10-${arch}\\publish\\illink.exe"
2150 // Default per-test timeout is 10 minutes. For stress modes and Debug scenarios, increase this
2151 // to 30 minutes (30 * 60 * 1000 = 180000). The "timeout" argument to runtest.cmd sets this, by
2152 // taking a timeout value in milliseconds. (Note that it sets the __TestTimeout environment variable,
2153 // which is read by the xunit harness.)
2154 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario) || (lowerConfiguration == 'debug'))
2156 def timeout = 1800000
2157 testOpts += " timeout ${timeout}"
2160 // If we are running a stress mode, we should write out the set of key
2161 // value env pairs to a file at this point and then we'll pass that to runtest.cmd
2163 def envScriptPath = ''
2164 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2165 def buildCommandsStr = ''
2166 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2167 buildCommandsStr += envScriptCreate(os, envScriptPath)
2169 if (isJitStressScenario(scenario)) {
2170 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2172 else if (isR2RStressScenario(scenario)) {
2173 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.r2rStressScenarios[scenario], envScriptPath)
2176 if (architecture == 'x86_arm_altjit') {
2177 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x86_arm_altjit.cmd", envScriptPath)
2179 else if (architecture == 'x64_arm64_altjit') {
2180 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd", envScriptPath)
2183 envScriptFinalize(os, envScriptPath)
2185 // Note that buildCommands is an array of individually executed commands; we want all the commands used to
2186 // create the SetStressModes.bat script to be executed together, hence we accumulate them as strings
2187 // into a single script.
2188 buildCommands += buildCommandsStr
2190 else if (architecture == 'x86_arm_altjit') {
2191 envScriptPath = "%WORKSPACE%\\tests\\x86_arm_altjit.cmd"
2193 else if (architecture == 'x64_arm64_altjit') {
2194 envScriptPath = "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd"
2196 if (envScriptPath != '') {
2197 testOpts += " TestEnv ${envScriptPath}"
2200 runtestArguments = "${lowerConfiguration} ${arch} ${testOpts}"
2202 if (doCoreFxTesting) {
2203 if (scenario == 'corefx_innerloop') {
2204 // Create CORE_ROOT and testhost
2205 buildCommands += "build-test.cmd ${lowerConfiguration} ${arch} buildtesthostonly"
2206 buildCommands += "tests\\runtest.cmd ${runtestArguments} CoreFXTestsAll"
2208 // Archive and process (only) the test results
2209 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2210 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2213 def workspaceRelativeFxRoot = "_/fx"
2214 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2215 def fxBranch = getFxBranch(branch)
2217 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}"
2219 // Archive and process (only) the test results
2220 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2221 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2223 //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
2224 Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
2225 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
2228 else if (isGcReliabilityFramework(scenario)) {
2229 buildCommands += "tests\\runtest.cmd ${runtestArguments} GenerateLayoutOnly"
2230 buildCommands += "tests\\scripts\\run-gc-reliability-framework.cmd ${arch} ${configuration}"
2233 buildCommands += "tests\\runtest.cmd ${runtestArguments}"
2235 } // end if (!isBuildOnly)
2237 if (!doCoreFxTesting) {
2238 // Run the rest of the build
2239 // Build the mscorlib for the other OS's
2240 buildCommands += "build.cmd ${lowerConfiguration} ${arch} linuxmscorlib"
2241 buildCommands += "build.cmd ${lowerConfiguration} ${arch} osxmscorlib"
2243 if (arch == 'x64') {
2244 buildCommands += "build.cmd ${lowerConfiguration} arm64 linuxmscorlib"
2247 // Zip up the tests directory so that we don't use so much space/time copying
2248 // 10s of thousands of files around.
2249 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')\"";
2251 if (!isJitStressScenario(scenario)) {
2252 // For Windows, pull full test results and test drops for x86/x64.
2253 // No need to pull for stress mode scenarios (downstream builds use the default scenario)
2254 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2257 if (scenario == 'jitdiff') {
2258 // retrieve jit-dasm output for base commit, and run jit-diff
2260 // if this is a build only job, we want to keep the default (build) artifacts for the flow job
2261 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${arch}.${configuration}/dasm/**")
2266 Utilities.addXUnitDotNETResults(newJob, 'bin/**/TestRun*.xml', true)
2272 assert isArmWindowsScenario(scenario)
2276 if (doCoreFxTesting) {
2277 buildOpts += ' skiptests'
2279 buildOpts += " -priority=${priority}"
2282 // This is now a build only job. Do not run tests. Use the flow job.
2283 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} ${buildOpts}"
2285 if (doCoreFxTesting) {
2288 // Set the stress mode variables; this is incorporated into the generated CoreFx RunTests.cmd files.
2289 def envScriptPath = ''
2290 def buildCommandsStr = ''
2291 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2292 buildCommandsStr += envScriptCreate(os, envScriptPath)
2293 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2294 envScriptFinalize(os, envScriptPath)
2295 buildCommands += buildCommandsStr
2297 def workspaceRelativeFxRootLinux = "_/fx"
2298 def workspaceRelativeFxRootWin = "_\\fx"
2299 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2300 def fxBranch = getFxBranch(branch)
2302 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"
2304 // Zip up the CoreFx runtime and tests. We don't need the CoreCLR binaries; they have been copied to the CoreFX tree.
2305 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')\"";
2306 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\tests', '${workspaceRelativeFxRootWin}\\fxtests.zip')\"";
2308 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2309 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2311 // Zip up the tests directory so that we don't use so much space/time copying
2312 // 10s of thousands of files around.
2313 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')\"";
2316 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2320 println("Unknown architecture: ${architecture}");
2325 // end case 'Windows_NT'; editor brace matching: }
2334 case 'Fedora24': // editor brace matching: {
2335 switch (architecture) {
2338 if (architecture == 'x86' && os == 'Ubuntu') {
2339 // build and PAL test
2340 def dockerImage = getDockerImageName(architecture, os, true)
2341 buildCommands += "docker run -i --rm -v \${WORKSPACE}:/opt/code -w /opt/code -e ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} ./build.sh ${architecture} cross ${lowerConfiguration}"
2342 dockerImage = getDockerImageName(architecture, os, false)
2343 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"
2344 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2345 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2349 if (scenario == 'formatting') {
2350 buildCommands += "python tests/scripts/format.py -c \${WORKSPACE} -o Linux -a ${architecture}"
2351 Utilities.addArchival(newJob, "format.patch", "", true, false)
2355 if (scenario == 'illink') {
2356 assert(os == 'Ubuntu')
2357 buildCommands += "./tests/scripts/build_illink.sh --clone --arch=${architecture}"
2360 if (!doCoreFxTesting) {
2361 // We run pal tests on all OS but generate mscorlib (and thus, nuget packages)
2362 // only on supported OS platforms.
2363 def bootstrapRid = Utilities.getBoostrapPublishRid(os)
2364 def bootstrapRidEnv = bootstrapRid != null ? "__PUBLISH_RID=${bootstrapRid} " : ''
2366 buildCommands += "${bootstrapRidEnv}./build.sh ${lowerConfiguration} ${architecture}"
2367 buildCommands += "src/pal/tests/palsuite/runpaltests.sh \${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration} \${WORKSPACE}/bin/paltestout"
2369 // Basic archiving of the build
2370 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2372 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2375 if (scenario == 'corefx_innerloop') {
2376 assert os == 'Ubuntu' || 'OSX10.12'
2377 assert architecture == 'x64'
2379 buildCommands += "./build.sh ${lowerConfiguration} ${architecture} skiptests"
2380 buildCommands += "./build-test.sh ${lowerConfiguration} ${architecture} generatetesthostonly"
2381 buildCommands += "./tests/runtest.sh --corefxtestsall --testHostDir=\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/testhost/ --coreclr-src=\${WORKSPACE}"
2384 // Archive and process (only) the test results
2385 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2386 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2389 // Corefx stress testing
2390 assert os == 'Ubuntu'
2391 assert architecture == 'x64'
2392 assert lowerConfiguration == 'checked'
2393 assert isJitStressScenario(scenario)
2396 buildCommands += "./build.sh ${lowerConfiguration} ${architecture}"
2398 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2400 def envScriptCmds = envScriptCreate(os, scriptFileName)
2401 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2402 envScriptCmds += envScriptFinalize(os, scriptFileName)
2403 buildCommands += envScriptCmds
2405 // Build and text corefx
2406 def workspaceRelativeFxRoot = "_/fx"
2407 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRoot}"
2408 def fxBranch = getFxBranch(branch)
2410 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}"
2412 // Archive and process (only) the test results
2413 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2414 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2419 // Emulator cross builds for ARM runs on Tizen currently
2420 assert os == 'Tizen'
2422 def arm_abi = "armel"
2423 def linuxCodeName = "tizen"
2425 // Unzip the Windows test binaries first. Exit with 0
2426 buildCommands += "unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.x64.${configuration} || exit 0"
2428 // Unpack the corefx binaries
2429 buildCommands += "mkdir ./bin/CoreFxBinDir"
2430 buildCommands += "tar -xf ./bin/build.tar.gz -C ./bin/CoreFxBinDir"
2432 // Call the ARM CI script to cross build and test using docker
2433 buildCommands += """./tests/scripts/arm32_ci_script.sh \\
2436 --linuxCodeName=${linuxCodeName} \\
2437 --buildConfig=${lowerConfiguration} \\
2438 --testRootDir=./bin/tests/Windows_NT.x64.${configuration} \\
2439 --coreFxBinDir=./bin/CoreFxBinDir \\
2440 --testDirFile=./tests/testsRunningInsideARM.txt"""
2442 // Basic archiving of the build, no pal tests
2443 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2447 // Non-Windows ARM cross builds on hardware run on Ubuntu only
2448 assert (os == 'Ubuntu') || (os == 'Ubuntu16.04')
2450 // Add some useful information to the log file. Ignore return codes.
2451 buildCommands += "uname -a || true"
2453 def additionalOpts = ""
2454 if (architecture == 'arm') {
2455 additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86"
2458 // Cross build the Ubuntu/arm product using docker with a docker image that contains the correct
2459 // Ubuntu cross-compilation toolset (running on a Ubuntu x64 host).
2460 // For CoreFX testing, we only need the product build; we don't need to generate the layouts. The product
2461 // build is then copied into the corefx layout by the run-corefx-test.py script. For CoreFX testing, we
2462 // ZIP up the generated CoreFX runtime and tests.
2464 def dockerImage = getDockerImageName(architecture, os, true)
2465 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} "
2467 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh ${lowerConfiguration} ${architecture} cross crosscomponent"
2469 if (doCoreFxTesting) {
2470 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2472 def envScriptCmds = envScriptCreate(os, scriptFileName)
2473 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2474 envScriptCmds += envScriptFinalize(os, scriptFileName)
2475 buildCommands += envScriptCmds
2477 // Build and text corefx
2478 def workspaceRelativeFxRootLinux = "_/fx"
2479 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRootLinux}"
2480 def fxBranch = getFxBranch(branch)
2482 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"
2484 // Docker creates files with root permission, so we need to zip in docker also, or else we'll get permission errors.
2485 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxruntime.zip ${workspaceRelativeFxRootLinux}/bin/testhost/netcoreapp-Linux-Release-${architecture}"
2486 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxtests.zip ${workspaceRelativeFxRootLinux}/bin/tests"
2488 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2489 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2490 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/run-test.sh")
2492 else if (isCrossGenComparisonScenario(scenario)) {
2493 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2495 def workspaceRelativeProductBinDir = "bin/Product/${osGroup}.${architecture}.${configuration}"
2496 def workspaceRelativeCoreLib = "${workspaceRelativeProductBinDir}/IL/System.Private.CoreLib.dll"
2497 def workspaceRelativeCoreRootDir = "bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root"
2498 def workspaceRelativeCrossGenComparisonScript = "tests/scripts/crossgen_comparison.py"
2499 def workspaceRelativeResultsDir = "_"
2500 def workspaceRelativeArtifactsArchive = "${os}.${architecture}.${configuration}.${scenario}.zip"
2501 def crossGenComparisonCmd = "python -u \${WORKSPACE}/${workspaceRelativeCrossGenComparisonScript} "
2502 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
2503 def crossGenExecutable = "\${WORKSPACE}/${workspaceRelativeProductBinDir}/${crossArch}/crossgen"
2504 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
2506 buildCommands += "${dockerCmd}mkdir -p \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2507 buildCommands += "${dockerCmd}${crossGenComparisonCmd}crossgen_corelib --crossgen ${crossGenExecutable} --il_corelib \${WORKSPACE}/${workspaceRelativeCoreLib} --result_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2508 buildCommands += "${dockerCmd}${crossGenComparisonCmd}crossgen_framework --crossgen ${crossGenExecutable} --core_root \${WORKSPACE}/${workspaceRelativeCoreRootDir} --result_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2510 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeArtifactsArchive} ${workspaceRelativeCoreLib} ${workspaceRelativeCoreRootDir} ${workspaceRelativeCrossGenComparisonScript} ${workspaceRelativeResultsDir}"
2511 Utilities.addArchival(newJob, "${workspaceRelativeArtifactsArchive}")
2513 else if (architecture == 'arm') {
2514 // Then, using the same docker image, generate the CORE_ROOT layout using build-test.sh to
2515 // download the appropriate CoreFX packages.
2516 // Note that docker should not be necessary here, for the "generatelayoutonly" case, but we use it
2517 // just to be consistent with the "build.sh" case -- so both are run with the same environment.
2519 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2521 // ZIP up for the test job (created in the flow job code):
2522 // (1) the built CORE_ROOT, /home/user/coreclr/bin/tests/Linux.arm.Checked/Tests/Core_Root,
2523 // used by runtest.sh as the "--coreOverlayDir" argument.
2524 // (2) the native parts of the test build: /home/user/coreclr/bin/obj/Linux.arm.Checked/tests,
2525 // used by runtest.sh as the "--testNativeBinDir" argument.
2527 // These commands are assumed to be run from the root of the workspace.
2528 buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root"
2529 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2531 Utilities.addArchival(newJob, "coreroot.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2534 assert architecture == 'arm64'
2536 // Then, using the same docker image, build the tests and generate the CORE_ROOT layout.
2537 // Linux/arm64 does not use Windows-built tests.
2539 def testBuildOpts = ""
2540 if (priority == '1') {
2541 testBuildOpts = "priority1"
2544 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross ${testBuildOpts}"
2546 // 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)
2547 buildCommands += "zip -r tests.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}"
2549 // We still use the testnativebin files until they get placed properly in the tests directory (next to their respective tests).
2550 // With https://github.com/dotnet/coreclr/pull/19918 this shouldn't be needed anymore.
2551 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2553 Utilities.addArchival(newJob, "tests.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2556 // Archive the build logs from both product and test builds.
2557 Utilities.addArchival(newJob, "bin/Logs/*.log,bin/Logs/*.wrn,bin/Logs/*.err", "")
2559 // We need to clean up the build machines; the docker build leaves newly built files with root permission, which
2560 // the cleanup task in Jenkins can't remove.
2563 azureVMAgentPostBuildAction {
2564 agentPostBuildAction('Delete agent after build execution (when idle).')
2570 println("Unknown architecture: ${architecture}");
2575 // editor brace matching: }
2577 println("Unknown os: ${os}");
2582 return buildCommands
2585 // Determine if we should generate a job for the given parameters. This is for non-flow jobs: either build and test, or build only.
2586 // Returns true if the job should be generated.
2587 def static shouldGenerateJob(def scenario, def isPR, def architecture, def configuration, def os, def isBuildOnly)
2589 // The various "innerloop" jobs are only available as PR triggered.
2592 if (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked')) {
2593 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
2594 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
2598 if (isInnerloopTestScenario(scenario)) {
2602 if (scenario == 'corefx_innerloop') {
2607 // Tizen is only supported for armem architecture
2608 if (os == 'Tizen' && architecture != 'armem') {
2612 // Filter based on architecture.
2614 switch (architecture) {
2616 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2621 if ((os != 'Windows_NT') && (os != 'Ubuntu16.04')) {
2626 if (os != 'Tizen') {
2630 case 'x86_arm_altjit':
2631 case 'x64_arm64_altjit':
2632 if (os != 'Windows_NT') {
2637 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2642 // Everything implemented
2645 println("Unknown architecture: ${architecture}")
2650 // Which (Windows) build only jobs are required?
2652 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
2655 switch (architecture) {
2658 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2659 if (!isCoreFxScenario(scenario)) {
2665 if (!isNormalOrInnerloop) {
2674 // Filter based on scenario.
2676 if (isJitStressScenario(scenario)) {
2677 if (configuration != 'Checked') {
2681 def isEnabledOS = (os == 'Windows_NT') ||
2682 (os == 'Ubuntu' && (architecture == 'x64') && isCoreFxScenario(scenario)) ||
2683 (os == 'Ubuntu' && architecture == 'arm') ||
2684 (os == 'Ubuntu16.04' && architecture == 'arm64')
2689 switch (architecture) {
2691 case 'x86_arm_altjit':
2692 case 'x64_arm64_altjit':
2696 // x86 ubuntu: no stress modes
2697 if (os == 'Ubuntu') {
2704 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2705 // No "regular" Windows arm corefx jobs, e.g.
2706 // For Ubuntu arm corefx testing, we use regular jobs (not "build only" since only Windows has "build only", and
2707 // the Ubuntu arm "regular" jobs don't run tests anyway).
2708 if (os == 'Windows_NT') {
2709 if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
2714 if (!isCoreFxScenario(scenario)) {
2721 // armem: no stress jobs for ARM emulator.
2725 else if (isR2RScenario(scenario)) {
2726 if (os != 'Windows_NT') {
2730 if (isR2RBaselineScenario(scenario)) {
2731 // no need for Debug scenario; Checked is sufficient
2732 if (configuration != 'Checked' && configuration != 'Release') {
2736 else if (isR2RStressScenario(scenario)) {
2737 // Stress scenarios only run with Checked builds, not Release (they would work with Debug, but be slow).
2738 if (configuration != 'Checked') {
2743 switch (architecture) {
2746 // Windows arm/arm64 ready-to-run jobs use flow jobs and test jobs, but depend on "normal" (not R2R specific) build jobs.
2753 else if (isCrossGenComparisonScenario(scenario)) {
2754 return shouldGenerateCrossGenComparisonJob(os, architecture, configuration, scenario)
2760 // The ilrt build isn't necessary except for Windows_NT2003. Non-Windows NT uses
2761 // the default scenario build
2762 if (os != 'Windows_NT') {
2766 if (architecture != 'x64') {
2770 if (configuration != 'Release') {
2775 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2778 if (architecture != 'x64') {
2781 if (configuration != 'Checked') {
2787 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2790 if (architecture != 'x64') {
2793 if (configuration != 'Release') {
2797 case 'gc_reliability_framework':
2798 case 'standalone_gc':
2799 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2803 if (architecture != 'x64') {
2807 if (configuration != 'Release' && configuration != 'Checked') {
2811 // We only run Windows and Ubuntu x64 Checked for formatting right now
2813 if (os != 'Windows_NT' && os != 'Ubuntu') {
2816 if (architecture != 'x64') {
2819 if (configuration != 'Checked') {
2824 if (os != 'Windows_NT' && (os != 'Ubuntu' || architecture != 'x64')) {
2827 if (architecture != 'x64' && architecture != 'x86') {
2835 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly)) {
2839 case 'corefx_innerloop':
2840 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2843 if (architecture != 'x64') {
2848 println("Unknown scenario: ${scenario}")
2854 // For altjit, don't do any scenarios that don't change compilation. That is, scenarios that only change
2855 // runtime behavior, not compile-time behavior, are not interesting.
2856 switch (architecture) {
2857 case 'x86_arm_altjit':
2858 case 'x64_arm64_altjit':
2859 if (isGCStressRelatedTesting(scenario)) {
2867 // The job was not filtered out, so we should generate it!
2871 Constants.allScenarios.each { scenario ->
2872 [true, false].each { isPR ->
2873 Constants.architectureList.each { architecture ->
2874 Constants.configurationList.each { configuration ->
2875 Constants.osList.each { os ->
2876 // If the OS is Windows_NT_BuildOnly, set the isBuildOnly flag to true
2877 // and reset the os to Windows_NT
2878 def isBuildOnly = false
2879 if (os == 'Windows_NT_BuildOnly') {
2884 if (!shouldGenerateJob(scenario, isPR, architecture, configuration, os, isBuildOnly)) {
2889 def jobName = getJobName(configuration, architecture, os, scenario, isBuildOnly)
2890 def folderName = getJobFolder(scenario)
2892 // Create the new job
2893 def newJob = job(Utilities.getFullJobName(project, jobName, isPR, folderName)) {}
2895 addToViews(newJob, false, isPR, architecture, os, configuration, scenario) // isFlowJob == false
2897 setJobMachineAffinity(architecture, os, true, false, false, newJob) // isBuildJob = true, isTestJob = false, isFlowJob = false
2899 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
2900 addTriggers(newJob, branch, isPR, architecture, os, configuration, scenario, false, isBuildOnly) // isFlowJob==false
2901 setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly)
2903 // Copy Windows build test binaries and corefx build artifacts for Linux cross build for armem.
2904 // We don't use a flow job for this, but we do depend on there being existing builds with these
2905 // artifacts produced.
2906 if ((architecture == 'armem') && (os == 'Tizen')) {
2907 // Define the Windows Tests and Corefx build job names
2908 def lowerConfiguration = configuration.toLowerCase()
2909 def WindowsTestsName = projectFolder + '/' +
2910 Utilities.getFullJobName(project,
2911 getJobName(lowerConfiguration, 'x64' , 'windows_nt', 'normal', true),
2913 def fxBranch = getFxBranch(branch)
2914 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' +
2915 Utilities.getFolderName(fxBranch)
2917 def arm_abi = 'armel'
2918 def corefx_os = 'tizen'
2920 // Let's use release CoreFX to test checked CoreCLR,
2921 // because we do not generate checked CoreFX in CoreFX CI yet.
2922 def corefx_lowerConfiguration = lowerConfiguration
2923 if (lowerConfiguration == 'checked') {
2924 corefx_lowerConfiguration = 'release'
2927 // Copy the Windows test binaries and the Corefx build binaries
2930 copyArtifacts(WindowsTestsName) {
2931 includePatterns('bin/tests/tests.zip')
2933 latestSuccessful(true)
2936 copyArtifacts("${corefxFolder}/${corefx_os}_${arm_abi}_cross_${corefx_lowerConfiguration}") {
2937 includePatterns('bin/build.tar.gz')
2939 latestSuccessful(true)
2946 def buildCommands = calculateBuildCommands(newJob, scenario, branch, isPR, architecture, configuration, os, isBuildOnly)
2950 if (os == 'Windows_NT') {
2951 buildCommands.each { buildCommand ->
2952 batchFile(buildCommand)
2956 buildCommands.each { buildCommand ->
2969 // Create a Windows ARM/ARM64 test job that will be used by a flow job.
2970 // Returns the newly created job.
2971 def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
2973 def osGroup = getOSGroup(os)
2974 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
2976 def jobFolder = getJobFolder(scenario)
2977 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
2979 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
2983 // Set up the copies
2985 // Coreclr build we are trying to test
2987 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
2989 copyArtifacts(inputCoreCLRBuildName) {
2990 excludePatterns('**/testResults.xml', '**/*.ni.dll')
2992 buildNumber('${CORECLR_BUILD}')
2996 if (isCoreFxScenario(scenario)) {
2998 // Only arm/arm64 supported for corefx testing now.
2999 assert architecture == 'arm' || architecture == 'arm64'
3001 // Unzip CoreFx runtime
3002 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}')\"")
3004 // Unzip CoreFx tests.
3005 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxtests.zip', '_\\fx\\bin\\tests')\"")
3007 // Add the script to run the corefx tests
3008 def corefx_runtime_path = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}"
3009 def corefx_tests_dir = "%WORKSPACE%\\_\\fx\\bin\\tests"
3010 def corefx_exclusion_file = "%WORKSPACE%\\tests\\${architecture}\\corefx_test_exclusions.txt"
3011 batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file} ${architecture}")
3013 } else { // !isCoreFxScenario(scenario)
3016 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}')\"")
3018 def buildCommands = ""
3020 def coreRootLocation = "%WORKSPACE%\\bin\\tests\\Windows_NT.${architecture}.${configuration}\\Tests\\Core_Root"
3021 def addEnvVariable = { variable, value -> buildCommands += "set ${variable}=${value}\r\n"}
3022 def addCommand = { cmd -> buildCommands += "${cmd}\r\n"}
3024 // Make sure Command Extensions are enabled. Used so %ERRORLEVEL% is available.
3025 addCommand("SETLOCAL ENABLEEXTENSIONS")
3028 addEnvVariable("CORE_ROOT", coreRootLocation)
3029 addEnvVariable("COMPlus_NoGuiOnAssert", "1")
3030 addEnvVariable("COMPlus_ContinueOnAssert", "0")
3032 // If we are running a stress mode, we'll set those variables as well
3033 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
3034 def stressValues = null
3035 if (isJitStressScenario(scenario)) {
3036 stressValues = Constants.jitStressModeScenarios[scenario]
3039 stressValues = Constants.r2rStressScenarios[scenario]
3042 stressValues.each { key, value ->
3043 addEnvVariable(key, value)
3047 if (isR2RScenario(scenario)) {
3048 // Crossgen the framework assemblies.
3049 buildCommands += """
3050 @for %%F in (%CORE_ROOT%\\*.dll) do @call :PrecompileAssembly "%CORE_ROOT%" "%%F" %%~nxF
3051 @goto skip_PrecompileAssembly
3054 @REM Skip mscorlib since it is already precompiled.
3055 @if /I "%3" == "mscorlib.dll" exit /b 0
3056 @if /I "%3" == "mscorlib.ni.dll" exit /b 0
3058 "%CORE_ROOT%\\crossgen.exe" /Platform_Assemblies_Paths "%CORE_ROOT%" %2 >nul 2>nul
3059 @if "%errorlevel%" == "-2146230517" (
3060 echo %2 is not a managed assembly.
3061 ) else if "%errorlevel%" == "-2146234344" (
3062 echo %2 is not a managed assembly.
3063 ) else if %errorlevel% neq 0 (
3064 echo Unable to precompile %2
3070 :skip_PrecompileAssembly
3073 // Set RunCrossGen variable to cause test wrappers to invoke their logic to run
3074 // crossgen on tests before running them.
3075 addEnvVariable("RunCrossGen", "true")
3076 } // isR2RScenario(scenario)
3078 // Create the smarty command
3079 def smartyCommand = "C:\\Tools\\Smarty.exe /noecid /noie /workers 9 /inc EXPECTED_PASS "
3080 def addSmartyFlag = { flag -> smartyCommand += flag + " "}
3081 def addExclude = { exclude -> addSmartyFlag("/exc " + exclude)}
3082 def addArchSpecificExclude = { architectureToExclude, exclude -> addExclude(exclude) }
3084 // Exclude tests based on scenario.
3085 Constants.validArmWindowsScenarios[scenario].each { excludeTag ->
3086 addArchSpecificExclude(architecture, excludeTag)
3089 if (isInnerloopTestScenario(scenario)) {
3093 // Exclude any test marked LONG_RUNNING; these often exceed the standard timeout and fail as a result.
3094 // TODO: We should create a "long running" job that runs these with a longer timeout.
3095 addExclude("LONG_RUNNING")
3097 smartyCommand += "/lstFile Tests.lst"
3099 def testListArch = [
3104 def archLocation = testListArch[architecture]
3106 addCommand("copy %WORKSPACE%\\tests\\${archLocation}\\Tests.lst bin\\tests\\${osGroup}.${architecture}.${configuration}")
3107 addCommand("pushd bin\\tests\\${osGroup}.${architecture}.${configuration}")
3108 addCommand("${smartyCommand}")
3110 // Save the errorlevel from the smarty command to be used as the errorlevel of this batch file.
3111 // However, we also need to remove all the variables that were set during this batch file, so we
3112 // can run the ZIP powershell command (below) in a clean environment. (We can't run the powershell
3113 // command with the COMPlus_AltJit variables set, for example.) To do that, we do ENDLOCAL as well
3114 // as save the current errorlevel on the same line. This works because CMD evaluates the %errorlevel%
3115 // variable expansion (or any variable expansion on the line) BEFORE it executes the ENDLOCAL command.
3116 // Note that the ENDLOCAL also undoes the pushd command, but we add the popd here for clarity.
3117 addCommand("popd & ENDLOCAL & set __save_smarty_errorlevel=%errorlevel%")
3119 // ZIP up the smarty output, no matter what the smarty result.
3120 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')\"")
3122 addCommand("echo %errorlevel%")
3123 addCommand("dir .\\bin\\tests\\${osGroup}.${architecture}.${configuration}")
3125 // Use the smarty errorlevel as the script errorlevel.
3126 addCommand("exit /b %__save_smarty_errorlevel%")
3128 batchFile(buildCommands)
3129 } // non-corefx testing
3133 if (!isCoreFxScenario(scenario)) {
3134 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0/*.smrt", '', true, false)
3136 // Archive a ZIP file of the entire Smarty.run.0 directory. This is possibly a little too much,
3137 // but there is no easy way to only archive the HTML/TXT files of the failing tests, so we get
3138 // all the passing test info as well. Not necessarily a bad thing, but possibly somewhat large.
3139 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0.zip", '', true, false)
3145 // Create a test job not covered by the "Windows ARM" case that will be used by a flow job.
3146 // E.g., non-Windows tests.
3147 // Returns the newly created job.
3148 def static CreateOtherTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3150 def lowerConfiguration = configuration.toLowerCase()
3152 def isUbuntuArm64Job = ((os == "Ubuntu16.04") && (architecture == 'arm64'))
3153 def isUbuntuArm32Job = ((os == "Ubuntu") && (architecture == 'arm'))
3154 def isUbuntuArmJob = isUbuntuArm32Job || isUbuntuArm64Job
3156 def doCoreFxTesting = isCoreFxScenario(scenario)
3158 def workspaceRelativeFxRootLinux = "_/fx" // only used for CoreFX testing
3160 def osGroup = getOSGroup(os)
3161 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3164 def useServerGC = false
3166 // Enable Server GC for Ubuntu PR builds
3167 // REVIEW: why? Does this apply to all architectures? Why only PR?
3168 if (os == 'Ubuntu' && isPR) {
3169 testOpts += ' --useServerGC'
3173 if (isR2RScenario(scenario)) {
3175 testOpts += ' --crossgen --runcrossgentests'
3177 if (scenario == 'r2r_jitstress1') {
3178 testOpts += ' --jitstress=1'
3180 else if (scenario == 'r2r_jitstress2') {
3181 testOpts += ' --jitstress=2'
3183 else if (scenario == 'r2r_jitstress1_tiered') {
3184 testOpts += ' --jitstress=1'
3186 else if (scenario == 'r2r_jitstress2_tiered') {
3187 testOpts += ' --jitstress=2'
3189 else if (scenario == 'r2r_jitstressregs1') {
3190 testOpts += ' --jitstressregs=1'
3192 else if (scenario == 'r2r_jitstressregs2') {
3193 testOpts += ' --jitstressregs=2'
3195 else if (scenario == 'r2r_jitstressregs3') {
3196 testOpts += ' --jitstressregs=3'
3198 else if (scenario == 'r2r_jitstressregs4') {
3199 testOpts += ' --jitstressregs=4'
3201 else if (scenario == 'r2r_jitstressregs8') {
3202 testOpts += ' --jitstressregs=8'
3204 else if (scenario == 'r2r_jitstressregs0x10') {
3205 testOpts += ' --jitstressregs=0x10'
3207 else if (scenario == 'r2r_jitstressregs0x80') {
3208 testOpts += ' --jitstressregs=0x80'
3210 else if (scenario == 'r2r_jitstressregs0x1000') {
3211 testOpts += ' --jitstressregs=0x1000'
3213 else if (scenario == 'r2r_jitminopts') {
3214 testOpts += ' --jitminopts'
3216 else if (scenario == 'r2r_jitforcerelocs') {
3217 testOpts += ' --jitforcerelocs'
3219 else if (scenario == 'r2r_gcstress15') {
3220 testOpts += ' --gcstresslevel=0xF'
3223 else if (scenario == 'jitdiff') {
3224 testOpts += ' --jitdisasm --crossgen'
3226 else if (scenario == 'illink') {
3227 testOpts += ' --link=\$WORKSPACE/linker/linker/bin/netcore_Release/netcoreapp2.0/ubuntu-x64/publish/illink'
3229 else if (isLongGc(scenario)) {
3230 // Long GC tests behave very poorly when they are not
3231 // the only test running (many of them allocate until OOM).
3232 testOpts += ' --sequential'
3234 // A note - runtest.sh does have "--long-gc" and "--gcsimulator" options
3235 // for running long GC and GCSimulator tests, respectively. We don't use them
3236 // here because using a playlist file produces much more readable output on the CI machines
3237 // and reduces running time.
3239 // The Long GC playlist contains all of the tests that are
3240 // going to be run. The GCSimulator playlist contains all of
3241 // the GC simulator tests.
3242 if (scenario == 'longgc') {
3243 testOpts += ' --long-gc --playlist=./tests/longRunningGcTests.txt'
3245 else if (scenario == 'gcsimulator') {
3246 testOpts += ' --gcsimulator --playlist=./tests/gcSimulatorTests.txt'
3249 else if (isGcReliabilityFramework(scenario)) {
3250 testOpts += ' --build-overlay-only'
3252 else if (scenario == 'standalone_gc') {
3253 if (osGroup == 'OSX') {
3254 testOpts += ' --gcname=libclrgc.dylib'
3256 else if (osGroup == 'Linux') {
3257 testOpts += ' --gcname=libclrgc.so'
3260 println("Unexpected OS group: ${osGroup} for os ${os}")
3265 // The ARM Ubuntu corefx test job doesn't depend on a Windows test build, and hence inputTestsBuildName
3266 // will be null in this case.
3268 def jobFolder = getJobFolder(scenario)
3269 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3271 if (inputTestsBuildName != null) {
3272 stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR Windows test binaries from')
3274 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3278 // Set up the copies
3280 // Coreclr build containing the tests and mscorlib
3281 // pri1 jobs still need to copy windows_nt built tests
3282 if (inputTestsBuildName != null) {
3283 copyArtifacts(inputTestsBuildName) {
3284 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3286 buildNumber('${CORECLR_WINDOWS_BUILD}')
3291 // Coreclr build we are trying to test
3293 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
3295 // HACK: the Ubuntu arm64 copyArtifacts Jenkins plug-in is ridiculously slow (45 minutes to
3296 // 1.5 hours for this step). Instead, directly use wget, which is fast (1 minute).
3298 if (!isUbuntuArm64Job) {
3299 copyArtifacts(inputCoreCLRBuildName) {
3300 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3302 buildNumber('${CORECLR_BUILD}')
3307 if (isUbuntuArmJob) {
3308 // Add some useful information to the log file. Ignore return codes.
3309 shell("uname -a || true")
3312 if (isUbuntuArm64Job) {
3313 // Copy the required artifacts directly, using wget, e.g.:
3315 // https://ci.dot.net/job/dotnet_coreclr/job/master/job/arm64_cross_checked_ubuntu16.04_innerloop_prtest/16/artifact/testnativebin.checked.zip
3316 // https://ci.dot.net/job/dotnet_coreclr/job/master/job/arm64_cross_checked_ubuntu16.04_innerloop_prtest/16/artifact/tests.checked.zip
3318 // parameterized as:
3320 // https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/job/${inputJobName}/${CORECLR_BUILD}/artifact/testnativebin.checked.zip
3321 // https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/job/${inputJobName}/${CORECLR_BUILD}/artifact/tests.checked.zip
3323 // CoreFX example artifact URLs:
3325 // 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
3326 // 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
3328 // Note that the source might be in a "jitstress" folder.
3330 // Use `--progress=dot:giga` to display some progress output, but limit it in the log file.
3332 // Use `--directory-prefix=_/fx` to specify where to put the corefx files (to match what other platforms do). Use this instead of `-O`.
3334 shell("echo \"Using wget instead of the Jenkins copy artifacts plug-in to copy artifacts from ${inputCoreCLRBuildName}\"")
3336 def mungedProjectName = Utilities.getFolderName(project)
3337 def mungedBranchName = Utilities.getFolderName(branch)
3339 def doCrossGenComparison = isCrossGenComparisonScenario(scenario)
3340 def inputCoreCLRBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3341 if (doCoreFxTesting || doCrossGenComparison) {
3342 // These depend on unique builds for each scenario
3343 inputCoreCLRBuildScenario = scenario
3345 def sourceJobName = getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, false)
3346 def inputJobName = Utilities.getFullJobName(sourceJobName, isPR)
3348 // Need to add the sub-folder if necessary.
3349 def inputJobPath = "job/${inputJobName}"
3350 def folderName = getJobFolder(inputCoreCLRBuildScenario)
3351 if (folderName != '') {
3352 inputJobPath = "job/${folderName}/job/${inputJobName}"
3355 def inputUrlRoot = "https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/${inputJobPath}/\${CORECLR_BUILD}/artifact"
3357 if (doCoreFxTesting) {
3358 shell("mkdir -p ${workspaceRelativeFxRootLinux}")
3359 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/fxtests.zip")
3360 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/fxruntime.zip")
3361 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/run-test.sh")
3362 shell("chmod +x ${workspaceRelativeFxRootLinux}/run-test.sh")
3365 shell("wget --progress=dot:giga ${inputUrlRoot}/testnativebin.${lowerConfiguration}.zip")
3366 shell("wget --progress=dot:giga ${inputUrlRoot}/tests.${lowerConfiguration}.zip")
3370 if (architecture == 'x86') {
3371 shell("mkdir ./bin/CoreFxNative")
3373 def fxBranch = getFxBranch(branch)
3374 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' + Utilities.getFolderName(fxBranch)
3376 copyArtifacts("${corefxFolder}/ubuntu16.04_x86_release") {
3377 includePatterns('bin/build.tar.gz')
3378 targetDirectory('bin/CoreFxNative')
3380 latestSuccessful(true)
3384 shell("mkdir ./bin/CoreFxBinDir")
3385 shell("tar -xf ./bin/CoreFxNative/bin/build.tar.gz -C ./bin/CoreFxBinDir")
3388 // CoreFX testing downloads the CoreFX tests, not the coreclr tests. Also, unzip the built CoreFX layout/runtime directories.
3389 if (doCoreFxTesting) {
3390 shell("unzip -q -o ${workspaceRelativeFxRootLinux}/fxtests.zip || exit 0")
3391 shell("unzip -q -o ${workspaceRelativeFxRootLinux}/fxruntime.zip || exit 0")
3393 else if (architecture != 'arm64') {
3394 // ARM64 copies the tests from the build machine; this is for unzip'ing tests copied from a Windows build.
3396 // Unzip the tests first. Exit with 0
3397 shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/${osGroup}.${architecture}.${configuration} || exit 0")
3398 shell("rm -r ./bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root || exit 0")
3401 // For arm Ubuntu (on hardware), we do the "build-test" step on the build machine, not on the test
3402 // machine. The arm Ubuntu test machines do no building -- they have no CLI, for example.
3403 // We should probably do the "generatelayoutonly" step on the build machine for all architectures.
3404 // However, it's believed that perhaps there's an issue with executable permission bits not getting
3405 // copied correctly.
3406 if (!doCoreFxTesting) {
3407 if (isUbuntuArmJob) {
3408 if (architecture == 'arm') {
3409 shell("unzip -q -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root
3410 shell("unzip -q -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3413 assert architecture == 'arm64'
3414 shell("unzip -q -o ./tests.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}
3416 // We still the testnativebin files until they get placed properly in the tests directory (next to their respective tests).
3417 shell("unzip -q -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3421 shell("./build-test.sh ${architecture} ${configuration} generatelayoutonly")
3425 // Execute the tests
3426 def runDocker = isNeedDocker(architecture, os, false)
3427 def dockerPrefix = ""
3430 def dockerImage = getDockerImageName(architecture, os, false)
3431 dockerPrefix = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} "
3432 dockerCmd = dockerPrefix + "${dockerImage} "
3435 // If we are running a stress mode, we'll set those variables first.
3436 // For CoreFX, the stress variables are already built into the CoreFX test build per-test wrappers.
3437 if (!doCoreFxTesting && isJitStressScenario(scenario)) {
3438 def scriptFileName = "\${WORKSPACE}/set_stress_test_env.sh"
3439 def envScriptCmds = envScriptCreate(os, scriptFileName)
3440 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
3441 envScriptCmds += envScriptFinalize(os, scriptFileName)
3442 shell("${envScriptCmds}")
3443 testOpts += " --test-env=${scriptFileName}"
3446 // setup-stress-dependencies.sh, invoked by runtest.sh to download the coredistools package, depends on the "dotnet"
3447 // tool downloaded by the "init-tools.sh" script. However, it only invokes setup-stress-dependencies.sh for x64. The
3448 // coredistools package is used by GCStress on x86 and x64 to disassemble code to determine instruction boundaries.
3449 // On arm/arm64, it is not required as determining instruction boundaries is trivial.
3450 if (isGCStressRelatedTesting(scenario)) {
3451 if (architecture == 'x64') {
3452 shell('./init-tools.sh')
3456 if (doCoreFxTesting) {
3458 \${WORKSPACE}/${workspaceRelativeFxRootLinux}/run-test.sh --sequential --test-exclude-file \${WORKSPACE}/tests/${architecture}/corefx_linux_test_exclusions.txt --runtime \${WORKSPACE}/${workspaceRelativeFxRootLinux}/bin/testhost/netcoreapp-Linux-Release-${architecture} --arch ${architecture} --corefx-tests \${WORKSPACE}/${workspaceRelativeFxRootLinux}/bin --configurationGroup Release""")
3461 def runScript = "${dockerCmd}./tests/runtest.sh"
3463 // TODO: the testNativeBinDir shouldn't be necessary if the native test binaries are placed properly with their corresponding managed test code.
3467 --testRootDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}\" \\
3468 --coreOverlayDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root\" \\
3469 --testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
3470 --copyNativeTestBin --limitedDumpGeneration ${testOpts}""")
3473 if (isGcReliabilityFramework(scenario)) {
3474 // runtest.sh doesn't actually execute the reliability framework - do it here.
3477 dockerCmd = dockerPrefix + "-e COMPlus_gcServer=1 ${dockerImage} "
3480 shell("export COMPlus_gcServer=1")
3484 shell("${dockerCmd}./tests/scripts/run-gc-reliability-framework.sh ${architecture} ${configuration}")
3489 // Experimental: If on Ubuntu 14.04, then attempt to pull in crash dump links
3490 if (os in ['Ubuntu']) {
3491 SummaryBuilder summaries = new SummaryBuilder()
3492 summaries.addLinksSummaryFromFile('Crash dumps from this run:', 'dumplings.txt')
3493 summaries.emit(newJob)
3496 if (doCoreFxTesting) {
3497 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3498 if ((os == "Ubuntu") && (architecture == 'arm')) {
3499 // We have a problem with the xunit plug-in, where it is consistently failing on Ubuntu arm32 test result uploading with this error:
3501 // [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
3503 // We haven't been able to identify the reason. So, do not add xunit parsing of the test data in this scenario.
3504 // This is tracked by: https://github.com/dotnet/coreclr/issues/19447.
3507 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3511 Utilities.addXUnitDotNETResults(newJob, '**/coreclrtests.xml')
3517 def static CreateNonWindowsCrossGenComparisonTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
3519 assert isCrossGenComparisonScenario(scenario)
3521 def osGroup = getOSGroup(os)
3522 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3524 def workspaceRelativeResultsDir = "_"
3525 def workspaceRelativeNativeArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${architecture}_${architecture}.${configuration}"
3527 def jobFolder = getJobFolder(scenario)
3528 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3530 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3533 def workspaceRelativeArtifactsArchive = "${os}.${architecture}.${configuration}.${scenario}.zip"
3536 copyArtifacts(inputCoreCLRBuildName) {
3537 includePatterns("${workspaceRelativeArtifactsArchive}")
3539 buildNumber('${CORECLR_BUILD}')
3543 shell("unzip -o ${workspaceRelativeArtifactsArchive} || exit 0")
3545 def workspaceRelativeCoreLib = "bin/Product/${osGroup}.${architecture}.${configuration}/IL/System.Private.CoreLib.dll"
3546 def workspaceRelativeCoreRootDir = "bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root"
3547 def workspaceRelativeCrossGenComparisonScript = "tests/scripts/crossgen_comparison.py"
3548 def workspaceRelativeCrossGenExecutable = "${workspaceRelativeCoreRootDir}/crossgen"
3550 def crossGenComparisonCmd = "python -u \${WORKSPACE}/${workspaceRelativeCrossGenComparisonScript} "
3551 def crossGenExecutable = "\${WORKSPACE}/${workspaceRelativeCrossGenExecutable}"
3553 shell("mkdir -p ${workspaceRelativeNativeArchResultDir}")
3554 shell("${crossGenComparisonCmd}crossgen_corelib --crossgen ${crossGenExecutable} --il_corelib \${WORKSPACE}/${workspaceRelativeCoreLib} --result_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir}")
3555 shell("${crossGenComparisonCmd}crossgen_framework --crossgen ${crossGenExecutable} --core_root \${WORKSPACE}/${workspaceRelativeCoreRootDir} --result_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir}")
3557 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
3558 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
3559 shell("${crossGenComparisonCmd}compare --base_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir} --diff_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}")
3564 Utilities.addArchival(newJob, "${workspaceRelativeNativeArchResultDir}/**")
3565 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
3566 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
3567 Utilities.addArchival(newJob, "${workspaceRelativeCrossArchResultDir}/**")
3573 // Create a test job that will be used by a flow job.
3574 // Returns the newly created job.
3575 // 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,
3576 // and we want the views to be the minimal set of "top-level" jobs that represent all work.
3577 def static CreateTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3579 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3582 if (windowsArmJob) {
3583 assert inputTestsBuildName == null
3584 newJob = CreateWindowsArmTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3586 else if (isCrossGenComparisonScenario(scenario)) {
3587 assert inputTestsBuildName == null
3588 newJob = CreateNonWindowsCrossGenComparisonTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3591 newJob = CreateOtherTestJob(dslFactory, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3594 setJobMachineAffinity(architecture, os, false, true, false, newJob) // isBuildJob = false, isTestJob = true, isFlowJob = false
3596 if (scenario == 'jitdiff') {
3597 def osGroup = getOSGroup(os)
3598 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/dasm/**")
3601 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
3602 setJobTimeout(newJob, isPR, architecture, configuration, scenario, false)
3607 // Create a flow job to tie together a build job with the given test job.
3608 // The 'inputTestsBuildName' argument might be null if the flow job doesn't depend on a Windows build job.
3609 // Returns the new flow job.
3610 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)
3612 // Windows CoreCLR build and Linux CoreCLR build (in parallel) ->
3613 // Linux CoreCLR test
3614 def flowJobName = getJobName(configuration, architecture, os, scenario, false) + "_flow"
3615 def jobFolder = getJobFolder(scenario)
3617 def newFlowJob = null
3619 if (inputTestsBuildName == null) {
3620 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3622 coreclrBuildJob = build(params, '${inputCoreCLRBuildName}')
3624 // And then build the test build
3625 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number], '${fullTestJobName}')
3628 JobReport.Report.addReference(inputCoreCLRBuildName)
3629 JobReport.Report.addReference(fullTestJobName)
3632 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3634 // Build the input jobs in parallel
3636 { coreclrBuildJob = build(params, '${inputCoreCLRBuildName}') },
3637 { windowsBuildJob = build(params, '${inputTestsBuildName}') }
3640 // And then build the test build
3641 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number,
3642 CORECLR_WINDOWS_BUILD: windowsBuildJob.build.number], '${fullTestJobName}')
3645 JobReport.Report.addReference(inputCoreCLRBuildName)
3646 JobReport.Report.addReference(inputTestsBuildName)
3647 JobReport.Report.addReference(fullTestJobName)
3650 addToViews(newFlowJob, true, isPR, architecture, os, configuration, scenario) // isFlowJob = true
3652 setJobMachineAffinity(architecture, os, false, false, true, newFlowJob) // isBuildJob = false, isTestJob = false, isFlowJob = true
3654 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
3655 addTriggers(newFlowJob, branch, isPR, architecture, os, configuration, scenario, true, false) // isFlowJob==true, isWindowsBuildOnlyJob==false
3660 // Determine if we should generate a flow job for the given parameters.
3661 // Returns true if the job should be generated.
3662 def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def configuration, def os)
3664 // The various "innerloop" jobs are only available as PR triggered.
3667 if (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked')) {
3668 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
3669 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
3673 if (isInnerloopTestScenario(scenario)) {
3677 if (scenario == 'corefx_innerloop') {
3682 // Filter based on OS and architecture.
3684 switch (architecture) {
3686 if (os != "Ubuntu" && os != "Windows_NT") {
3691 if (os != "Ubuntu16.04" && os != "Windows_NT") {
3696 if (os != "Ubuntu") {
3701 if (!(os in Constants.crossList)) {
3704 if (os == "Windows_NT") {
3709 case 'x86_arm_altjit':
3710 case 'x64_arm64_altjit':
3714 println("Unknown architecture: ${architecture}")
3719 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
3721 // Filter based on scenario in OS.
3723 if (os == 'Windows_NT') {
3724 assert architecture == 'arm' || architecture == 'arm64'
3725 if (!isArmWindowsScenario(scenario)) {
3728 if (isNormalOrInnerloop && (configuration == 'Debug')) {
3729 // The arm32/arm64 Debug configuration for innerloop/normal scenario is a special case: it does a build only, and no test run.
3730 // To do that, it doesn't require a flow job.
3736 if (architecture == 'arm') {
3737 if (!(scenario in Constants.validLinuxArmScenarios)) {
3741 else if (architecture == 'arm64') {
3742 if (!(scenario in Constants.validLinuxArm64Scenarios)) {
3746 else if (architecture == 'x86') {
3747 // Linux/x86 only want innerloop and default test
3748 if (!isNormalOrInnerloop) {
3752 else if (architecture == 'x64') {
3753 // Linux/x64 corefx testing doesn't need a flow job; the "build" job runs run-corefx-tests.py which
3754 // builds and runs the corefx tests. Other Linux/x64 flow jobs are required to get the test
3755 // build from a Windows machine.
3756 if (isCoreFxScenario(scenario)) {
3762 // For CentOS, we only want Checked/Release builds.
3763 if (os == 'CentOS7.1') {
3764 if (configuration != 'Checked' && configuration != 'Release') {
3767 if (!isNormalOrInnerloop && !isR2RScenario(scenario)) {
3772 // For RedHat and Debian, we only do Release builds.
3773 else if (os == 'RHEL7.2' || os == 'Debian8.4') {
3774 if (configuration != 'Release') {
3777 if (!isNormalOrInnerloop) {
3782 // Next, filter based on scenario.
3784 if (isJitStressScenario(scenario)) {
3785 if (configuration != 'Checked') {
3789 else if (isR2RBaselineScenario(scenario)) {
3790 if (configuration != 'Checked' && configuration != 'Release') {
3794 else if (isR2RStressScenario(scenario)) {
3795 if (configuration != 'Checked') {
3799 else if (isCrossGenComparisonScenario(scenario)) {
3800 return shouldGenerateCrossGenComparisonJob(os, architecture, configuration, scenario)
3808 // Long GC tests take a long time on non-Release builds
3809 // ilrt is also Release only
3810 if (configuration != 'Release') {
3816 if (configuration != 'Checked') {
3821 case 'gc_reliability_framework':
3822 case 'standalone_gc':
3823 if (configuration != 'Release' && configuration != 'Checked') {
3832 if (os != 'Windows_NT' && os != 'Ubuntu') {
3842 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, false)) {
3847 case 'corefx_innerloop':
3848 // No flow job needed
3852 println("Unknown scenario: ${scenario}")
3858 // The job was not filtered out, so we should generate it!
3862 // Create jobs requiring flow jobs. This includes x64 non-Windows, arm/arm64 Ubuntu, and arm/arm64 Windows.
3863 Constants.allScenarios.each { scenario ->
3864 [true, false].each { isPR ->
3865 Constants.architectureList.each { architecture ->
3866 Constants.configurationList.each { configuration ->
3867 Constants.osList.each { os ->
3869 if (!shouldGenerateFlowJob(scenario, isPR, architecture, configuration, os)) {
3873 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3874 def doCoreFxTesting = isCoreFxScenario(scenario)
3875 def doCrossGenComparison = isCrossGenComparisonScenario(scenario)
3877 // Figure out the job name of the CoreCLR build the test will depend on.
3879 def inputCoreCLRBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3880 def inputCoreCLRBuildIsBuildOnly = false
3881 if (doCoreFxTesting) {
3882 // Every CoreFx test depends on its own unique build.
3883 inputCoreCLRBuildScenario = scenario
3884 if (windowsArmJob) {
3885 // Only Windows ARM corefx jobs use "build only" jobs. Others, such as Ubuntu ARM corefx, use "regular" jobs.
3886 inputCoreCLRBuildIsBuildOnly = true
3889 if (doCrossGenComparison) {
3890 inputCoreCLRBuildScenario = scenario
3893 def inputCoreCLRFolderName = getJobFolder(inputCoreCLRBuildScenario)
3894 def inputCoreCLRBuildName = projectFolder + '/' +
3895 Utilities.getFullJobName(project, getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, inputCoreCLRBuildIsBuildOnly), isPR, inputCoreCLRFolderName)
3897 // Figure out the name of the build job that the test job will depend on.
3898 // For Windows ARM tests, this is not used, as the CoreCLR build creates the tests. For other
3899 // tests (e.g., Linux ARM), we depend on a Windows build to get the tests.
3900 // For CoreFX tests, however, Linux doesn't need the Windows build for the tests, since the
3901 // CoreFX build creates the tests.
3903 def inputTestsBuildName = null
3905 // Ubuntu Arm64 jobs do the test build on the build machine, and thus don't depend on a Windows build.
3906 def isUbuntuArm64Job = ((os == "Ubuntu16.04") && (architecture == 'arm64'))
3908 if (!windowsArmJob && !doCoreFxTesting & !doCrossGenComparison && !isUbuntuArm64Job) {
3909 def testBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3911 def inputTestsBuildArch = architecture
3912 if (architecture == "arm") {
3913 // Use the x86 test build for arm unix
3914 inputTestsBuildArch = "x86"
3917 def inputTestsBuildIsBuildOnly = true
3919 inputTestsBuildName = projectFolder + '/' +
3920 Utilities.getFullJobName(project, getJobName(configuration, inputTestsBuildArch, 'windows_nt', testBuildScenario, inputTestsBuildIsBuildOnly), isPR)
3923 // =============================================================================================
3924 // Create the test job
3925 // =============================================================================================
3927 def testJob = CreateTestJob(this, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3929 // =============================================================================================
3930 // Create a build flow to join together the build and tests required to run this test.
3931 // =============================================================================================
3933 if (os == 'RHEL7.2' || os == 'Debian8.4') {
3934 // Do not create the flow job for RHEL jobs.
3938 def fullTestJobName = projectFolder + '/' + testJob.name
3939 def flowJob = CreateFlowJob(this, project, branch, architecture, os, configuration, scenario, isPR, fullTestJobName, inputCoreCLRBuildName, inputTestsBuildName)
3947 JobReport.Report.generateJobReport(out)
3949 // Make the call to generate the help job
3950 Utilities.createHelperJob(this, project, branch,
3951 "Welcome to the ${project} Repository", // This is prepended to the help message
3952 "Have a nice day!") // This is appended to the help message. You might put known issues here.
3954 Utilities.addCROSSCheck(this, project, branch)