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 ARM64 hardware (used for ARM/ARM64 testing). So only allow certain branches to use it.
51 def static LimitedHardwareBranches = [
54 // Innerloop build OS's
55 // The Windows_NT_BuildOnly OS is a way to speed up the Non-Windows builds by avoiding
56 // test execution in the build flow runs. It generates the exact same build
57 // as Windows_NT but without running the tests.
63 'Windows_NT_BuildOnly',
71 def static crossList = [
79 // This is a set of JIT stress modes combined with the set of variables that
80 // need to be set to actually enable that stress mode. The key of the map is the stress mode and
81 // the values are the environment variables
82 def static jitStressModeScenarios = [
83 'minopts' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JITMinOpts' : '1'],
84 'tieredcompilation' : ['COMPlus_TieredCompilation' : '1'], // this can be removed once tiered compilation is on by default
85 'no_tiered_compilation' : ['COMPlus_TieredCompilation' : '0'],
86 'no_tiered_compilation_innerloop': ['COMPlus_TieredCompilation' : '0'],
87 'forcerelocs' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_ForceRelocs' : '1'],
88 'jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '1'],
89 'jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2'],
90 'jitstress1_tiered' : ['COMPlus_TieredCompilation' : '1', 'COMPlus_JitStress' : '1'],
91 'jitstress2_tiered' : ['COMPlus_TieredCompilation' : '1', 'COMPlus_JitStress' : '2'],
92 'jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '1'],
93 'jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '2'],
94 'jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '3'],
95 'jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '4'],
96 'jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '8'],
97 'jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x10'],
98 'jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x80'],
99 'jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x1000'],
100 'jitstress2_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '1'],
101 'jitstress2_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '2'],
102 'jitstress2_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '3'],
103 'jitstress2_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '4'],
104 'jitstress2_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '8'],
105 'jitstress2_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x10'],
106 'jitstress2_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x80'],
107 'jitstress2_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x1000'],
108 'tailcallstress' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_TailcallStress' : '1'],
109 'jitsse2only' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableAVX' : '0', 'COMPlus_EnableSSE3_4' : '0'],
110 'jitnosimd' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_FeatureSIMD' : '0'],
111 'jitincompletehwintrinsic' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1'],
112 'jitx86hwintrinsicnoavx' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX' : '0'], // testing the legacy SSE encoding
113 'jitx86hwintrinsicnoavx2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_EnableAVX2' : '0'], // testing SNB/IVB
114 'jitx86hwintrinsicnosimd' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_EnableIncompleteISAClass' : '1', 'COMPlus_FeatureSIMD' : '0'], // match "jitnosimd", may need to remove after decoupling HW intrinsic from FeatureSIMD
115 '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'],
116 'corefx_baseline' : ['COMPlus_TieredCompilation' : '0'], // corefx baseline
117 'corefx_minopts' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JITMinOpts' : '1'],
118 'corefx_tieredcompilation' : ['COMPlus_TieredCompilation' : '1'], // this can be removed once tiered compilation is on by default
119 'corefx_jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '1'],
120 'corefx_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStress' : '2'],
121 'corefx_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '1'],
122 'corefx_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '2'],
123 'corefx_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '3'],
124 'corefx_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '4'],
125 'corefx_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '8'],
126 'corefx_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x10'],
127 'corefx_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x80'],
128 'corefx_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_JitStressRegs' : '0x1000'],
129 'gcstress0x3' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0x3'],
130 'gcstress0xc' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC'],
131 'zapdisable' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
132 'heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_HeapVerify' : '1'],
133 'gcstress0xc_zapdisable' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0'],
134 'gcstress0xc_zapdisable_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_JitStress' : '2'],
135 'gcstress0xc_zapdisable_heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_ReadyToRun' : '0', 'COMPlus_HeapVerify' : '1'],
136 'gcstress0xc_jitstress1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '1'],
137 'gcstress0xc_jitstress2' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '2'],
138 'gcstress0xc_minopts_heapverify1' : ['COMPlus_TieredCompilation' : '0', 'COMPlus_GCStress' : '0xC', 'COMPlus_JITMinOpts' : '1', 'COMPlus_HeapVerify' : '1']
141 // This is a set of ReadyToRun stress scenarios
142 def static r2rStressScenarios = [
143 'r2r_jitstress1' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStress": "1"],
144 'r2r_jitstress2' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStress": "2"],
145 'r2r_jitstress1_tiered' : ['COMPlus_TieredCompilation' : '1', "COMPlus_JitStress": "1"],
146 'r2r_jitstress2_tiered' : ['COMPlus_TieredCompilation' : '1', "COMPlus_JitStress": "2"],
147 'r2r_jitstressregs1' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "1"],
148 'r2r_jitstressregs2' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "2"],
149 'r2r_jitstressregs3' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "3"],
150 'r2r_jitstressregs4' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "4"],
151 'r2r_jitstressregs8' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "8"],
152 'r2r_jitstressregs0x10' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x10"],
153 'r2r_jitstressregs0x80' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x80"],
154 'r2r_jitstressregs0x1000' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JitStressRegs": "0x1000"],
155 'r2r_jitminopts' : ['COMPlus_TieredCompilation' : '0', "COMPlus_JITMinOpts": "1"],
156 'r2r_jitforcerelocs' : ['COMPlus_TieredCompilation' : '0', "COMPlus_ForceRelocs": "1"],
157 'r2r_gcstress15' : ['COMPlus_TieredCompilation' : '0', "COMPlus_GCStress": "0xF"],
158 'r2r_no_tiered_compilation' : ['COMPlus_TieredCompilation' : '0'],
161 // This is the basic set of scenarios
162 def static basicScenarios = [
170 // 'jitdiff', // jitdiff is currently disabled, until someone spends the effort to make it fully work
172 'gc_reliability_framework',
175 'crossgen_comparison']
177 def static allScenarios = basicScenarios + r2rStressScenarios.keySet() + jitStressModeScenarios.keySet()
179 // Valid PR trigger combinations.
180 def static prTriggeredValidInnerLoopCombos = [
198 'Windows_NT_BuildOnly': [
242 // A set of scenarios that are valid for arm/arm64 tests run on hardware. This is a map from valid scenario name
243 // to Tests.lst file categories to exclude.
245 // This list should contain a subset of the scenarios from `allScenarios`. Please keep this in the same order as that,
246 // and with the same values, with some commented out, for easier maintenance.
248 // Note that some scenarios that are commented out should be enabled, but haven't yet been.
250 def static validArmWindowsScenarios = [
254 'r2r': ["R2R_FAIL", "R2R_EXCLUDE"],
260 // 'gc_reliability_framework'
262 // 'corefx_innerloop'
263 // 'crossgen_comparison'
264 'r2r_jitstress1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
265 'r2r_jitstress2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
266 'r2r_jitstress1_tiered': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
267 'r2r_jitstress2_tiered': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
268 'r2r_jitstressregs1': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
269 'r2r_jitstressregs2': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
270 'r2r_jitstressregs3': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
271 'r2r_jitstressregs4': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
272 'r2r_jitstressregs8': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
273 'r2r_jitstressregs0x10': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
274 'r2r_jitstressregs0x80': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
275 'r2r_jitstressregs0x1000': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
276 'r2r_jitminopts': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
277 'r2r_jitforcerelocs': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
278 'r2r_gcstress15': ["R2R_FAIL", "R2R_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE", "GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
279 'r2r_no_tiered_compilation': ["R2R_FAIL", "R2R_EXCLUDE"],
280 'minopts': ["MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
281 'tieredcompilation': [],
282 'no_tiered_compilation': [],
283 'no_tiered_compilation_innerloop': [],
285 'jitstress1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
286 'jitstress2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
287 'jitstress1_tiered': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
288 'jitstress2_tiered': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
289 'jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
290 'jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
291 'jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
292 'jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
293 'jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
294 'jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
295 'jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
296 'jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
297 'jitstress2_jitstressregs1': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
298 'jitstress2_jitstressregs2': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
299 'jitstress2_jitstressregs3': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
300 'jitstress2_jitstressregs4': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
301 'jitstress2_jitstressregs8': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
302 'jitstress2_jitstressregs0x10': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
303 'jitstress2_jitstressregs0x80': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
304 'jitstress2_jitstressregs0x1000': ["JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
305 'tailcallstress': ["TAILCALLSTRESS_FAIL", "TAILCALLSTRESS_EXCLUDE"],
306 // 'jitsse2only' // Only relevant to xarch
307 'jitnosimd': [], // Only interesting on platforms where SIMD support exists.
308 // 'jitincompletehwintrinsic'
309 // 'jitx86hwintrinsicnoavx'
310 // 'jitx86hwintrinsicnoavx2'
311 // 'jitx86hwintrinsicnosimd'
312 // 'jitnox86hwintrinsic'
313 'corefx_baseline': [], // corefx tests don't use smarty
314 'corefx_minopts': [], // corefx tests don't use smarty
315 'corefx_tieredcompilation': [], // corefx tests don't use smarty
316 'corefx_jitstress1': [], // corefx tests don't use smarty
317 'corefx_jitstress2': [], // corefx tests don't use smarty
318 'corefx_jitstressregs1': [], // corefx tests don't use smarty
319 'corefx_jitstressregs2': [], // corefx tests don't use smarty
320 'corefx_jitstressregs3': [], // corefx tests don't use smarty
321 'corefx_jitstressregs4': [], // corefx tests don't use smarty
322 'corefx_jitstressregs8': [], // corefx tests don't use smarty
323 'corefx_jitstressregs0x10': [], // corefx tests don't use smarty
324 'corefx_jitstressregs0x80': [], // corefx tests don't use smarty
325 'corefx_jitstressregs0x1000': [], // corefx tests don't use smarty
326 'gcstress0x3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
327 'gcstress0xc': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE"],
328 'zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
330 'gcstress0xc_zapdisable': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
331 'gcstress0xc_zapdisable_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
332 'gcstress0xc_zapdisable_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE"],
333 'gcstress0xc_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
334 'gcstress0xc_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
335 'gcstress0xc_minopts_heapverify1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
338 // NOTE: the following scenarios are not defined in the 'allScenarios' list! Is this a bug?
341 'minopts_zapdisable': ["ZAPDISABLE_FAIL", "ZAPDISABLE_EXCLUDE", "MINOPTS_FAIL", "MINOPTS_EXCLUDE"],
342 'gcstress0x3_jitstress1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
343 'gcstress0x3_jitstress2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
344 'gcstress0x3_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
345 'gcstress0x3_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
346 'gcstress0x3_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
347 'gcstress0x3_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
348 'gcstress0x3_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
349 'gcstress0x3_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
350 'gcstress0x3_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
351 'gcstress0x3_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
352 'gcstress0xc_jitstressregs1': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
353 'gcstress0xc_jitstressregs2': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
354 'gcstress0xc_jitstressregs3': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
355 'gcstress0xc_jitstressregs4': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
356 'gcstress0xc_jitstressregs8': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
357 'gcstress0xc_jitstressregs0x10': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
358 'gcstress0xc_jitstressregs0x80': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"],
359 'gcstress0xc_jitstressregs0x1000': ["GCSTRESS_FAIL", "GCSTRESS_EXCLUDE", "JITSTRESS_FAIL", "JITSTRESS_EXCLUDE"]
362 def static validLinuxArmScenarios = [
372 // 'gc_reliability_framework'
374 // 'corefx_innerloop'
375 'crossgen_comparison',
378 'r2r_jitstress1_tiered',
379 'r2r_jitstress2_tiered',
380 'r2r_jitstressregs1',
381 'r2r_jitstressregs2',
382 'r2r_jitstressregs3',
383 'r2r_jitstressregs4',
384 'r2r_jitstressregs8',
385 'r2r_jitstressregs0x10',
386 'r2r_jitstressregs0x80',
387 'r2r_jitstressregs0x1000',
389 'r2r_jitforcerelocs',
391 'r2r_no_tiered_compilation',
394 'no_tiered_compilation',
395 'no_tiered_compilation_innerloop',
408 'jitstressregs0x1000',
409 'jitstress2_jitstressregs1',
410 'jitstress2_jitstressregs2',
411 'jitstress2_jitstressregs3',
412 'jitstress2_jitstressregs4',
413 'jitstress2_jitstressregs8',
414 'jitstress2_jitstressregs0x10',
415 'jitstress2_jitstressregs0x80',
416 'jitstress2_jitstressregs0x1000',
418 // 'jitsse2only' // Only relevant to xarch
419 // 'jitnosimd' // Only interesting on platforms where SIMD support exists.
420 // 'jitincompletehwintrinsic'
421 // 'jitx86hwintrinsicnoavx'
422 // 'jitx86hwintrinsicnoavx2'
423 // 'jitx86hwintrinsicnosimd'
424 // 'jitnox86hwintrinsic'
427 'corefx_tieredcompilation',
430 'corefx_jitstressregs1',
431 'corefx_jitstressregs2',
432 'corefx_jitstressregs3',
433 'corefx_jitstressregs4',
434 'corefx_jitstressregs8',
435 'corefx_jitstressregs0x10',
436 'corefx_jitstressregs0x80',
437 'corefx_jitstressregs0x1000',
442 'gcstress0xc_zapdisable',
443 'gcstress0xc_zapdisable_jitstress2',
444 'gcstress0xc_zapdisable_heapverify1',
445 'gcstress0xc_jitstress1',
446 'gcstress0xc_jitstress2',
447 'gcstress0xc_minopts_heapverify1'
450 def static validLinuxArm64Scenarios = [
460 // 'gc_reliability_framework'
462 // 'corefx_innerloop'
463 // 'crossgen_comparison'
466 'r2r_jitstress1_tiered',
467 'r2r_jitstress2_tiered',
468 'r2r_jitstressregs1',
469 'r2r_jitstressregs2',
470 'r2r_jitstressregs3',
471 'r2r_jitstressregs4',
472 'r2r_jitstressregs8',
473 'r2r_jitstressregs0x10',
474 'r2r_jitstressregs0x80',
475 'r2r_jitstressregs0x1000',
477 'r2r_jitforcerelocs',
479 'r2r_no_tiered_compilation',
482 'no_tiered_compilation',
483 'no_tiered_compilation_innerloop',
496 'jitstressregs0x1000',
497 'jitstress2_jitstressregs1',
498 'jitstress2_jitstressregs2',
499 'jitstress2_jitstressregs3',
500 'jitstress2_jitstressregs4',
501 'jitstress2_jitstressregs8',
502 'jitstress2_jitstressregs0x10',
503 'jitstress2_jitstressregs0x80',
504 'jitstress2_jitstressregs0x1000',
506 // 'jitsse2only' // Only relevant to xarch
507 'jitnosimd', // Only interesting on platforms where SIMD support exists.
508 // 'jitincompletehwintrinsic'
509 // 'jitx86hwintrinsicnoavx'
510 // 'jitx86hwintrinsicnoavx2'
511 // 'jitx86hwintrinsicnosimd'
512 // 'jitnox86hwintrinsic'
515 'corefx_tieredcompilation',
518 'corefx_jitstressregs1',
519 'corefx_jitstressregs2',
520 'corefx_jitstressregs3',
521 'corefx_jitstressregs4',
522 'corefx_jitstressregs8',
523 'corefx_jitstressregs0x10',
524 'corefx_jitstressregs0x80',
525 'corefx_jitstressregs0x1000',
530 'gcstress0xc_zapdisable',
531 'gcstress0xc_zapdisable_jitstress2',
532 'gcstress0xc_zapdisable_heapverify1',
533 'gcstress0xc_jitstress1',
534 'gcstress0xc_jitstress2',
535 'gcstress0xc_minopts_heapverify1'
538 def static configurationList = ['Debug', 'Checked', 'Release']
540 // This is the set of architectures
541 // Some of these are pseudo-architectures:
542 // armem -- ARM builds/runs using an emulator. Used for Tizen runs.
543 // x86_arm_altjit -- ARM runs on x86 using the ARM altjit
544 // x64_arm64_altjit -- ARM64 runs on x64 using the ARM64 altjit
545 def static architectureList = ['arm', 'armem', 'x86_arm_altjit', 'x64_arm64_altjit', 'arm64', 'x64', 'x86']
547 // This set of architectures that cross build on Windows and run on Windows ARM64 hardware.
548 def static armWindowsCrossArchitectureList = ['arm', 'arm64']
551 // **************************************************************
552 // Create some specific views
554 // These aren't using the Utilities.addStandardFolderView() function, because that creates
555 // views based on a single regular expression. These views will be generated by adding a
556 // specific set of jobs to them.
558 // Utilities.addStandardFolderView() also creates a lot of additional stuff around the
559 // view, like "Build Statistics", "Job Statistics", "Unstable Jobs". Until it is determined
560 // those are required, don't add them (which simplifies the view pages, as well).
561 // **************************************************************
564 def static MergeJobView = null
565 def static PeriodicJobView = null
566 def static ArchitectureViews = [:]
567 def static OSViews = [:]
570 // MergeJobView: include all jobs that execute when a PR change is merged.
571 Views.MergeJobView = listView('Merge') {
584 // PeriodicJobView: include all jobs that execute on a schedule
585 Views.PeriodicJobView = listView('Periodic') {
598 // Create a view for non-PR jobs for each architecture.
599 Constants.architectureList.each { architecture ->
600 Views.ArchitectureViews[architecture] = listView(architecture) {
614 // Create a view for non-PR jobs for each OS.
615 Constants.osList.each { os ->
616 // Don't create one for the special 'Windows_NT_BuildOnly'
617 if (os == 'Windows_NT_BuildOnly') {
620 Views.OSViews[os] = listView(os) {
634 def static addToMergeView(def job) {
635 Views.MergeJobView.with {
642 def static addToPeriodicView(def job) {
643 Views.PeriodicJobView.with {
650 def static addToViews(def job, def isPR, def architecture, def os) {
652 // No views want PR jobs currently.
656 // Add to architecture view.
657 Views.ArchitectureViews[architecture].with {
664 Views.OSViews[os].with {
671 def static addPeriodicTriggerHelper(def job, String cronString, boolean alwaysRuns = false) {
672 addToPeriodicView(job)
673 Utilities.addPeriodicTrigger(job, cronString, alwaysRuns)
676 def static addGithubPushTriggerHelper(def job) {
678 Utilities.addGithubPushTrigger(job)
682 def static setMachineAffinity(def job, def os, def architecture, def options = null) {
683 assert os instanceof String
684 assert architecture instanceof String
686 def armArches = ['arm', 'armem', 'arm64']
688 if (!(architecture in armArches)) {
689 assert options == null
690 Utilities.setMachineAffinity(job, os, 'latest-or-auto')
695 // This is an arm(64) job.
697 // There are several options.
701 // Arm32 (Build) -> latest-arm64
702 // |-> os == "Windows_NT" && (architecture == "arm") && options['use_arm64_build_machine'] == true
703 // Arm32 (Test) -> arm64-windows_nt
704 // |-> os == "Windows_NT" && (architecture == "arm") && options['use_arm64_build_machine'] == false
706 // Arm64 (Build) -> latest-arm64
707 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == true
708 // Arm64 (Test) -> arm64-windows_nt
709 // |-> os == "Windows_NT" && architecture == "arm64" && options['use_arm64_build_machine'] == false
713 // Arm32 emulator (Build, Test) -> arm-cross-latest
714 // |-> os == "Tizen" && (architecture == "armem")
716 // Arm32 hardware (Flow) -> Ubuntu 16.04 latest-or-auto (don't use limited arm hardware)
717 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_flow_job'] == true
718 // Arm32 hardware (Build) -> Ubuntu 16.04 latest-or-auto
719 // |-> os == "Ubuntu" && (architecture == "arm") && options['is_build_job'] == true
720 // Arm32 hardware (Test) -> Helix ubuntu.1404.arm32.open queue
721 // |-> os == "Ubuntu" && (architecture == "arm")
723 // Arm64 (Build) -> arm64-cross-latest
724 // |-> os != "Windows_NT" && architecture == "arm64" && options['is_build_job'] == true
725 // Arm64 (Test) -> Helix Ubuntu.1604.Arm64.Open queue
726 // |-> os != "Windows_NT" && architecture == "arm64"
728 // Note: we are no longer using Jenkins tags "arm64-huge-page-size", "arm64-small-page-size".
729 // Support for Linux arm64 large page size has been removed for now, as it wasn't being used.
731 // Note: we are no longer using Jenkins tag 'latest-arm64' for arm/arm64 Windows build machines. Instead,
732 // we are using public VS2017 arm/arm64 tools in a VM from Helix.
734 // This has to be a arm arch
735 assert architecture in armArches
736 if (os == "Windows_NT") {
737 // arm32/arm64 Windows jobs share the same machines for now
738 def isBuild = options['use_arm64_build_machine'] == true
740 if (isBuild == true) {
742 label('Windows.10.Amd64.ClientRS4.DevEx.Open')
745 Utilities.setMachineAffinity(job, os, 'arm64-windows_nt')
748 assert os != 'Windows_NT'
750 if (architecture == 'armem') {
751 // arm emulator (Tizen). Build and test on same machine,
754 Utilities.setMachineAffinity(job, 'Ubuntu', 'arm-cross-latest')
757 // arm/arm64 Ubuntu on hardware.
758 assert architecture == 'arm' || architecture == 'arm64'
759 def isFlow = (options != null) && (options['is_flow_job'] == true)
760 def isBuild = (options != null) && (options['is_build_job'] == true)
761 if (isFlow || isBuild) {
762 // arm/arm64 Ubuntu build machine. Build uses docker, so the actual host OS is not
763 // very important. Therefore, use latest or auto. Flow jobs don't need to use arm hardware.
764 Utilities.setMachineAffinity(job, 'Ubuntu16.04', 'latest-or-auto')
766 // arm/arm64 Ubuntu test machine. Specify the Helix queue name here.
767 if (architecture == 'arm64') {
768 assert os == 'Ubuntu16.04'
770 label('Ubuntu.1604.Arm64.Open')
774 assert os == 'Ubuntu'
776 label('ubuntu.1404.arm32.open')
784 // setJobMachineAffinity: compute the machine affinity options for a job,
785 // then set the job with those affinity options.
786 def static setJobMachineAffinity(def architecture, def os, def isBuildJob, def isTestJob, def isFlowJob, def job)
788 assert (isBuildJob && !isTestJob && !isFlowJob) ||
789 (!isBuildJob && isTestJob && !isFlowJob) ||
790 (!isBuildJob && !isTestJob && isFlowJob)
792 def affinityOptions = null
793 def affinityArchitecture = architecture
795 if (os == "Windows_NT") {
796 if (architecture in Constants.armWindowsCrossArchitectureList) {
798 affinityOptions = [ "use_arm64_build_machine" : true ]
799 } else if (isTestJob) {
800 affinityOptions = [ "use_arm64_build_machine" : false ]
801 } else if (isFlowJob) {
802 // For the flow jobs set the machine affinity as x64
803 affinityArchitecture = 'x64'
808 if ((architecture == 'arm64') || (architecture == 'arm')) {
810 affinityOptions = ['is_build_job': true]
811 } else if (isFlowJob) {
812 affinityOptions = ['is_flow_job': true]
817 setMachineAffinity(job, os, affinityArchitecture, affinityOptions)
820 def static isGCStressRelatedTesting(def scenario) {
821 // The 'r2r_gcstress15' scenario is a basic scenario.
822 // Detect it and make it a GCStress related.
823 if (scenario == 'r2r_gcstress15')
828 def gcStressTestEnvVars = [ 'COMPlus_GCStress', 'COMPlus_ZapDisable', 'COMPlus_HeapVerify']
829 def scenarioName = scenario.toLowerCase()
830 def isGCStressTesting = false
831 Constants.jitStressModeScenarios[scenario].each{ k, v ->
832 if (k in gcStressTestEnvVars) {
833 isGCStressTesting = true;
836 return isGCStressTesting
839 def static isCoreFxScenario(def scenario) {
840 def corefx_prefix = 'corefx_'
841 if (scenario.length() < corefx_prefix.length()) {
844 return scenario.substring(0,corefx_prefix.length()) == corefx_prefix
847 def static isR2RBaselineScenario(def scenario) {
848 return (scenario == 'r2r')
851 def static isR2RStressScenario(def scenario) {
852 return Constants.r2rStressScenarios.containsKey(scenario)
855 def static isR2RScenario(def scenario) {
856 return isR2RBaselineScenario(scenario) || isR2RStressScenario(scenario)
859 def static isJitStressScenario(def scenario) {
860 return Constants.jitStressModeScenarios.containsKey(scenario)
863 def static isLongGc(def scenario) {
864 return (scenario == 'longgc' || scenario == 'gcsimulator')
867 def static isJitDiff(def scenario) {
868 return (scenario == 'jitdiff')
871 def static isGcReliabilityFramework(def scenario) {
872 return (scenario == 'gc_reliability_framework')
875 def static isArmWindowsScenario(def scenario) {
876 return Constants.validArmWindowsScenarios.containsKey(scenario)
879 def static isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly) {
880 if (isBuildOnly == true) {
881 os = 'Windows_NT_BuildOnly'
884 def validOsPrTriggerArchConfigs = Constants.prTriggeredValidInnerLoopCombos[os]
885 if (validOsPrTriggerArchConfigs != null) {
886 def validOsPrTriggerConfigs = validOsPrTriggerArchConfigs[architecture]
887 if (validOsPrTriggerConfigs != null) {
888 if (configuration in validOsPrTriggerConfigs) {
897 // This means the job builds and runs the 'innerloop' test set. This does not mean the job is
898 // scheduled with a default PR trigger despite the correlation being true at the moment.
899 def static isInnerloopTestScenario(def scenario) {
900 return (scenario == 'innerloop' || scenario == 'no_tiered_compilation_innerloop')
903 def static isCrossGenComparisonScenario(def scenario) {
904 return (scenario == 'crossgen_comparison')
907 def static shouldGenerateCrossGenComparisonJob(def os, def architecture, def configuration, def scenario) {
908 assert isCrossGenComparisonScenario(scenario)
909 return (os == 'Ubuntu' && architecture == 'arm' && configuration == 'Checked')
912 def static getFxBranch(def branch) {
913 def fxBranch = branch
914 // Map 'dev/unix_test_workflow' to 'master' so we can test CoreFX jobs in the CoreCLR dev/unix_test_workflow
915 // branch even though CoreFX doesn't have such a branch.
916 if (branch == 'dev/unix_test_workflow') {
922 def static setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly) {
923 // 2 hours (120 minutes) is the default timeout
926 if (!isInnerloopTestScenario(scenario)) {
927 // Pri-1 test builds take a long time (see calculateBuildCommands()). So up the Pri-1 build jobs timeout.
932 // Note that these can only increase, never decrease, the Pri-1 timeout possibly set above.
933 if (isGCStressRelatedTesting(scenario)) {
936 else if (isCoreFxScenario(scenario)) {
939 else if (isJitStressScenario(scenario)) {
942 else if (isR2RBaselineScenario(scenario)) {
945 else if (isLongGc(scenario)) {
948 else if (isJitDiff(scenario)) {
951 else if (isGcReliabilityFramework(scenario)) {
954 else if (architecture == 'armem' || architecture == 'arm64') {
958 if (architecture == 'arm') {
959 // ARM32 machines are particularly slow.
964 if (configuration == 'Debug') {
965 // Debug runs can be very slow. Add an hour.
969 if (architecture == 'x86_arm_altjit' || architecture == 'x64_arm64_altjit') {
970 // AltJit runs compile all methods twice.
974 // If we've changed the timeout from the default, set it in the job.
976 if (timeout != 120) {
977 Utilities.setJobTimeout(newJob, timeout)
981 def static getJobFolder(def scenario) {
982 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
985 if (scenario == 'illink') {
991 def static getStressModeDisplayName(def scenario) {
993 Constants.jitStressModeScenarios[scenario].each{ k, v ->
994 def prefixLength = 'COMPlus_'.length()
995 if (k.length() >= prefixLength) {
996 def modeName = k.substring(prefixLength, k.length())
997 if (displayStr != '') {
998 // Separate multiple variables with a space.
1001 displayStr += modeName + '=' + v
1005 if (isCoreFxScenario(scenario)) {
1006 displayStr = ('CoreFx ' + displayStr).trim()
1012 def static getR2RDisplayName(def scenario) {
1013 // Assume the scenario name is one from the r2rStressScenarios dict, and remove its "r2r_" prefix.
1014 def displayStr = scenario
1015 def prefixLength = 'r2r_'.length()
1016 if (displayStr.length() >= prefixLength) {
1017 displayStr = "R2R " + displayStr.substring(prefixLength, displayStr.length())
1018 } else if (scenario == 'r2r') {
1024 def static getScenarioDisplayString(def scenario) {
1027 return "Innerloop Build and Test"
1029 case 'no_tiered_compilation_innerloop':
1030 def displayStr = getStressModeDisplayName(scenario)
1031 return "Innerloop Build and Test (Jit - ${displayStr})"
1033 case 'corefx_innerloop':
1034 return "CoreFX Tests"
1037 return "Build and Test"
1040 return "Jit Diff Build and Test"
1043 return "IL RoundTrip Build and Test"
1046 return "Long-Running GC Build & Test"
1049 return "GC Simulator"
1051 case 'standalone_gc':
1052 return "Standalone GC"
1054 case 'gc_reliability_framework':
1055 return "GC Reliability Framework"
1061 if (isJitStressScenario(scenario)) {
1062 def displayStr = getStressModeDisplayName(scenario)
1063 return "Build and Test (Jit - ${displayStr})"
1065 else if (isR2RScenario(scenario)) {
1066 def displayStr = getR2RDisplayName(scenario)
1067 return "${displayStr} Build and Test"
1070 return "${scenario}"
1075 println("Unknown scenario: ${scenario}");
1080 // Functions to create an environment script.
1081 // envScriptCreate -- initialize the script (call first)
1082 // envScriptFinalize -- finalize the script (call last)
1083 // envScriptSetStressModeVariables -- set stress mode variables in the env script
1084 // envScriptAppendExistingScript -- append an existing script to the generated script
1086 // Each script returns a string of commands. Concatenate all the strings together before
1087 // adding them to the builds commands, to make sure they get executed as one Jenkins script.
1090 // Initialize the environment setting script.
1091 def static envScriptCreate(def os, def stepScriptLocation) {
1093 if (os == 'Windows_NT') {
1094 stepScript += "echo Creating TestEnv script\r\n"
1095 stepScript += "if exist ${stepScriptLocation} del ${stepScriptLocation}\r\n"
1097 // Create at least an empty script.
1098 stepScript += "echo. > ${stepScriptLocation}\r\n"
1101 stepScript += "echo Creating environment setting script\n"
1102 stepScript += "echo \\#\\!/usr/bin/env bash > ${stepScriptLocation}\n"
1108 // Generates the string for setting stress mode variables.
1109 def static envScriptSetStressModeVariables(def os, def stressModeVars, def stepScriptLocation) {
1111 if (os == 'Windows_NT') {
1112 stressModeVars.each{ k, v ->
1113 // Write out what we are writing to the script file
1114 stepScript += "echo Setting ${k}=${v}\r\n"
1115 // Write out the set itself to the script file`
1116 stepScript += "echo set ${k}=${v} >> ${stepScriptLocation}\r\n"
1120 stressModeVars.each{ k, v ->
1121 // Write out what we are writing to the script file
1122 stepScript += "echo Setting ${k}=${v}\n"
1123 // Write out the set itself to the script file`
1124 stepScript += "echo export ${k}=${v} >> ${stepScriptLocation}\n"
1131 // Append an existing script to an environment script.
1132 // Returns string of commands to do this.
1133 def static envScriptAppendExistingScript(def os, def appendScript, def stepScriptLocation) {
1134 assert (os == 'Windows_NT')
1137 stepScript += "echo Appending ${appendScript} to ${stepScriptLocation}\r\n"
1138 stepScript += "type ${appendScript} >> ${stepScriptLocation}\r\n"
1143 // Finalize an environment setting script.
1144 // Returns string of commands to do this.
1145 def static envScriptFinalize(def os, def stepScriptLocation) {
1148 if (os == 'Windows_NT') {
1149 // Display the resulting script. This is useful when looking at the output log file.
1150 stepScript += "echo Display the total script ${stepScriptLocation}\r\n"
1151 stepScript += "type ${stepScriptLocation}\r\n"
1154 stepScript += "chmod +x ${stepScriptLocation}\n"
1160 def static isNeedDocker(def architecture, def os, def isBuild) {
1162 if (architecture == 'x86' && os == 'Ubuntu') {
1165 else if (architecture == 'armem') {
1168 else if (architecture == 'arm') {
1169 if (os == 'Ubuntu') {
1173 else if (architecture == 'arm64') {
1174 if (os == 'Ubuntu16.04') {
1180 if (architecture == 'x86' && os == 'Ubuntu') {
1187 def static getDockerImageName(def architecture, def os, def isBuild) {
1188 // We must change some docker private images to official later
1190 if (architecture == 'x86' && os == 'Ubuntu') {
1191 return "hseok82/dotnet-buildtools-prereqs:ubuntu-16.04-crossx86-ef0ac75-20175511035548"
1193 else if (architecture == 'armem') {
1194 if (os == 'Tizen') {
1195 return "tizendotnet/dotnet-buildtools-prereqs:ubuntu-16.04-cross-e435274-20180426002255-tizen-rootfs-5.0m1"
1198 else if (architecture == 'arm') {
1199 if (os == 'Ubuntu') {
1200 return "microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-e435274-20180426002420"
1203 else if (architecture == 'arm64') {
1204 if (os == 'Ubuntu16.04') {
1205 return "microsoft/dotnet-buildtools-prereqs:ubuntu-16.04-cross-arm64-a3ae44b-20180315221921"
1210 if (architecture == 'x86' && os == 'Ubuntu') {
1211 return "hseok82/dotnet-buildtools-prereqs:ubuntu1604_x86_test"
1214 println("Unknown architecture to use docker: ${architecture} ${os}");
1219 // We have a limited amount of some hardware. For these, scale back the periodic testing we do,
1220 // and only allowing using this hardware in some specific branches.
1221 def static jobRequiresLimitedHardware(def architecture, def os) {
1222 if (architecture == 'arm') {
1223 // arm Windows and Linux hardware is limited.
1226 else if (architecture == 'arm64') {
1227 if (os == 'Windows_NT') {
1228 // arm64 Windows hardware is limited.
1232 // arm64 Linux hardware is fast enough to allow more frequent jobs
1241 // Calculates the name of the build job based on some typical parameters.
1243 def static getJobName(def configuration, def architecture, def os, def scenario, def isBuildOnly) {
1244 // If the architecture is x64, do not add that info into the build name.
1245 // Need to change around some systems and other builds to pick up the right builds
1248 def suffix = scenario != 'normal' ? "_${scenario}" : '';
1253 switch (architecture) {
1255 if (scenario == 'normal') {
1256 // For now we leave x64 off of the name for compatibility with other jobs
1257 baseName = configuration.toLowerCase() + '_' + os.toLowerCase()
1259 else if (scenario == 'formatting') {
1260 // we don't care about the configuration for the formatting job. It runs all configs
1261 baseName = architecture.toLowerCase() + '_' + os.toLowerCase()
1264 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1268 // These are cross builds
1269 assert os == 'Tizen'
1270 baseName = 'armel_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1274 // These are cross builds
1275 baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1278 case 'x86_arm_altjit':
1279 case 'x64_arm64_altjit':
1280 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
1283 println("Unknown architecture: ${architecture}");
1288 return baseName + suffix
1291 def static addNonPRTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob, def bidailyCrossList) {
1292 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1294 // Limited hardware is restricted for non-PR triggers to certain branches.
1295 if (jobRequiresLimitedHardware(architecture, os) && (!(branch in Constants.LimitedHardwareBranches))) {
1299 // Ubuntu x86 CI jobs are failing. Disable non-PR triggered jobs to avoid these constant failures
1300 // until this is fixed. Tracked by https://github.com/dotnet/coreclr/issues/19003.
1301 if (architecture == 'x86' && os == 'Ubuntu') {
1308 case 'no_tiered_compilation_innerloop':
1309 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
1310 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
1311 // We should never get here (in the "innerloop cases) for non-PR jobs, except for this TEMPORARY exception.
1312 // Only trigger the flow job, not the build job.
1313 assert (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked'))
1315 addGithubPushTriggerHelper(job)
1319 case 'crossgen_comparison':
1322 switch (architecture) {
1325 if (isFlowJob && architecture == 'x86' && os == 'Ubuntu') {
1326 addPeriodicTriggerHelper(job, '@daily')
1328 else if (isFlowJob || os == 'Windows_NT' || (architecture == 'x64' && !(os in Constants.crossList))) {
1329 addGithubPushTriggerHelper(job)
1333 if (os == 'Windows_NT') {
1334 if (isFlowJob || (isNormalOrInnerloop && (configuration == 'Debug'))) {
1335 // We would normally want a per-push trigger, but with limited hardware we can't keep up.
1336 // Do the builds daily.
1337 addPeriodicTriggerHelper(job, '@daily')
1341 // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job.
1343 addPeriodicTriggerHelper(job, '@daily')
1348 if (os == 'Windows_NT') {
1349 if (isFlowJob || (isNormalOrInnerloop && (configuration == 'Debug'))) {
1350 // We would normally want a push trigger, but with limited hardware we can't keep up.
1351 // Do the builds daily.
1352 addPeriodicTriggerHelper(job, '@daily')
1356 assert os == 'Ubuntu'
1357 // Only the flow jobs get push triggers; the build and test jobs are triggered by the flow job.
1359 // Currently no push triggers, with limited arm Linux hardware.
1360 // TODO: If we have enough machine capacity, add some arm Linux push triggers.
1361 addPeriodicTriggerHelper(job, '@daily')
1366 addGithubPushTriggerHelper(job)
1368 case 'x86_arm_altjit':
1369 case 'x64_arm64_altjit':
1370 // Only do altjit push triggers for Checked; don't waste time on Debug or Release.
1371 if (configuration == 'Checked') {
1372 addGithubPushTriggerHelper(job)
1376 println("Unknown architecture: ${architecture}");
1382 assert !(os in bidailyCrossList)
1383 // r2r gets a push trigger for checked/release
1384 if (configuration == 'Checked' || configuration == 'Release') {
1385 if (architecture == 'x64' && os != 'OSX10.12') {
1386 //Flow jobs should be Windows, Ubuntu, OSX0.12, or CentOS
1387 if (isFlowJob || os == 'Windows_NT') {
1388 addGithubPushTriggerHelper(job)
1390 // OSX10.12 r2r jobs should only run every 12 hours, not daily.
1391 } else if (architecture == 'x64' && os == 'OSX10.12'){
1393 addPeriodicTriggerHelper(job, 'H H/12 * * *')
1396 // For x86, only add per-commit jobs for Windows
1397 else if (architecture == 'x86') {
1398 if (os == 'Windows_NT') {
1399 addGithubPushTriggerHelper(job)
1402 // arm r2r jobs should only run weekly.
1403 else if (architecture == 'arm') {
1405 addPeriodicTriggerHelper(job, '@weekly')
1408 // arm64 r2r jobs should only run weekly.
1409 else if (architecture == 'arm64') {
1411 addPeriodicTriggerHelper(job, '@weekly')
1416 case 'r2r_jitstress1':
1417 case 'r2r_jitstress2':
1418 case 'r2r_jitstress1_tiered':
1419 case 'r2r_jitstress2_tiered':
1420 case 'r2r_jitstressregs1':
1421 case 'r2r_jitstressregs2':
1422 case 'r2r_jitstressregs3':
1423 case 'r2r_jitstressregs4':
1424 case 'r2r_jitstressregs8':
1425 case 'r2r_jitstressregs0x10':
1426 case 'r2r_jitstressregs0x80':
1427 case 'r2r_jitstressregs0x1000':
1428 case 'r2r_jitminopts':
1429 case 'r2r_jitforcerelocs':
1430 case 'r2r_gcstress15':
1431 case 'r2r_no_tiered_compilation':
1432 assert !(os in bidailyCrossList)
1434 // GCStress=C is currently not supported on OS X
1435 if (os == 'OSX10.12' && isGCStressRelatedTesting(scenario)) {
1439 if (configuration == 'Checked' || configuration == 'Release') {
1440 if (architecture == 'x64') {
1441 //Flow jobs should be Windows, Ubuntu, OSX10.12, or CentOS
1442 if (isFlowJob || os == 'Windows_NT') {
1443 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1446 // For x86, only add periodic jobs for Windows
1447 else if (architecture == 'x86') {
1448 if (os == 'Windows_NT') {
1449 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1452 else if (architecture == 'arm') {
1454 addPeriodicTriggerHelper(job, '@weekly')
1457 else if (architecture == 'arm64') {
1459 addPeriodicTriggerHelper(job, '@weekly')
1465 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1466 assert configuration == 'Release'
1467 assert architecture == 'x64'
1468 addPeriodicTriggerHelper(job, '@daily')
1469 // TODO: Add once external email sending is available again
1470 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1473 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1474 assert configuration == 'Release'
1475 assert architecture == 'x64'
1476 addPeriodicTriggerHelper(job, 'H H * * 3,6') // some time every Wednesday and Saturday
1477 // TODO: Add once external email sending is available again
1478 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1480 case 'standalone_gc':
1481 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1482 assert (configuration == 'Release' || configuration == 'Checked')
1483 // TODO: Add once external email sending is available again
1484 // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
1485 addPeriodicTriggerHelper(job, '@daily')
1487 case 'gc_reliability_framework':
1488 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1489 assert (configuration == 'Release' || configuration == 'Checked')
1490 // Only triggered by phrase.
1493 assert !(os in bidailyCrossList)
1494 // ILASM/ILDASM roundtrip one gets a daily build, and only for release
1495 if (architecture == 'x64' && configuration == 'Release') {
1496 if (isFlowJob || os == 'Windows_NT') {
1497 addPeriodicTriggerHelper(job, '@daily')
1502 assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX10.12')
1503 assert configuration == 'Checked'
1504 assert (architecture == 'x64' || architecture == 'x86')
1505 addGithubPushTriggerHelper(job)
1508 assert (os == 'Windows_NT' || os == "Ubuntu")
1509 assert architecture == 'x64'
1510 addGithubPushTriggerHelper(job)
1512 case 'jitstressregs1':
1513 case 'jitstressregs2':
1514 case 'jitstressregs3':
1515 case 'jitstressregs4':
1516 case 'jitstressregs8':
1517 case 'jitstressregs0x10':
1518 case 'jitstressregs0x80':
1519 case 'jitstressregs0x1000':
1521 case 'tieredcompilation':
1522 case 'no_tiered_compilation':
1526 case 'jitstress1_tiered':
1527 case 'jitstress2_tiered':
1528 case 'jitstress2_jitstressregs1':
1529 case 'jitstress2_jitstressregs2':
1530 case 'jitstress2_jitstressregs3':
1531 case 'jitstress2_jitstressregs4':
1532 case 'jitstress2_jitstressregs8':
1533 case 'jitstress2_jitstressregs0x10':
1534 case 'jitstress2_jitstressregs0x80':
1535 case 'jitstress2_jitstressregs0x1000':
1536 case 'tailcallstress':
1539 case 'jitnox86hwintrinsic':
1540 case 'jitincompletehwintrinsic':
1541 case 'jitx86hwintrinsicnoavx':
1542 case 'jitx86hwintrinsicnoavx2':
1543 case 'jitx86hwintrinsicnosimd':
1544 case 'corefx_baseline':
1545 case 'corefx_minopts':
1546 case 'corefx_tieredcompilation':
1547 case 'corefx_jitstress1':
1548 case 'corefx_jitstress2':
1549 case 'corefx_jitstressregs1':
1550 case 'corefx_jitstressregs2':
1551 case 'corefx_jitstressregs3':
1552 case 'corefx_jitstressregs4':
1553 case 'corefx_jitstressregs8':
1554 case 'corefx_jitstressregs0x10':
1555 case 'corefx_jitstressregs0x80':
1556 case 'corefx_jitstressregs0x1000':
1558 if (os == 'CentOS7.1') {
1561 if (os in bidailyCrossList) {
1564 // ARM corefx testing uses non-flow jobs to provide the configuration-specific
1565 // build for the flow job. We don't need cron jobs for these. Note that the
1566 // Windows ARM jobs depend on a Windows "build only" job that exits the trigger
1567 // function very early, so only non-Windows gets here.
1568 if ((architecture == 'arm') && isCoreFxScenario(scenario) && !isFlowJob) {
1571 if ((architecture == 'arm64') && isCoreFxScenario(scenario) && !isFlowJob) {
1574 if (jobRequiresLimitedHardware(architecture, os)) {
1575 addPeriodicTriggerHelper(job, '@weekly')
1578 addPeriodicTriggerHelper(job, '@daily')
1583 if (os == 'CentOS7.1') {
1586 if (os in bidailyCrossList) {
1589 addPeriodicTriggerHelper(job, '@weekly')
1592 case 'gcstress0xc_zapdisable':
1593 case 'gcstress0xc_zapdisable_jitstress2':
1594 case 'gcstress0xc_zapdisable_heapverify1':
1595 case 'gcstress0xc_jitstress1':
1596 case 'gcstress0xc_jitstress2':
1597 case 'gcstress0xc_minopts_heapverify1':
1598 if (os == 'OSX10.12') {
1599 // GCStress=C is currently not supported on OS X
1602 if (os == 'CentOS7.1') {
1605 if (os in bidailyCrossList) {
1608 addPeriodicTriggerHelper(job, '@weekly')
1612 // Testing on other operating systems TBD
1613 assert (os == 'Windows_NT' || os == 'Ubuntu')
1614 if (architecture == 'x64' || architecture == 'x86') {
1615 if (configuration == 'Checked') {
1616 addPeriodicTriggerHelper(job, '@daily')
1622 println("Unknown scenario: ${scenario}");
1629 // **************************
1630 // Define the basic inner loop builds for PR and commit. This is basically just the set
1631 // of coreclr builds over linux/osx 10.12/windows and debug/release/checked. In addition, the windows
1632 // builds will do a couple extra steps.
1633 // **************************
1635 // Adds a trigger for the PR build if one is needed. If isFlowJob is true, then this is the
1636 // flow job that rolls up the build and test for non-windows OS's. // If the job is a windows build only job,
1637 // it's just used for internal builds
1638 // If you add a job with a trigger phrase, please add that phrase to coreclr/Documentation/project-docs/ci-trigger-phrases.md
1639 def static addTriggers(def job, def branch, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob, def isWindowsBuildOnlyJob) {
1640 def isNormalOrInnerloop = (scenario == "normal" || scenario == "innerloop")
1642 if (isWindowsBuildOnlyJob) {
1646 def bidailyCrossList = ['RHEL7.2', 'Debian8.4']
1647 // Non pull request builds.
1649 addNonPRTriggers(job, branch, isPR, architecture, os, configuration, scenario, isFlowJob, isWindowsBuildOnlyJob, bidailyCrossList)
1674 // Pull request builds. Generally these fall into two categories: default triggers and on-demand triggers
1675 // We generally only have a distinct set of default triggers but a bunch of on-demand ones.
1677 def contextString = ""
1678 def triggerString = ""
1679 def needsTrigger = true
1680 def isDefaultTrigger = false
1681 def isArm64PrivateJob = false
1682 def scenarioString = ""
1684 // Set up default context string and trigger phrases. This is overridden in places, sometimes just to keep
1685 // the existing non-standard descriptions and phrases. In some cases, the scenarios are asymmetric, as for
1686 // some jobs where the Debug configuration just does builds, no tests.
1688 // Some configurations, like arm32/arm64, always use the exact scenario name as part of the context string.
1689 // This makes it possible to copy/paste the displayed context string as "@dotnet-bot test <context-string>"
1690 // to invoke the trigger. Any "fancy" context string makes that impossible, requiring the user to either
1691 // remember the mapping from context string to trigger string, or use "@dotnet-bot help" to look it up.
1693 if (architecture == 'armem') {
1694 assert os == 'Tizen'
1695 architecture = 'armel'
1698 switch (architecture) {
1699 case 'x64_arm64_altjit':
1700 case 'x86_arm_altjit':
1701 // TODO: for consistency, add "Build and Test" at end.
1702 contextString = "${os} ${architecture} ${configuration} ${scenario}"
1703 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*"
1709 contextString = "${os} ${architecture} Cross ${configuration}"
1710 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+Cross\\W+${configuration}"
1712 if (scenario == 'innerloop') {
1713 contextString += " Innerloop"
1714 triggerString += "\\W+Innerloop"
1717 contextString += " ${scenario}"
1718 triggerString += "\\W+${scenario}"
1721 if (configuration == 'Debug') {
1722 contextString += " Build"
1723 triggerString += "\\W+Build"
1726 contextString += " Build and Test"
1727 triggerString += "\\W+Build and Test"
1730 triggerString += ".*"
1734 scenarioString = getScenarioDisplayString(scenario)
1735 contextString = "${os} ${architecture} ${configuration} ${scenarioString}"
1736 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}"
1740 triggerString += "\\W+Build and Test.*"
1743 case 'corefx_innerloop': // maintain this asymmetry
1744 triggerString += "\\W+CoreFX Tests.*"
1748 triggerString += "\\W+${scenario}.*"
1752 triggerString += ".*"
1756 // Now determine what kind of trigger this job needs, if any. Any job should be triggerable, except for
1757 // non-flow jobs that are only used as part of flow jobs.
1759 switch (architecture) {
1760 case 'x64': // editor brace matching: {
1761 if (scenario == 'formatting') {
1762 assert configuration == 'Checked'
1763 if (os == 'Windows_NT' || os == 'Ubuntu') {
1764 isDefaultTrigger = true
1765 contextString = "${os} ${architecture} Formatting"
1771 // OpenSUSE, Debian & RedHat get trigger phrases for pri 0 build, and pri 1 build & test
1774 if (scenario == 'innerloop') {
1776 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1777 isDefaultTrigger = true
1787 assert scenario != 'innerloop'
1788 contextString = "${os} ${architecture} ${configuration} Build"
1789 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+Build.*"
1793 if (scenario == 'illink') {
1796 else if (scenario == 'corefx_innerloop') {
1797 if (configuration == 'Checked') {
1798 isDefaultTrigger = true
1806 // Triggers on the non-flow jobs aren't necessary here
1807 // Corefx testing uses non-flow jobs.
1808 if (!isFlowJob && !isCoreFxScenario(scenario)) {
1809 needsTrigger = false
1814 isDefaultTrigger = true
1817 case 'no_tiered_compilation_innerloop':
1818 if (os == 'Ubuntu') {
1819 isDefaultTrigger = true
1831 // CentOS uses checked for default PR tests while debug is build only
1832 if (configuration == 'Debug') {
1833 isDefaultTrigger = true
1834 contextString = "${os} ${architecture} ${configuration} Innerloop Build"
1838 // Make sure this is a flow job to get build and test.
1840 needsTrigger = false
1844 if (configuration == 'Checked') {
1845 assert job.name.contains("flow")
1846 isDefaultTrigger = true
1847 contextString = "${os} ${architecture} ${configuration} Innerloop Build and Test"
1852 // Make sure this is a flow job to get build and test.
1854 needsTrigger = false
1867 case 'no_tiered_compilation_innerloop':
1868 isDefaultTrigger = true
1871 case 'corefx_innerloop':
1872 if (configuration == 'Checked' || configuration == 'Release') {
1873 isDefaultTrigger = true
1883 println("Unknown os: ${os}");
1890 // editor brace matching: }
1892 case 'armel': // editor brace matching: {
1895 azureVMAgentPostBuildAction {
1896 agentPostBuildAction('Delete agent if the build was not successful (when idle).')
1903 if (scenario == 'innerloop') {
1904 if (configuration == 'Checked') {
1905 isDefaultTrigger = true
1912 // editor brace matching: }
1915 case 'arm64': // editor brace matching: {
1921 // Triggers on the non-flow jobs aren't necessary
1923 needsTrigger = false
1929 case 'no_tiered_compilation_innerloop':
1930 if (configuration == 'Checked') {
1931 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
1932 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
1933 if (architecture == 'arm64') {
1936 isDefaultTrigger = true
1943 assert isArmWindowsScenario(scenario)
1945 // 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
1946 // the non-flow Build job. All others need a trigger on the flow job.
1947 def needsFlowJobTrigger = !(isNormalOrInnerloop && (configuration == 'Debug'))
1948 if (isFlowJob != needsFlowJobTrigger) {
1949 needsTrigger = false
1955 if (configuration == 'Debug') {
1956 // Add default PR trigger for Windows arm64 Debug builds. This is a build only -- no tests are run --
1957 // so the private test hardware is not used. Thus, it can be run by all users, not just arm64Users.
1958 // People in arm64Users will get both this and the Checked Build and Test job.
1959 isDefaultTrigger = true
1960 } else if (configuration == 'Checked') {
1961 isDefaultTrigger = true
1962 isArm64PrivateJob = true
1966 isArm64PrivateJob = true
1971 println("NYI os: ${os}");
1977 // editor brace matching: }
1978 case 'x86': // editor brace matching: {
1979 assert ((os == 'Windows_NT') || ((os == 'Ubuntu') && isNormalOrInnerloop))
1980 if (os == 'Ubuntu') {
1981 // Triggers on the non-flow jobs aren't necessary here
1983 needsTrigger = false
1987 // on-demand only for ubuntu x86
1988 contextString = "${os} ${architecture} ${configuration} Build"
1989 triggerString = "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}.*"
1994 case 'no_tiered_compilation_innerloop':
1995 isDefaultTrigger = true
2002 // editor brace matching: }
2003 case 'x64_arm64_altjit':
2004 case 'x86_arm_altjit':
2005 // Everything default
2009 println("Unknown architecture: ${architecture}");
2015 if (isArm64PrivateJob) {
2016 if (isDefaultTrigger) {
2017 Utilities.addDefaultPrivateGithubPRTriggerForBranch(job, branch, contextString, null, arm64Users)
2020 Utilities.addPrivateGithubPRTriggerForBranch(job, branch, contextString, triggerString, null, arm64Users)
2024 if (isDefaultTrigger) {
2025 Utilities.addGithubPRTriggerForBranch(job, branch, contextString)
2028 Utilities.addGithubPRTriggerForBranch(job, branch, contextString, triggerString)
2034 def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR, def architecture, def configuration, def os, def isBuildOnly) {
2035 def buildCommands = []
2036 def osGroup = getOSGroup(os)
2037 def lowerConfiguration = configuration.toLowerCase()
2040 if (isInnerloopTestScenario(scenario)) {
2044 def doCoreFxTesting = isCoreFxScenario(scenario)
2046 // Calculate the build steps, archival, and xunit results
2048 case 'Windows_NT': // editor brace matching: {
2049 switch (architecture) {
2052 case 'x86_arm_altjit':
2053 case 'x64_arm64_altjit':
2054 def arch = architecture
2056 if (architecture == 'x86_arm_altjit') {
2059 else if (architecture == 'x64_arm64_altjit') {
2063 if (scenario == 'formatting') {
2064 buildCommands += "python -u tests\\scripts\\format.py -c %WORKSPACE% -o Windows_NT -a ${arch}"
2065 Utilities.addArchival(newJob, "format.patch", "", true, false)
2069 if (scenario == 'illink') {
2070 buildCommands += "tests\\scripts\\build_illink.cmd clone ${arch}"
2073 // If it is a release build for Windows, ensure PGO is used, else fail the build.
2074 if ((lowerConfiguration == 'release') &&
2075 (scenario in Constants.basicScenarios) &&
2076 (architecture != 'x86_arm_altjit') &&
2077 (architecture != 'x64_arm64_altjit')) {
2079 buildOpts += ' -enforcepgo'
2082 if (doCoreFxTesting) {
2083 buildOpts += ' skiptests';
2085 buildOpts += " -priority=${priority}"
2088 // Set __TestIntermediateDir to something short. If __TestIntermediateDir is already set, build-test.cmd will
2089 // output test binaries to that directory. If it is not set, the binaries are sent to a default directory whose name is about
2090 // 35 characters long.
2092 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts}"
2095 def runtestArguments = ''
2096 def testOpts = 'collectdumps'
2098 if (isR2RScenario(scenario)) {
2100 // If this is a ReadyToRun scenario, pass 'crossgen' or 'crossgenaltjit'
2101 // to cause framework assemblies to be crossgen'ed. Pass 'runcrossgentests'
2102 // to cause the tests to be crossgen'ed.
2104 if ((architecture == 'x86_arm_altjit') || (architecture == 'x64_arm64_altjit')) {
2105 testOpts += ' crossgenaltjit protononjit.dll'
2107 testOpts += ' crossgen'
2110 testOpts += ' runcrossgentests'
2112 else if (scenario == 'jitdiff') {
2113 testOpts += ' jitdisasm crossgen'
2115 else if (scenario == 'ilrt') {
2116 testOpts += ' ilasmroundtrip'
2118 else if (isLongGc(scenario)) {
2119 testOpts += " ${scenario} sequential"
2121 else if (scenario == 'standalone_gc') {
2122 testOpts += ' gcname clrgc.dll'
2124 else if (scenario == 'illink') {
2125 testOpts += " link %WORKSPACE%\\linker\\linker\\bin\\netcore_Release\\netcoreapp2.0\\win10-${arch}\\publish\\illink.exe"
2128 // Default per-test timeout is 10 minutes. For stress modes and Debug scenarios, increase this
2129 // to 30 minutes (30 * 60 * 1000 = 180000). The "timeout" argument to runtest.cmd sets this, by
2130 // taking a timeout value in milliseconds. (Note that it sets the __TestTimeout environment variable,
2131 // which is read by the xunit harness.)
2132 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario) || (lowerConfiguration == 'debug'))
2134 def timeout = 1800000
2135 testOpts += " timeout ${timeout}"
2138 // If we are running a stress mode, we should write out the set of key
2139 // value env pairs to a file at this point and then we'll pass that to runtest.cmd
2141 def envScriptPath = ''
2142 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
2143 def buildCommandsStr = ''
2144 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2145 buildCommandsStr += envScriptCreate(os, envScriptPath)
2147 if (isJitStressScenario(scenario)) {
2148 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2150 else if (isR2RStressScenario(scenario)) {
2151 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.r2rStressScenarios[scenario], envScriptPath)
2154 if (architecture == 'x86_arm_altjit') {
2155 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x86_arm_altjit.cmd", envScriptPath)
2157 else if (architecture == 'x64_arm64_altjit') {
2158 buildCommandsStr += envScriptAppendExistingScript(os, "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd", envScriptPath)
2161 envScriptFinalize(os, envScriptPath)
2163 // Note that buildCommands is an array of individually executed commands; we want all the commands used to
2164 // create the SetStressModes.bat script to be executed together, hence we accumulate them as strings
2165 // into a single script.
2166 buildCommands += buildCommandsStr
2168 else if (architecture == 'x86_arm_altjit') {
2169 envScriptPath = "%WORKSPACE%\\tests\\x86_arm_altjit.cmd"
2171 else if (architecture == 'x64_arm64_altjit') {
2172 envScriptPath = "%WORKSPACE%\\tests\\x64_arm64_altjit.cmd"
2174 if (envScriptPath != '') {
2175 testOpts += " TestEnv ${envScriptPath}"
2178 runtestArguments = "${lowerConfiguration} ${arch} ${testOpts}"
2180 if (doCoreFxTesting) {
2181 if (scenario == 'corefx_innerloop') {
2182 // Create CORE_ROOT and testhost
2183 buildCommands += "build-test.cmd ${lowerConfiguration} ${arch} buildtesthostonly"
2184 buildCommands += "tests\\runtest.cmd ${runtestArguments} CoreFXTestsAll"
2186 // Archive and process (only) the test results
2187 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2188 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2191 def workspaceRelativeFxRoot = "_/fx"
2192 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2193 def fxBranch = getFxBranch(branch)
2195 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}"
2197 // Archive and process (only) the test results
2198 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2199 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2201 //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
2202 Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
2203 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
2206 else if (isGcReliabilityFramework(scenario)) {
2207 buildCommands += "tests\\runtest.cmd ${runtestArguments} GenerateLayoutOnly"
2208 buildCommands += "tests\\scripts\\run-gc-reliability-framework.cmd ${arch} ${configuration}"
2211 buildCommands += "tests\\runtest.cmd ${runtestArguments}"
2213 } // end if (!isBuildOnly)
2215 if (!doCoreFxTesting) {
2216 // Run the rest of the build
2217 // Build the mscorlib for the other OS's
2218 buildCommands += "build.cmd ${lowerConfiguration} ${arch} linuxmscorlib"
2219 buildCommands += "build.cmd ${lowerConfiguration} ${arch} osxmscorlib"
2221 if (arch == 'x64') {
2222 buildCommands += "build.cmd ${lowerConfiguration} arm64 linuxmscorlib"
2225 // Zip up the tests directory so that we don't use so much space/time copying
2226 // 10s of thousands of files around.
2227 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')\"";
2229 if (!isJitStressScenario(scenario)) {
2230 // For Windows, pull full test results and test drops for x86/x64.
2231 // No need to pull for stress mode scenarios (downstream builds use the default scenario)
2232 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2235 if (scenario == 'jitdiff') {
2236 // retrieve jit-dasm output for base commit, and run jit-diff
2238 // if this is a build only job, we want to keep the default (build) artifacts for the flow job
2239 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${arch}.${configuration}/dasm/**")
2244 Utilities.addXUnitDotNETResults(newJob, 'bin/**/TestRun*.xml', true)
2250 assert isArmWindowsScenario(scenario)
2254 if (doCoreFxTesting) {
2255 buildOpts += ' skiptests'
2257 buildOpts += " -priority=${priority}"
2260 // This is now a build only job. Do not run tests. Use the flow job.
2261 buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} ${buildOpts}"
2263 if (doCoreFxTesting) {
2266 // Set the stress mode variables; this is incorporated into the generated CoreFx RunTests.cmd files.
2267 def envScriptPath = ''
2268 def buildCommandsStr = ''
2269 envScriptPath = "%WORKSPACE%\\SetStressModes.bat"
2270 buildCommandsStr += envScriptCreate(os, envScriptPath)
2271 buildCommandsStr += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], envScriptPath)
2272 envScriptFinalize(os, envScriptPath)
2273 buildCommands += buildCommandsStr
2275 def workspaceRelativeFxRootLinux = "_/fx"
2276 def workspaceRelativeFxRootWin = "_\\fx"
2277 def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
2278 def fxBranch = getFxBranch(branch)
2280 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"
2282 // Zip up the CoreFx runtime and tests. We don't need the CoreCLR binaries; they have been copied to the CoreFX tree.
2283 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')\"";
2284 buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\tests', '${workspaceRelativeFxRootWin}\\fxtests.zip')\"";
2286 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2287 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2289 // Zip up the tests directory so that we don't use so much space/time copying
2290 // 10s of thousands of files around.
2291 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')\"";
2294 Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
2298 println("Unknown architecture: ${architecture}");
2303 // end case 'Windows_NT'; editor brace matching: }
2312 case 'Fedora24': // editor brace matching: {
2313 switch (architecture) {
2316 if (architecture == 'x86' && os == 'Ubuntu') {
2317 // build and PAL test
2318 def dockerImage = getDockerImageName(architecture, os, true)
2319 buildCommands += "docker run -i --rm -v \${WORKSPACE}:/opt/code -w /opt/code -e ROOTFS_DIR=/crossrootfs/x86 ${dockerImage} ./build.sh ${architecture} cross ${lowerConfiguration}"
2320 dockerImage = getDockerImageName(architecture, os, false)
2321 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"
2322 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2323 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2327 if (scenario == 'formatting') {
2328 buildCommands += "python tests/scripts/format.py -c \${WORKSPACE} -o Linux -a ${architecture}"
2329 Utilities.addArchival(newJob, "format.patch", "", true, false)
2333 if (scenario == 'illink') {
2334 assert(os == 'Ubuntu')
2335 buildCommands += "./tests/scripts/build_illink.sh --clone --arch=${architecture}"
2338 if (!doCoreFxTesting) {
2339 // We run pal tests on all OS but generate mscorlib (and thus, nuget packages)
2340 // only on supported OS platforms.
2341 def bootstrapRid = Utilities.getBoostrapPublishRid(os)
2342 def bootstrapRidEnv = bootstrapRid != null ? "__PUBLISH_RID=${bootstrapRid} " : ''
2344 buildCommands += "${bootstrapRidEnv}./build.sh ${lowerConfiguration} ${architecture}"
2345 buildCommands += "src/pal/tests/palsuite/runpaltests.sh \${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration} \${WORKSPACE}/bin/paltestout"
2347 // Basic archiving of the build
2348 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2350 Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
2353 if (scenario == 'corefx_innerloop') {
2354 assert os == 'Ubuntu' || 'OSX10.12'
2355 assert architecture == 'x64'
2357 buildCommands += "./build.sh ${lowerConfiguration} ${architecture} skiptests"
2358 buildCommands += "./build-test.sh ${lowerConfiguration} ${architecture} generatetesthostonly"
2359 buildCommands += "./tests/runtest.sh --corefxtestsall --testHostDir=\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/testhost/ --coreclr-src=\${WORKSPACE}"
2362 // Archive and process (only) the test results
2363 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
2364 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
2367 // Corefx stress testing
2368 assert os == 'Ubuntu'
2369 assert architecture == 'x64'
2370 assert lowerConfiguration == 'checked'
2371 assert isJitStressScenario(scenario)
2374 buildCommands += "./build.sh ${lowerConfiguration} ${architecture}"
2376 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2378 def envScriptCmds = envScriptCreate(os, scriptFileName)
2379 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2380 envScriptCmds += envScriptFinalize(os, scriptFileName)
2381 buildCommands += envScriptCmds
2383 // Build and text corefx
2384 def workspaceRelativeFxRoot = "_/fx"
2385 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRoot}"
2386 def fxBranch = getFxBranch(branch)
2388 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}"
2390 // Archive and process (only) the test results
2391 Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2392 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
2397 // Emulator cross builds for ARM runs on Tizen currently
2398 assert os == 'Tizen'
2400 def arm_abi = "armel"
2401 def linuxCodeName = "tizen"
2403 // Unzip the Windows test binaries first. Exit with 0
2404 buildCommands += "unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.x64.${configuration} || exit 0"
2406 // Unpack the corefx binaries
2407 buildCommands += "mkdir ./bin/CoreFxBinDir"
2408 buildCommands += "tar -xf ./bin/build.tar.gz -C ./bin/CoreFxBinDir"
2410 // Call the ARM CI script to cross build and test using docker
2411 buildCommands += """./tests/scripts/arm32_ci_script.sh \\
2414 --linuxCodeName=${linuxCodeName} \\
2415 --buildConfig=${lowerConfiguration} \\
2416 --testRootDir=./bin/tests/Windows_NT.x64.${configuration} \\
2417 --coreFxBinDir=./bin/CoreFxBinDir \\
2418 --testDirFile=./tests/testsRunningInsideARM.txt"""
2420 // Basic archiving of the build, no pal tests
2421 Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**/*.dylib,bin/obj/*/tests/**/*.so", "bin/Product/**/.nuget/**")
2425 // Non-Windows ARM cross builds on hardware run on Ubuntu only
2426 assert (os == 'Ubuntu') || (os == 'Ubuntu16.04')
2428 // Add some useful information to the log file. Ignore return codes.
2429 buildCommands += "uname -a || true"
2431 def additionalOpts = ""
2432 if (architecture == 'arm') {
2433 additionalOpts = "-e CAC_ROOTFS_DIR=/crossrootfs/x86"
2436 // Cross build the Ubuntu/arm product using docker with a docker image that contains the correct
2437 // Ubuntu cross-compilation toolset (running on a Ubuntu x64 host).
2438 // For CoreFX testing, we only need the product build; we don't need to generate the layouts. The product
2439 // build is then copied into the corefx layout by the run-corefx-test.py script. For CoreFX testing, we
2440 // ZIP up the generated CoreFX runtime and tests.
2442 def dockerImage = getDockerImageName(architecture, os, true)
2443 def dockerCmd = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} -e ROOTFS_DIR=/crossrootfs/${architecture} ${additionalOpts} ${dockerImage} "
2445 buildCommands += "${dockerCmd}\${WORKSPACE}/build.sh ${lowerConfiguration} ${architecture} cross crosscomponent"
2447 if (doCoreFxTesting) {
2448 def scriptFileName = "\$WORKSPACE/set_stress_test_env.sh"
2450 def envScriptCmds = envScriptCreate(os, scriptFileName)
2451 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
2452 envScriptCmds += envScriptFinalize(os, scriptFileName)
2453 buildCommands += envScriptCmds
2455 // Build and text corefx
2456 def workspaceRelativeFxRootLinux = "_/fx"
2457 def absoluteFxRoot = "\$WORKSPACE/${workspaceRelativeFxRootLinux}"
2458 def fxBranch = getFxBranch(branch)
2460 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"
2462 // Docker creates files with root permission, so we need to zip in docker also, or else we'll get permission errors.
2463 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxruntime.zip ${workspaceRelativeFxRootLinux}/bin/testhost/netcoreapp-Linux-Release-${architecture}"
2464 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeFxRootLinux}/fxtests.zip ${workspaceRelativeFxRootLinux}/bin/tests"
2466 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
2467 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxtests.zip")
2468 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/run-test.sh")
2470 else if (isCrossGenComparisonScenario(scenario)) {
2471 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2473 def workspaceRelativeProductBinDir = "bin/Product/${osGroup}.${architecture}.${configuration}"
2474 def workspaceRelativeCoreLib = "${workspaceRelativeProductBinDir}/IL/System.Private.CoreLib.dll"
2475 def workspaceRelativeCoreRootDir = "bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root"
2476 def workspaceRelativeCrossGenComparisonScript = "tests/scripts/crossgen_comparison.py"
2477 def workspaceRelativeResultsDir = "_"
2478 def workspaceRelativeArtifactsArchive = "${os}.${architecture}.${configuration}.${scenario}.zip"
2479 def crossGenComparisonCmd = "python -u \${WORKSPACE}/${workspaceRelativeCrossGenComparisonScript} "
2480 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
2481 def crossGenExecutable = "\${WORKSPACE}/${workspaceRelativeProductBinDir}/${crossArch}/crossgen"
2482 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
2484 buildCommands += "${dockerCmd}mkdir -p \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2485 buildCommands += "${dockerCmd}${crossGenComparisonCmd}crossgen_corelib --crossgen ${crossGenExecutable} --il_corelib \${WORKSPACE}/${workspaceRelativeCoreLib} --result_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2486 buildCommands += "${dockerCmd}${crossGenComparisonCmd}crossgen_framework --crossgen ${crossGenExecutable} --core_root \${WORKSPACE}/${workspaceRelativeCoreRootDir} --result_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}"
2488 buildCommands += "${dockerCmd}zip -r ${workspaceRelativeArtifactsArchive} ${workspaceRelativeCoreLib} ${workspaceRelativeCoreRootDir} ${workspaceRelativeCrossGenComparisonScript} ${workspaceRelativeResultsDir}"
2489 Utilities.addArchival(newJob, "${workspaceRelativeArtifactsArchive}")
2491 else if (architecture == 'arm') {
2492 // Then, using the same docker image, generate the CORE_ROOT layout using build-test.sh to
2493 // download the appropriate CoreFX packages.
2494 // Note that docker should not be necessary here, for the "generatelayoutonly" case, but we use it
2495 // just to be consistent with the "build.sh" case -- so both are run with the same environment.
2497 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross generatelayoutonly"
2499 // ZIP up for the test job (created in the flow job code):
2500 // (1) the built CORE_ROOT, /home/user/coreclr/bin/tests/Linux.arm.Checked/Tests/Core_Root,
2501 // used by runtest.sh as the "--coreOverlayDir" argument.
2502 // (2) the native parts of the test build: /home/user/coreclr/bin/obj/Linux.arm.Checked/tests,
2503 // used by runtest.sh as the "--testNativeBinDir" argument.
2505 // These commands are assumed to be run from the root of the workspace.
2506 buildCommands += "zip -r coreroot.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root"
2507 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2509 Utilities.addArchival(newJob, "coreroot.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2512 assert architecture == 'arm64'
2514 // Then, using the same docker image, build the tests and generate the CORE_ROOT layout.
2515 // Linux/arm64 does not use Windows-built tests.
2517 def testBuildOpts = ""
2518 if (priority == '1') {
2519 testBuildOpts = "priority1"
2522 buildCommands += "${dockerCmd}\${WORKSPACE}/build-test.sh ${lowerConfiguration} ${architecture} cross ${testBuildOpts}"
2524 // 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)
2525 buildCommands += "zip -r tests.${lowerConfiguration}.zip ./bin/tests/Linux.${architecture}.${configuration}"
2527 // We still use the testnativebin files until they get placed properly in the tests directory (next to their respective tests).
2528 // With https://github.com/dotnet/coreclr/pull/19918 this shouldn't be needed anymore.
2529 buildCommands += "zip -r testnativebin.${lowerConfiguration}.zip ./bin/obj/Linux.${architecture}.${configuration}/tests"
2531 Utilities.addArchival(newJob, "tests.${lowerConfiguration}.zip,testnativebin.${lowerConfiguration}.zip", "")
2534 // Archive the build logs from both product and test builds.
2535 Utilities.addArchival(newJob, "bin/Logs/*.log,bin/Logs/*.wrn,bin/Logs/*.err", "")
2537 // We need to clean up the build machines; the docker build leaves newly built files with root permission, which
2538 // the cleanup task in Jenkins can't remove.
2541 azureVMAgentPostBuildAction {
2542 agentPostBuildAction('Delete agent after build execution (when idle).')
2548 println("Unknown architecture: ${architecture}");
2553 // editor brace matching: }
2555 println("Unknown os: ${os}");
2560 return buildCommands
2563 // Determine if we should generate a job for the given parameters. This is for non-flow jobs: either build and test, or build only.
2564 // Returns true if the job should be generated.
2565 def static shouldGenerateJob(def scenario, def isPR, def architecture, def configuration, def os, def isBuildOnly)
2567 // The various "innerloop" jobs are only available as PR triggered.
2570 if (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked')) {
2571 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
2572 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
2576 if (isInnerloopTestScenario(scenario)) {
2580 if (scenario == 'corefx_innerloop') {
2585 // Tizen is only supported for armem architecture
2586 if (os == 'Tizen' && architecture != 'armem') {
2590 // Filter based on architecture.
2592 switch (architecture) {
2594 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2599 if ((os != 'Windows_NT') && (os != 'Ubuntu16.04')) {
2604 if (os != 'Tizen') {
2608 case 'x86_arm_altjit':
2609 case 'x64_arm64_altjit':
2610 if (os != 'Windows_NT') {
2615 if ((os != 'Windows_NT') && (os != 'Ubuntu')) {
2620 // Everything implemented
2623 println("Unknown architecture: ${architecture}")
2628 // Which (Windows) build only jobs are required?
2630 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
2633 switch (architecture) {
2636 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2637 if (!isCoreFxScenario(scenario)) {
2643 if (!isNormalOrInnerloop) {
2652 // Filter based on scenario.
2654 if (isJitStressScenario(scenario)) {
2655 if (configuration != 'Checked') {
2659 def isEnabledOS = (os == 'Windows_NT') ||
2660 (os == 'Ubuntu' && (architecture == 'x64') && isCoreFxScenario(scenario)) ||
2661 (os == 'Ubuntu' && architecture == 'arm') ||
2662 (os == 'Ubuntu16.04' && architecture == 'arm64')
2667 switch (architecture) {
2669 case 'x86_arm_altjit':
2670 case 'x64_arm64_altjit':
2674 // x86 ubuntu: no stress modes
2675 if (os == 'Ubuntu') {
2682 // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
2683 // No "regular" Windows arm corefx jobs, e.g.
2684 // For Ubuntu arm corefx testing, we use regular jobs (not "build only" since only Windows has "build only", and
2685 // the Ubuntu arm "regular" jobs don't run tests anyway).
2686 if (os == 'Windows_NT') {
2687 if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
2692 if (!isCoreFxScenario(scenario)) {
2699 // armem: no stress jobs for ARM emulator.
2703 else if (isR2RScenario(scenario)) {
2704 if (os != 'Windows_NT') {
2708 if (isR2RBaselineScenario(scenario)) {
2709 // no need for Debug scenario; Checked is sufficient
2710 if (configuration != 'Checked' && configuration != 'Release') {
2714 else if (isR2RStressScenario(scenario)) {
2715 // Stress scenarios only run with Checked builds, not Release (they would work with Debug, but be slow).
2716 if (configuration != 'Checked') {
2721 switch (architecture) {
2724 // Windows arm/arm64 ready-to-run jobs use flow jobs and test jobs, but depend on "normal" (not R2R specific) build jobs.
2731 else if (isCrossGenComparisonScenario(scenario)) {
2732 return shouldGenerateCrossGenComparisonJob(os, architecture, configuration, scenario)
2738 // The ilrt build isn't necessary except for Windows_NT2003. Non-Windows NT uses
2739 // the default scenario build
2740 if (os != 'Windows_NT') {
2744 if (architecture != 'x64') {
2748 if (configuration != 'Release') {
2753 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2756 if (architecture != 'x64') {
2759 if (configuration != 'Checked') {
2765 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2768 if (architecture != 'x64') {
2771 if (configuration != 'Release') {
2775 case 'gc_reliability_framework':
2776 case 'standalone_gc':
2777 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2781 if (architecture != 'x64') {
2785 if (configuration != 'Release' && configuration != 'Checked') {
2789 // We only run Windows and Ubuntu x64 Checked for formatting right now
2791 if (os != 'Windows_NT' && os != 'Ubuntu') {
2794 if (architecture != 'x64') {
2797 if (configuration != 'Checked') {
2802 if (os != 'Windows_NT' && (os != 'Ubuntu' || architecture != 'x64')) {
2805 if (architecture != 'x64' && architecture != 'x86') {
2813 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, isBuildOnly)) {
2817 case 'corefx_innerloop':
2818 if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX10.12') {
2821 if (architecture != 'x64') {
2826 println("Unknown scenario: ${scenario}")
2832 // For altjit, don't do any scenarios that don't change compilation. That is, scenarios that only change
2833 // runtime behavior, not compile-time behavior, are not interesting.
2834 switch (architecture) {
2835 case 'x86_arm_altjit':
2836 case 'x64_arm64_altjit':
2837 if (isGCStressRelatedTesting(scenario)) {
2845 // The job was not filtered out, so we should generate it!
2849 Constants.allScenarios.each { scenario ->
2850 [true, false].each { isPR ->
2851 Constants.architectureList.each { architecture ->
2852 Constants.configurationList.each { configuration ->
2853 Constants.osList.each { os ->
2854 // If the OS is Windows_NT_BuildOnly, set the isBuildOnly flag to true
2855 // and reset the os to Windows_NT
2856 def isBuildOnly = false
2857 if (os == 'Windows_NT_BuildOnly') {
2862 if (!shouldGenerateJob(scenario, isPR, architecture, configuration, os, isBuildOnly)) {
2867 def jobName = getJobName(configuration, architecture, os, scenario, isBuildOnly)
2868 def folderName = getJobFolder(scenario)
2870 // Create the new job
2871 def newJob = job(Utilities.getFullJobName(project, jobName, isPR, folderName)) {}
2873 // 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
2874 // "top-level" jobs. Build only jobs are such jobs.
2877 addToViews(newJob, isPR, architecture, os)
2880 setJobMachineAffinity(architecture, os, true, false, false, newJob) // isBuildJob = true, isTestJob = false, isFlowJob = false
2882 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
2883 addTriggers(newJob, branch, isPR, architecture, os, configuration, scenario, false, isBuildOnly) // isFlowJob==false
2884 setJobTimeout(newJob, isPR, architecture, configuration, scenario, isBuildOnly)
2886 // Copy Windows build test binaries and corefx build artifacts for Linux cross build for armem.
2887 // We don't use a flow job for this, but we do depend on there being existing builds with these
2888 // artifacts produced.
2889 if ((architecture == 'armem') && (os == 'Tizen')) {
2890 // Define the Windows Tests and Corefx build job names
2891 def lowerConfiguration = configuration.toLowerCase()
2892 def WindowsTestsName = projectFolder + '/' +
2893 Utilities.getFullJobName(project,
2894 getJobName(lowerConfiguration, 'x64' , 'windows_nt', 'normal', true),
2896 def fxBranch = getFxBranch(branch)
2897 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' +
2898 Utilities.getFolderName(fxBranch)
2900 def arm_abi = 'armel'
2901 def corefx_os = 'tizen'
2903 // Let's use release CoreFX to test checked CoreCLR,
2904 // because we do not generate checked CoreFX in CoreFX CI yet.
2905 def corefx_lowerConfiguration = lowerConfiguration
2906 if (lowerConfiguration == 'checked') {
2907 corefx_lowerConfiguration = 'release'
2910 // Copy the Windows test binaries and the Corefx build binaries
2913 copyArtifacts(WindowsTestsName) {
2914 includePatterns('bin/tests/tests.zip')
2916 latestSuccessful(true)
2919 copyArtifacts("${corefxFolder}/${corefx_os}_${arm_abi}_cross_${corefx_lowerConfiguration}") {
2920 includePatterns('bin/build.tar.gz')
2922 latestSuccessful(true)
2929 def buildCommands = calculateBuildCommands(newJob, scenario, branch, isPR, architecture, configuration, os, isBuildOnly)
2933 if (os == 'Windows_NT') {
2934 buildCommands.each { buildCommand ->
2935 batchFile(buildCommand)
2939 buildCommands.each { buildCommand ->
2952 // Create a Windows ARM/ARM64 test job that will be used by a flow job.
2953 // Returns the newly created job.
2954 def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
2956 def osGroup = getOSGroup(os)
2957 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
2959 def jobFolder = getJobFolder(scenario)
2960 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
2962 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
2966 // Set up the copies
2968 // Coreclr build we are trying to test
2970 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
2972 copyArtifacts(inputCoreCLRBuildName) {
2973 excludePatterns('**/testResults.xml', '**/*.ni.dll')
2975 buildNumber('${CORECLR_BUILD}')
2979 if (isCoreFxScenario(scenario)) {
2981 // Only arm/arm64 supported for corefx testing now.
2982 assert architecture == 'arm' || architecture == 'arm64'
2984 // Unzip CoreFx runtime
2985 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}')\"")
2987 // Unzip CoreFx tests.
2988 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxtests.zip', '_\\fx\\bin\\tests')\"")
2990 // Add the script to run the corefx tests
2991 def corefx_runtime_path = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}"
2992 def corefx_tests_dir = "%WORKSPACE%\\_\\fx\\bin\\tests"
2993 def corefx_exclusion_file = "%WORKSPACE%\\tests\\${architecture}\\corefx_test_exclusions.txt"
2994 batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file} ${architecture}")
2996 } else { // !isCoreFxScenario(scenario)
2999 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}')\"")
3001 def buildCommands = ""
3003 def coreRootLocation = "%WORKSPACE%\\bin\\tests\\Windows_NT.${architecture}.${configuration}\\Tests\\Core_Root"
3004 def addEnvVariable = { variable, value -> buildCommands += "set ${variable}=${value}\r\n"}
3005 def addCommand = { cmd -> buildCommands += "${cmd}\r\n"}
3007 // Make sure Command Extensions are enabled. Used so %ERRORLEVEL% is available.
3008 addCommand("SETLOCAL ENABLEEXTENSIONS")
3011 addEnvVariable("CORE_ROOT", coreRootLocation)
3012 addEnvVariable("COMPlus_NoGuiOnAssert", "1")
3013 addEnvVariable("COMPlus_ContinueOnAssert", "0")
3015 // If we are running a stress mode, we'll set those variables as well
3016 if (isJitStressScenario(scenario) || isR2RStressScenario(scenario)) {
3017 def stressValues = null
3018 if (isJitStressScenario(scenario)) {
3019 stressValues = Constants.jitStressModeScenarios[scenario]
3022 stressValues = Constants.r2rStressScenarios[scenario]
3025 stressValues.each { key, value ->
3026 addEnvVariable(key, value)
3030 if (isR2RScenario(scenario)) {
3031 // Crossgen the framework assemblies.
3032 buildCommands += """
3033 @for %%F in (%CORE_ROOT%\\*.dll) do @call :PrecompileAssembly "%CORE_ROOT%" "%%F" %%~nxF
3034 @goto skip_PrecompileAssembly
3037 @REM Skip mscorlib since it is already precompiled.
3038 @if /I "%3" == "mscorlib.dll" exit /b 0
3039 @if /I "%3" == "mscorlib.ni.dll" exit /b 0
3041 "%CORE_ROOT%\\crossgen.exe" /Platform_Assemblies_Paths "%CORE_ROOT%" %2 >nul 2>nul
3042 @if "%errorlevel%" == "-2146230517" (
3043 echo %2 is not a managed assembly.
3044 ) else if "%errorlevel%" == "-2146234344" (
3045 echo %2 is not a managed assembly.
3046 ) else if %errorlevel% neq 0 (
3047 echo Unable to precompile %2
3053 :skip_PrecompileAssembly
3056 // Set RunCrossGen variable to cause test wrappers to invoke their logic to run
3057 // crossgen on tests before running them.
3058 addEnvVariable("RunCrossGen", "true")
3059 } // isR2RScenario(scenario)
3061 // Create the smarty command
3062 def smartyCommand = "C:\\Tools\\Smarty.exe /noecid /noie /workers 9 /inc EXPECTED_PASS "
3063 def addSmartyFlag = { flag -> smartyCommand += flag + " "}
3064 def addExclude = { exclude -> addSmartyFlag("/exc " + exclude)}
3065 def addArchSpecificExclude = { architectureToExclude, exclude -> addExclude(exclude) }
3067 // Exclude tests based on scenario.
3068 Constants.validArmWindowsScenarios[scenario].each { excludeTag ->
3069 addArchSpecificExclude(architecture, excludeTag)
3072 if (isInnerloopTestScenario(scenario)) {
3076 // Exclude any test marked LONG_RUNNING; these often exceed the standard timeout and fail as a result.
3077 // TODO: We should create a "long running" job that runs these with a longer timeout.
3078 addExclude("LONG_RUNNING")
3080 smartyCommand += "/lstFile Tests.lst"
3082 def testListArch = [
3087 def archLocation = testListArch[architecture]
3089 addCommand("copy %WORKSPACE%\\tests\\${archLocation}\\Tests.lst bin\\tests\\${osGroup}.${architecture}.${configuration}")
3090 addCommand("pushd bin\\tests\\${osGroup}.${architecture}.${configuration}")
3091 addCommand("${smartyCommand}")
3093 // Save the errorlevel from the smarty command to be used as the errorlevel of this batch file.
3094 // However, we also need to remove all the variables that were set during this batch file, so we
3095 // can run the ZIP powershell command (below) in a clean environment. (We can't run the powershell
3096 // command with the COMPlus_AltJit variables set, for example.) To do that, we do ENDLOCAL as well
3097 // as save the current errorlevel on the same line. This works because CMD evaluates the %errorlevel%
3098 // variable expansion (or any variable expansion on the line) BEFORE it executes the ENDLOCAL command.
3099 // Note that the ENDLOCAL also undoes the pushd command, but we add the popd here for clarity.
3100 addCommand("popd & ENDLOCAL & set __save_smarty_errorlevel=%errorlevel%")
3102 // ZIP up the smarty output, no matter what the smarty result.
3103 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')\"")
3105 addCommand("echo %errorlevel%")
3106 addCommand("dir .\\bin\\tests\\${osGroup}.${architecture}.${configuration}")
3108 // Use the smarty errorlevel as the script errorlevel.
3109 addCommand("exit /b %__save_smarty_errorlevel%")
3111 batchFile(buildCommands)
3112 } // non-corefx testing
3116 if (!isCoreFxScenario(scenario)) {
3117 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0/*.smrt", '', true, false)
3119 // Archive a ZIP file of the entire Smarty.run.0 directory. This is possibly a little too much,
3120 // but there is no easy way to only archive the HTML/TXT files of the failing tests, so we get
3121 // all the passing test info as well. Not necessarily a bad thing, but possibly somewhat large.
3122 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/Smarty.run.0.zip", '', true, false)
3128 // Create a test job not covered by the "Windows ARM" case that will be used by a flow job.
3129 // E.g., non-Windows tests.
3130 // Returns the newly created job.
3131 def static CreateOtherTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3133 def lowerConfiguration = configuration.toLowerCase()
3135 def isUbuntuArm64Job = ((os == "Ubuntu16.04") && (architecture == 'arm64'))
3136 def isUbuntuArm32Job = ((os == "Ubuntu") && (architecture == 'arm'))
3137 def isUbuntuArmJob = isUbuntuArm32Job || isUbuntuArm64Job
3139 def doCoreFxTesting = isCoreFxScenario(scenario)
3141 def workspaceRelativeFxRootLinux = "_/fx" // only used for CoreFX testing
3143 def osGroup = getOSGroup(os)
3144 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3147 def useServerGC = false
3149 // Enable Server GC for Ubuntu PR builds
3150 // REVIEW: why? Does this apply to all architectures? Why only PR?
3151 if (os == 'Ubuntu' && isPR) {
3152 testOpts += ' --useServerGC'
3156 if (isR2RScenario(scenario)) {
3158 testOpts += ' --crossgen --runcrossgentests'
3160 if (scenario == 'r2r_jitstress1') {
3161 testOpts += ' --jitstress=1'
3163 else if (scenario == 'r2r_jitstress2') {
3164 testOpts += ' --jitstress=2'
3166 else if (scenario == 'r2r_jitstress1_tiered') {
3167 testOpts += ' --jitstress=1'
3169 else if (scenario == 'r2r_jitstress2_tiered') {
3170 testOpts += ' --jitstress=2'
3172 else if (scenario == 'r2r_jitstressregs1') {
3173 testOpts += ' --jitstressregs=1'
3175 else if (scenario == 'r2r_jitstressregs2') {
3176 testOpts += ' --jitstressregs=2'
3178 else if (scenario == 'r2r_jitstressregs3') {
3179 testOpts += ' --jitstressregs=3'
3181 else if (scenario == 'r2r_jitstressregs4') {
3182 testOpts += ' --jitstressregs=4'
3184 else if (scenario == 'r2r_jitstressregs8') {
3185 testOpts += ' --jitstressregs=8'
3187 else if (scenario == 'r2r_jitstressregs0x10') {
3188 testOpts += ' --jitstressregs=0x10'
3190 else if (scenario == 'r2r_jitstressregs0x80') {
3191 testOpts += ' --jitstressregs=0x80'
3193 else if (scenario == 'r2r_jitstressregs0x1000') {
3194 testOpts += ' --jitstressregs=0x1000'
3196 else if (scenario == 'r2r_jitminopts') {
3197 testOpts += ' --jitminopts'
3199 else if (scenario == 'r2r_jitforcerelocs') {
3200 testOpts += ' --jitforcerelocs'
3202 else if (scenario == 'r2r_gcstress15') {
3203 testOpts += ' --gcstresslevel=0xF'
3206 else if (scenario == 'jitdiff') {
3207 testOpts += ' --jitdisasm --crossgen'
3209 else if (scenario == 'illink') {
3210 testOpts += ' --link=\$WORKSPACE/linker/linker/bin/netcore_Release/netcoreapp2.0/ubuntu-x64/publish/illink'
3212 else if (isLongGc(scenario)) {
3213 // Long GC tests behave very poorly when they are not
3214 // the only test running (many of them allocate until OOM).
3215 testOpts += ' --sequential'
3217 // A note - runtest.sh does have "--long-gc" and "--gcsimulator" options
3218 // for running long GC and GCSimulator tests, respectively. We don't use them
3219 // here because using a playlist file produces much more readable output on the CI machines
3220 // and reduces running time.
3222 // The Long GC playlist contains all of the tests that are
3223 // going to be run. The GCSimulator playlist contains all of
3224 // the GC simulator tests.
3225 if (scenario == 'longgc') {
3226 testOpts += ' --long-gc --playlist=./tests/longRunningGcTests.txt'
3228 else if (scenario == 'gcsimulator') {
3229 testOpts += ' --gcsimulator --playlist=./tests/gcSimulatorTests.txt'
3232 else if (isGcReliabilityFramework(scenario)) {
3233 testOpts += ' --build-overlay-only'
3235 else if (scenario == 'standalone_gc') {
3236 if (osGroup == 'OSX') {
3237 testOpts += ' --gcname=libclrgc.dylib'
3239 else if (osGroup == 'Linux') {
3240 testOpts += ' --gcname=libclrgc.so'
3243 println("Unexpected OS group: ${osGroup} for os ${os}")
3248 // The ARM Ubuntu corefx test job doesn't depend on a Windows test build, and hence inputTestsBuildName
3249 // will be null in this case.
3251 def jobFolder = getJobFolder(scenario)
3252 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3254 if (inputTestsBuildName != null) {
3255 stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR Windows test binaries from')
3257 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3261 // Set up the copies
3263 // Coreclr build containing the tests and mscorlib
3264 // pri1 jobs still need to copy windows_nt built tests
3265 if (inputTestsBuildName != null) {
3266 copyArtifacts(inputTestsBuildName) {
3267 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3269 buildNumber('${CORECLR_WINDOWS_BUILD}')
3274 // Coreclr build we are trying to test
3276 // ** NOTE ** This will, correctly, overwrite the CORE_ROOT from the Windows test archive
3278 // HACK: the Ubuntu arm64 copyArtifacts Jenkins plug-in is ridiculously slow (45 minutes to
3279 // 1.5 hours for this step). Instead, directly use wget, which is fast (1 minute).
3281 if (!isUbuntuArm64Job) {
3282 copyArtifacts(inputCoreCLRBuildName) {
3283 excludePatterns('**/testResults.xml', '**/*.ni.dll')
3285 buildNumber('${CORECLR_BUILD}')
3290 if (isUbuntuArmJob) {
3291 // Add some useful information to the log file. Ignore return codes.
3292 shell("uname -a || true")
3295 if (isUbuntuArm64Job) {
3296 // Copy the required artifacts directly, using wget, e.g.:
3298 // https://ci.dot.net/job/dotnet_coreclr/job/master/job/arm64_cross_checked_ubuntu16.04_innerloop_prtest/16/artifact/testnativebin.checked.zip
3299 // https://ci.dot.net/job/dotnet_coreclr/job/master/job/arm64_cross_checked_ubuntu16.04_innerloop_prtest/16/artifact/tests.checked.zip
3301 // parameterized as:
3303 // https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/job/${inputJobName}/${CORECLR_BUILD}/artifact/testnativebin.checked.zip
3304 // https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/job/${inputJobName}/${CORECLR_BUILD}/artifact/tests.checked.zip
3306 // CoreFX example artifact URLs:
3308 // 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
3309 // 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
3311 // Note that the source might be in a "jitstress" folder.
3313 // Use `--progress=dot:giga` to display some progress output, but limit it in the log file.
3315 // Use `--directory-prefix=_/fx` to specify where to put the corefx files (to match what other platforms do). Use this instead of `-O`.
3317 shell("echo \"Using wget instead of the Jenkins copy artifacts plug-in to copy artifacts from ${inputCoreCLRBuildName}\"")
3319 def mungedProjectName = Utilities.getFolderName(project)
3320 def mungedBranchName = Utilities.getFolderName(branch)
3322 def doCrossGenComparison = isCrossGenComparisonScenario(scenario)
3323 def inputCoreCLRBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3324 if (doCoreFxTesting || doCrossGenComparison) {
3325 // These depend on unique builds for each scenario
3326 inputCoreCLRBuildScenario = scenario
3328 def sourceJobName = getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, false)
3329 def inputJobName = Utilities.getFullJobName(sourceJobName, isPR)
3331 // Need to add the sub-folder if necessary.
3332 def inputJobPath = "job/${inputJobName}"
3333 def folderName = getJobFolder(inputCoreCLRBuildScenario)
3334 if (folderName != '') {
3335 inputJobPath = "job/${folderName}/job/${inputJobName}"
3338 def inputUrlRoot = "https://ci.dot.net/job/${mungedProjectName}/job/${mungedBranchName}/${inputJobPath}/\${CORECLR_BUILD}/artifact"
3340 if (doCoreFxTesting) {
3341 shell("mkdir -p ${workspaceRelativeFxRootLinux}")
3342 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/fxtests.zip")
3343 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/fxruntime.zip")
3344 shell("wget --progress=dot:giga --directory-prefix=${workspaceRelativeFxRootLinux} ${inputUrlRoot}/${workspaceRelativeFxRootLinux}/run-test.sh")
3345 shell("chmod +x ${workspaceRelativeFxRootLinux}/run-test.sh")
3348 shell("wget --progress=dot:giga ${inputUrlRoot}/testnativebin.${lowerConfiguration}.zip")
3349 shell("wget --progress=dot:giga ${inputUrlRoot}/tests.${lowerConfiguration}.zip")
3353 if (architecture == 'x86') {
3354 shell("mkdir ./bin/CoreFxNative")
3356 def fxBranch = getFxBranch(branch)
3357 def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' + Utilities.getFolderName(fxBranch)
3359 copyArtifacts("${corefxFolder}/ubuntu16.04_x86_release") {
3360 includePatterns('bin/build.tar.gz')
3361 targetDirectory('bin/CoreFxNative')
3363 latestSuccessful(true)
3367 shell("mkdir ./bin/CoreFxBinDir")
3368 shell("tar -xf ./bin/CoreFxNative/bin/build.tar.gz -C ./bin/CoreFxBinDir")
3371 // CoreFX testing downloads the CoreFX tests, not the coreclr tests. Also, unzip the built CoreFX layout/runtime directories.
3372 if (doCoreFxTesting) {
3373 shell("unzip -q -o ${workspaceRelativeFxRootLinux}/fxtests.zip || exit 0")
3374 shell("unzip -q -o ${workspaceRelativeFxRootLinux}/fxruntime.zip || exit 0")
3376 else if (architecture != 'arm64') {
3377 // ARM64 copies the tests from the build machine; this is for unzip'ing tests copied from a Windows build.
3379 // Unzip the tests first. Exit with 0
3380 shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/${osGroup}.${architecture}.${configuration} || exit 0")
3381 shell("rm -r ./bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root || exit 0")
3384 // For arm Ubuntu (on hardware), we do the "build-test" step on the build machine, not on the test
3385 // machine. The arm Ubuntu test machines do no building -- they have no CLI, for example.
3386 // We should probably do the "generatelayoutonly" step on the build machine for all architectures.
3387 // However, it's believed that perhaps there's an issue with executable permission bits not getting
3388 // copied correctly.
3389 if (!doCoreFxTesting) {
3390 if (isUbuntuArmJob) {
3391 if (architecture == 'arm') {
3392 shell("unzip -q -o ./coreroot.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}/Tests/Core_Root
3393 shell("unzip -q -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3396 assert architecture == 'arm64'
3397 shell("unzip -q -o ./tests.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/tests/Linux.${architecture}.${configuration}
3399 // We still the testnativebin files until they get placed properly in the tests directory (next to their respective tests).
3400 shell("unzip -q -o ./testnativebin.${lowerConfiguration}.zip || exit 0") // unzips to ./bin/obj/Linux.${architecture}.${configuration}/tests
3404 shell("./build-test.sh ${architecture} ${configuration} generatelayoutonly")
3408 // Execute the tests
3409 def runDocker = isNeedDocker(architecture, os, false)
3410 def dockerPrefix = ""
3413 def dockerImage = getDockerImageName(architecture, os, false)
3414 dockerPrefix = "docker run -i --rm -v \${WORKSPACE}:\${WORKSPACE} -w \${WORKSPACE} "
3415 dockerCmd = dockerPrefix + "${dockerImage} "
3418 // If we are running a stress mode, we'll set those variables first.
3419 // For CoreFX, the stress variables are already built into the CoreFX test build per-test wrappers.
3420 if (!doCoreFxTesting && isJitStressScenario(scenario)) {
3421 def scriptFileName = "\${WORKSPACE}/set_stress_test_env.sh"
3422 def envScriptCmds = envScriptCreate(os, scriptFileName)
3423 envScriptCmds += envScriptSetStressModeVariables(os, Constants.jitStressModeScenarios[scenario], scriptFileName)
3424 envScriptCmds += envScriptFinalize(os, scriptFileName)
3425 shell("${envScriptCmds}")
3426 testOpts += " --test-env=${scriptFileName}"
3429 // setup-stress-dependencies.sh, invoked by runtest.sh to download the coredistools package, depends on the "dotnet"
3430 // tool downloaded by the "init-tools.sh" script. However, it only invokes setup-stress-dependencies.sh for x64. The
3431 // coredistools package is used by GCStress on x86 and x64 to disassemble code to determine instruction boundaries.
3432 // On arm/arm64, it is not required as determining instruction boundaries is trivial.
3433 if (isGCStressRelatedTesting(scenario)) {
3434 if (architecture == 'x64') {
3435 shell('./init-tools.sh')
3439 if (doCoreFxTesting) {
3441 \${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""")
3444 def runScript = "${dockerCmd}./tests/runtest.sh"
3446 // TODO: the testNativeBinDir shouldn't be necessary if the native test binaries are placed properly with their corresponding managed test code.
3450 --testRootDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}\" \\
3451 --coreOverlayDir=\"\${WORKSPACE}/bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root\" \\
3452 --testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
3453 --copyNativeTestBin --limitedDumpGeneration ${testOpts}""")
3456 if (isGcReliabilityFramework(scenario)) {
3457 // runtest.sh doesn't actually execute the reliability framework - do it here.
3460 dockerCmd = dockerPrefix + "-e COMPlus_gcServer=1 ${dockerImage} "
3463 shell("export COMPlus_gcServer=1")
3467 shell("${dockerCmd}./tests/scripts/run-gc-reliability-framework.sh ${architecture} ${configuration}")
3472 // Experimental: If on Ubuntu 14.04, then attempt to pull in crash dump links
3473 if (os in ['Ubuntu']) {
3474 SummaryBuilder summaries = new SummaryBuilder()
3475 summaries.addLinksSummaryFromFile('Crash dumps from this run:', 'dumplings.txt')
3476 summaries.emit(newJob)
3479 if (doCoreFxTesting) {
3480 Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3481 if ((os == "Ubuntu") && (architecture == 'arm')) {
3482 // We have a problem with the xunit plug-in, where it is consistently failing on Ubuntu arm32 test result uploading with this error:
3484 // [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
3486 // We haven't been able to identify the reason. So, do not add xunit parsing of the test data in this scenario.
3487 // This is tracked by: https://github.com/dotnet/coreclr/issues/19447.
3490 Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRootLinux}/bin/**/testResults.xml")
3494 Utilities.addXUnitDotNETResults(newJob, '**/coreclrtests.xml')
3500 def static CreateNonWindowsCrossGenComparisonTestJob(def dslFactory, def project, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName)
3502 assert isCrossGenComparisonScenario(scenario)
3504 def osGroup = getOSGroup(os)
3505 def jobName = getJobName(configuration, architecture, os, scenario, false) + "_tst"
3507 def workspaceRelativeResultsDir = "_"
3508 def workspaceRelativeNativeArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${architecture}_${architecture}.${configuration}"
3510 def jobFolder = getJobFolder(scenario)
3511 def newJob = dslFactory.job(Utilities.getFullJobName(project, jobName, isPR, jobFolder)) {
3513 stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
3516 def workspaceRelativeArtifactsArchive = "${os}.${architecture}.${configuration}.${scenario}.zip"
3519 copyArtifacts(inputCoreCLRBuildName) {
3520 includePatterns("${workspaceRelativeArtifactsArchive}")
3522 buildNumber('${CORECLR_BUILD}')
3526 shell("unzip -o ${workspaceRelativeArtifactsArchive} || exit 0")
3528 def workspaceRelativeCoreLib = "bin/Product/${osGroup}.${architecture}.${configuration}/IL/System.Private.CoreLib.dll"
3529 def workspaceRelativeCoreRootDir = "bin/tests/${osGroup}.${architecture}.${configuration}/Tests/Core_Root"
3530 def workspaceRelativeCrossGenComparisonScript = "tests/scripts/crossgen_comparison.py"
3531 def workspaceRelativeCrossGenExecutable = "${workspaceRelativeCoreRootDir}/crossgen"
3533 def crossGenComparisonCmd = "python -u \${WORKSPACE}/${workspaceRelativeCrossGenComparisonScript} "
3534 def crossGenExecutable = "\${WORKSPACE}/${workspaceRelativeCrossGenExecutable}"
3536 shell("mkdir -p ${workspaceRelativeNativeArchResultDir}")
3537 shell("${crossGenComparisonCmd}crossgen_corelib --crossgen ${crossGenExecutable} --il_corelib \${WORKSPACE}/${workspaceRelativeCoreLib} --result_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir}")
3538 shell("${crossGenComparisonCmd}crossgen_framework --crossgen ${crossGenExecutable} --core_root \${WORKSPACE}/${workspaceRelativeCoreRootDir} --result_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir}")
3540 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
3541 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
3542 shell("${crossGenComparisonCmd}compare --base_dir \${WORKSPACE}/${workspaceRelativeNativeArchResultDir} --diff_dir \${WORKSPACE}/${workspaceRelativeCrossArchResultDir}")
3547 Utilities.addArchival(newJob, "${workspaceRelativeNativeArchResultDir}/**")
3548 getCrossArchitectures(os, architecture, scenario).each{ crossArch ->
3549 def workspaceRelativeCrossArchResultDir = "${workspaceRelativeResultsDir}/${osGroup}.${crossArch}_${architecture}.${configuration}"
3550 Utilities.addArchival(newJob, "${workspaceRelativeCrossArchResultDir}/**")
3556 // Create a test job that will be used by a flow job.
3557 // Returns the newly created job.
3558 // 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,
3559 // and we want the views to be the minimal set of "top-level" jobs that represent all work.
3560 def static CreateTestJob(def dslFactory, def project, def branch, def architecture, def os, def configuration, def scenario, def isPR, def inputCoreCLRBuildName, def inputTestsBuildName)
3562 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3565 if (windowsArmJob) {
3566 assert inputTestsBuildName == null
3567 newJob = CreateWindowsArmTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3569 else if (isCrossGenComparisonScenario(scenario)) {
3570 assert inputTestsBuildName == null
3571 newJob = CreateNonWindowsCrossGenComparisonTestJob(dslFactory, project, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName)
3574 newJob = CreateOtherTestJob(dslFactory, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3577 setJobMachineAffinity(architecture, os, false, true, false, newJob) // isBuildJob = false, isTestJob = true, isFlowJob = false
3579 if (scenario == 'jitdiff') {
3580 def osGroup = getOSGroup(os)
3581 Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/dasm/**")
3584 Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
3585 setJobTimeout(newJob, isPR, architecture, configuration, scenario, false)
3590 // Create a flow job to tie together a build job with the given test job.
3591 // The 'inputTestsBuildName' argument might be null if the flow job doesn't depend on a Windows build job.
3592 // Returns the new flow job.
3593 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)
3595 // Windows CoreCLR build and Linux CoreCLR build (in parallel) ->
3596 // Linux CoreCLR test
3597 def flowJobName = getJobName(configuration, architecture, os, scenario, false) + "_flow"
3598 def jobFolder = getJobFolder(scenario)
3600 def newFlowJob = null
3602 if (inputTestsBuildName == null) {
3603 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3605 coreclrBuildJob = build(params, '${inputCoreCLRBuildName}')
3607 // And then build the test build
3608 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number], '${fullTestJobName}')
3611 JobReport.Report.addReference(inputCoreCLRBuildName)
3612 JobReport.Report.addReference(fullTestJobName)
3615 newFlowJob = dslFactory.buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR, jobFolder)) {
3617 // Build the input jobs in parallel
3619 { coreclrBuildJob = build(params, '${inputCoreCLRBuildName}') },
3620 { windowsBuildJob = build(params, '${inputTestsBuildName}') }
3623 // And then build the test build
3624 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number,
3625 CORECLR_WINDOWS_BUILD: windowsBuildJob.build.number], '${fullTestJobName}')
3628 JobReport.Report.addReference(inputCoreCLRBuildName)
3629 JobReport.Report.addReference(inputTestsBuildName)
3630 JobReport.Report.addReference(fullTestJobName)
3633 addToViews(newFlowJob, isPR, architecture, os)
3635 setJobMachineAffinity(architecture, os, false, false, true, newFlowJob) // isBuildJob = false, isTestJob = false, isFlowJob = true
3637 Utilities.standardJobSetup(newFlowJob, project, isPR, "*/${branch}")
3638 addTriggers(newFlowJob, branch, isPR, architecture, os, configuration, scenario, true, false) // isFlowJob==true, isWindowsBuildOnlyJob==false
3643 // Determine if we should generate a flow job for the given parameters.
3644 // Returns true if the job should be generated.
3645 def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def configuration, def os)
3647 // The various "innerloop" jobs are only available as PR triggered.
3650 if (isInnerloopTestScenario(scenario) && (architecture == 'arm64') && (os == 'Ubuntu16.04') && (configuration == 'Checked')) {
3651 // TEMPORARY: make arm64 Linux innerloop jobs push jobs, not default triggered jobs, until we have experience
3652 // with the machines running these jobs (and the jobs themselves), to understand how robust they are.
3656 if (isInnerloopTestScenario(scenario)) {
3660 if (scenario == 'corefx_innerloop') {
3665 // Filter based on OS and architecture.
3667 switch (architecture) {
3669 if (os != "Ubuntu" && os != "Windows_NT") {
3674 if (os != "Ubuntu16.04" && os != "Windows_NT") {
3679 if (os != "Ubuntu") {
3684 if (!(os in Constants.crossList)) {
3687 if (os == "Windows_NT") {
3692 case 'x86_arm_altjit':
3693 case 'x64_arm64_altjit':
3697 println("Unknown architecture: ${architecture}")
3702 def isNormalOrInnerloop = (scenario == 'innerloop' || scenario == 'normal')
3704 // Filter based on scenario in OS.
3706 if (os == 'Windows_NT') {
3707 assert architecture == 'arm' || architecture == 'arm64'
3708 if (!isArmWindowsScenario(scenario)) {
3711 if (isNormalOrInnerloop && (configuration == 'Debug')) {
3712 // The arm32/arm64 Debug configuration for innerloop/normal scenario is a special case: it does a build only, and no test run.
3713 // To do that, it doesn't require a flow job.
3719 if (architecture == 'arm') {
3720 if (!(scenario in Constants.validLinuxArmScenarios)) {
3724 else if (architecture == 'arm64') {
3725 if (!(scenario in Constants.validLinuxArm64Scenarios)) {
3729 else if (architecture == 'x86') {
3730 // Linux/x86 only want innerloop and default test
3731 if (!isNormalOrInnerloop) {
3735 else if (architecture == 'x64') {
3736 // Linux/x64 corefx testing doesn't need a flow job; the "build" job runs run-corefx-tests.py which
3737 // builds and runs the corefx tests. Other Linux/x64 flow jobs are required to get the test
3738 // build from a Windows machine.
3739 if (isCoreFxScenario(scenario)) {
3745 // For CentOS, we only want Checked/Release builds.
3746 if (os == 'CentOS7.1') {
3747 if (configuration != 'Checked' && configuration != 'Release') {
3750 if (!isNormalOrInnerloop && !isR2RScenario(scenario)) {
3755 // For RedHat and Debian, we only do Release builds.
3756 else if (os == 'RHEL7.2' || os == 'Debian8.4') {
3757 if (configuration != 'Release') {
3760 if (!isNormalOrInnerloop) {
3765 // Next, filter based on scenario.
3767 if (isJitStressScenario(scenario)) {
3768 if (configuration != 'Checked') {
3772 else if (isR2RBaselineScenario(scenario)) {
3773 if (configuration != 'Checked' && configuration != 'Release') {
3777 else if (isR2RStressScenario(scenario)) {
3778 if (configuration != 'Checked') {
3782 else if (isCrossGenComparisonScenario(scenario)) {
3783 return shouldGenerateCrossGenComparisonJob(os, architecture, configuration, scenario)
3791 // Long GC tests take a long time on non-Release builds
3792 // ilrt is also Release only
3793 if (configuration != 'Release') {
3799 if (configuration != 'Checked') {
3804 case 'gc_reliability_framework':
3805 case 'standalone_gc':
3806 if (configuration != 'Release' && configuration != 'Checked') {
3815 if (os != 'Windows_NT' && os != 'Ubuntu') {
3825 if (!isValidPrTriggeredInnerLoopJob(os, architecture, configuration, false)) {
3830 case 'corefx_innerloop':
3831 // No flow job needed
3835 println("Unknown scenario: ${scenario}")
3841 // The job was not filtered out, so we should generate it!
3845 // Create jobs requiring flow jobs. This includes x64 non-Windows, arm/arm64 Ubuntu, and arm/arm64 Windows.
3846 Constants.allScenarios.each { scenario ->
3847 [true, false].each { isPR ->
3848 Constants.architectureList.each { architecture ->
3849 Constants.configurationList.each { configuration ->
3850 Constants.osList.each { os ->
3852 if (!shouldGenerateFlowJob(scenario, isPR, architecture, configuration, os)) {
3856 def windowsArmJob = ((os == "Windows_NT") && (architecture in Constants.armWindowsCrossArchitectureList))
3857 def doCoreFxTesting = isCoreFxScenario(scenario)
3858 def doCrossGenComparison = isCrossGenComparisonScenario(scenario)
3860 // Figure out the job name of the CoreCLR build the test will depend on.
3862 def inputCoreCLRBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3863 def inputCoreCLRBuildIsBuildOnly = false
3864 if (doCoreFxTesting) {
3865 // Every CoreFx test depends on its own unique build.
3866 inputCoreCLRBuildScenario = scenario
3867 if (windowsArmJob) {
3868 // Only Windows ARM corefx jobs use "build only" jobs. Others, such as Ubuntu ARM corefx, use "regular" jobs.
3869 inputCoreCLRBuildIsBuildOnly = true
3872 if (doCrossGenComparison) {
3873 inputCoreCLRBuildScenario = scenario
3876 def inputCoreCLRFolderName = getJobFolder(inputCoreCLRBuildScenario)
3877 def inputCoreCLRBuildName = projectFolder + '/' +
3878 Utilities.getFullJobName(project, getJobName(configuration, architecture, os, inputCoreCLRBuildScenario, inputCoreCLRBuildIsBuildOnly), isPR, inputCoreCLRFolderName)
3880 // Figure out the name of the build job that the test job will depend on.
3881 // For Windows ARM tests, this is not used, as the CoreCLR build creates the tests. For other
3882 // tests (e.g., Linux ARM), we depend on a Windows build to get the tests.
3883 // For CoreFX tests, however, Linux doesn't need the Windows build for the tests, since the
3884 // CoreFX build creates the tests.
3886 def inputTestsBuildName = null
3888 // Ubuntu Arm64 jobs do the test build on the build machine, and thus don't depend on a Windows build.
3889 def isUbuntuArm64Job = ((os == "Ubuntu16.04") && (architecture == 'arm64'))
3891 if (!windowsArmJob && !doCoreFxTesting & !doCrossGenComparison && !isUbuntuArm64Job) {
3892 def testBuildScenario = isInnerloopTestScenario(scenario) ? 'innerloop' : 'normal'
3894 def inputTestsBuildArch = architecture
3895 if (architecture == "arm") {
3896 // Use the x86 test build for arm unix
3897 inputTestsBuildArch = "x86"
3900 def inputTestsBuildIsBuildOnly = true
3902 inputTestsBuildName = projectFolder + '/' +
3903 Utilities.getFullJobName(project, getJobName(configuration, inputTestsBuildArch, 'windows_nt', testBuildScenario, inputTestsBuildIsBuildOnly), isPR)
3906 // =============================================================================================
3907 // Create the test job
3908 // =============================================================================================
3910 def testJob = CreateTestJob(this, project, branch, architecture, os, configuration, scenario, isPR, inputCoreCLRBuildName, inputTestsBuildName)
3912 // =============================================================================================
3913 // Create a build flow to join together the build and tests required to run this test.
3914 // =============================================================================================
3916 if (os == 'RHEL7.2' || os == 'Debian8.4') {
3917 // Do not create the flow job for RHEL jobs.
3921 def fullTestJobName = projectFolder + '/' + testJob.name
3922 def flowJob = CreateFlowJob(this, project, branch, architecture, os, configuration, scenario, isPR, fullTestJobName, inputCoreCLRBuildName, inputTestsBuildName)
3930 JobReport.Report.generateJobReport(out)
3932 // Make the call to generate the help job
3933 Utilities.createHelperJob(this, project, branch,
3934 "Welcome to the ${project} Repository", // This is prepended to the help message
3935 "Have a nice day!") // This is appended to the help message. You might put known issues here.
3937 Utilities.addCROSSCheck(this, project, branch)