Merge pull request #3244 from erozenfeld/SIMDInit
[platform/upstream/coreclr.git] / netci.groovy
1 // Import the utility functionality.
2
3 import jobs.generation.Utilities;
4
5 def project = GithubProject
6                        
7 def static getOSGroup(def os) {
8     def osGroupMap = ['Ubuntu':'Linux',
9         'RHEL7.2': 'Linux',
10         'Ubuntu15.10': 'Linux',
11         'Debian8.2':'Linux',
12         'OSX':'OSX',
13         'Windows_NT':'Windows_NT',
14         'FreeBSD':'FreeBSD',
15         'CentOS7.1': 'Linux',
16         'OpenSUSE13.2': 'Linux']
17     def osGroup = osGroupMap.get(os, null) 
18     assert osGroup != null : "Could not find os group for ${os}"
19     return osGroupMap[os]
20 }
21
22 def static getFullBranchName(def branch) {
23     def branchMap = ['master':'*/master',
24         'rc2':'*/release/1.0.0-rc2',
25         'pr':'*/master']
26     def fullBranchName = branchMap.get(branch, null)
27     assert fullBranchName != null : "Could not find a full branch name for ${branch}"
28     return branchMap[branch]
29 }
30
31 // We use this class (vs variables) so that the static functions can access data here.
32 class Constants {
33     // Innerloop build OS's
34     // The Windows_NT_BuildOnly OS is a way to speed up the Non-NT builds temporarily by avoiding
35     // test execution in the build flow runs.  It generates the exact same build
36     // as Windows_NT but without the tests.
37     def static osList = ['Ubuntu', 'Debian8.2', 'OSX', 'Windows_NT', 'Windows_NT_BuildOnly', 'FreeBSD', 'CentOS7.1', 'OpenSUSE13.2', 'Ubuntu15.10', 'RHEL7.2']
38     def static crossList = ['Ubuntu', 'OSX']
39     // This is a set of JIT stress modes combined with the set of variables that
40     // need to be set to actually enable that stress mode.  The key of the map is the stress mode and
41     // the values are the environment variables
42     def static jitStressModeScenarios = ['minopts' : ['COMPlus_JitMinOpts' : '1'], 'forcerelocs' : ['COMPlus_ForceRelocs' : '1'],
43                'jitstress1' : ['COMPlus_JitStress' : '1'], 'jitstress2' : ['COMPlus_JitStress' : '2'],
44                'jitstressregs1' : ['COMPlus_JitStressRegs' : '1'], 'jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
45                'jitstressregs3' : ['COMPlus_JitStressRegs' : '3'], 'jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
46                'jitstressregs8' : ['COMPlus_JitStressRegs' : '8'], 'jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
47                'jitstressregs0x80' : ['COMPlus_JitStressRegs' : '0x80'],
48                'jitstress2_jitstressregs1'    : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '1'],
49                'jitstress2_jitstressregs2'    : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '2'],
50                'jitstress2_jitstressregs3'    : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '3'],
51                'jitstress2_jitstressregs4'    : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '4'],
52                'jitstress2_jitstressregs8'    : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '8'],
53                'jitstress2_jitstressregs0x10' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x10'],
54                'jitstress2_jitstressregs0x80' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x80'],
55                'corefx_baseline' : ['' : ''], // corefx baseline
56                'corefx_minopts' : ['COMPlus_JitMinOpts' : '1'],
57                'corefx_jitstress1' : ['COMPlus_JitStress' : '1'], 
58                'corefx_jitstress2' : ['COMPlus_JitStress' : '2'],
59                'corefx_jitstressregs1' : ['COMPlus_JitStressRegs' : '1'], 'corefx_jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
60                'corefx_jitstressregs3' : ['COMPlus_JitStressRegs' : '3'], 'corefx_jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
61                'corefx_jitstressregs8' : ['COMPlus_JitStressRegs' : '8'], 'corefx_jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
62                'corefx_jitstressregs0x80' : ['COMPlus_JitStressRegs' : '0x80']]
63     // This is the basic set of scenarios
64     def static basicScenarios = ['default', 'pri1', 'ilrt']
65     // This is the set of configurations
66     def static configurationList = ['Debug', 'Checked', 'Release']
67     // This is the set of architectures
68     def static architectureList = ['arm', 'arm64', 'x64', 'x86']
69     // This is the set of branches
70     def static branchList = ['master', 'rc2', 'pr']
71 }
72
73 def static setMachineAffinity(def job, def os, def architecture) {
74     if (architecture == 'arm64' && os == 'Windows_NT') {
75         // For cross compilation
76         job.with {
77             label('arm64')
78         }
79     } else {
80         return Utilities.setMachineAffinity(job, os, 'latest-or-auto');
81     }
82 }
83
84 def static isCorefxTesting(def scenario) {
85     def corefx_prefix = 'corefx_'
86     if (scenario.length() < corefx_prefix.length()) {
87         return
88     }
89     return scenario.substring(0,corefx_prefix.length()) == corefx_prefix
90 }
91
92 def static getStressModeDisplayName(def scenario) {
93     def displayStr = ''
94     Constants.jitStressModeScenarios[scenario].each{ k, v -> 
95         def prefixLength = 'COMPlus_'.length()
96         if (k.length() >= prefixLength) {
97             def modeName = k.substring(prefixLength, k.length())
98             displayStr += ' ' + modeName + '=' + v
99         }
100     }   
101     return displayStr
102 }
103
104
105 // Generates the string for creating a file that sets environment variables
106 // that makes it possible to run stress modes.  Writes the script to a file called
107 // SetStressModes.[sh/cmd]
108 def static genStressModeScriptStep(def os, def stressModeName, def stressModeVars, def stepScriptLocation) {
109     def stepScript = ''
110     if (os == 'Windows_NT') {
111         stepScript += "echo Creating TestEnv Script for ${stressModeName}\r\n"
112         stepScript += "del ${stepScriptLocation}\r\n"
113         stressModeVars.each{ k, v -> 
114             // Write out what we are writing to the script file
115             stepScript += "echo Setting ${k}=${v}\r\n"
116             // Write out the set itself to the script file`
117             stepScript += "echo set ${k}=${v} >> ${stepScriptLocation}\r\n"
118         }
119     }
120     else {
121         // For these we don't use a script, we use directly
122         stepScript += "echo Setting variables for ${stressModeName}\n"
123         stressModeVars.each{ k, v -> 
124             // Write out what we are writing to the script file
125             stepScript += "echo Setting ${k}=${v}\n"
126             // Write out the set itself to the script file`
127             stepScript += "export ${k}=${v}\n"
128         }
129     }
130     return stepScript
131 }
132
133 // Calculates the name of the build job based on some typical parameters.
134 //
135 def static getJobName(def configuration, def architecture, def os, def scenario, def isBuildOnly, def branchName) {
136     // If the architecture is x64, do not add that info into the build name.
137     // Need to change around some systems and other builds to pick up the right builds
138     // to do that.
139     
140     def suffix = scenario != 'default' ? "_${scenario}" : '';
141     if (isBuildOnly) {
142         suffix += '_bld'
143     }
144     if (branchName == 'rc2'){
145         suffix += '_rc2'
146     }
147     def baseName = ''
148     switch (architecture) {
149         case 'x64':
150             if (scenario == 'default') {
151                 // For now we leave x64 off of the name for compatibility with other jobs
152                 baseName = configuration.toLowerCase() + '_' + os.toLowerCase()
153             }
154             else {
155                 baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
156             }
157             break
158         case 'arm64':
159         case 'arm':
160             // These are cross builds
161             baseName = architecture.toLowerCase() + '_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
162             break
163         case 'x86':
164             baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
165             break
166         default:
167             println("Unknown architecture: ${architecture}");
168             assert false
169             break
170     }
171     
172     return baseName + suffix
173 }
174
175 // **************************
176 // Define the basic inner loop builds for PR and commit.  This is basically just the set
177 // of coreclr builds over linux/osx/freebsd/windows and debug/release/checked.  In addition, the windows
178 // builds will do a couple extra steps.
179 // **************************
180
181 // Adds a trigger for the PR build if one is needed.  If isFlowJob is true, then this is the
182 // flow job that rolls up the build and test for non-windows OS's
183 def static addTriggers(def job, def isPR, def architecture, def os, def configuration, def scenario, def isFlowJob) {
184     // Non pull request builds.
185     if (!isPR) {
186         // Check scenario.
187         switch (scenario) {
188             case 'default':
189                 switch (architecture)
190                 {
191                     case 'x64':
192                     case 'x86':
193                         if (isFlowJob || os == 'Windows_NT' || !(os in Constants.crossList)) {
194                             Utilities.addGithubPushTrigger(job)
195                         }
196                         break
197                     case 'arm':
198                     case 'arm64':
199                         Utilities.addGithubPushTrigger(job)
200                         break
201                     default:
202                         println("Unknown architecture: ${architecture}");
203                         assert false
204                         break
205                 }
206                 break
207             case 'pri1':
208                 // Pri one gets a push trigger, and only for release
209                 if (architecture == 'x64' && configuration == 'Release') {
210                     // We don't expect to see a job generated except in these scenarios
211                     assert (os == 'Windows_NT') || (os in Constants.crossList)
212                     if (isFlowJob || os == 'Windows_NT') {
213                         Utilities.addGithubPushTrigger(job)
214                     }
215                 }
216                 break
217             case 'ilrt':
218                 // ILASM/ILDASM roundtrip one gets a daily build, and only for release
219                 if (architecture == 'x64' && configuration == 'Release') {
220                     // We don't expect to see a job generated except in these scenarios
221                     assert (os == 'Windows_NT') || (os in Constants.crossList)
222                     if (isFlowJob || os == 'Windows_NT') {
223                         Utilities.addPeriodicTrigger(job, '@daily')
224                     }
225                 }
226                 break
227             case 'jitstressregs1':
228             case 'jitstressregs2':
229             case 'jitstressregs3':
230             case 'jitstressregs4':
231             case 'jitstressregs8':
232             case 'jitstressregs0x10':
233             case 'jitstressregs0x80':
234             case 'minopts':
235             case 'forcerelocs':
236             case 'jitstress1':
237             case 'jitstress2':   
238             case 'jitstress2_jitstressregs1':
239             case 'jitstress2_jitstressregs2':
240             case 'jitstress2_jitstressregs3':
241             case 'jitstress2_jitstressregs4':
242             case 'jitstress2_jitstressregs8':
243             case 'jitstress2_jitstressregs0x10':
244             case 'jitstress2_jitstressregs0x80':
245             case 'corefx_baseline': 
246             case 'corefx_minopts':
247             case 'corefx_jitstress1':               
248             case 'corefx_jitstress2':
249             case 'corefx_jitstressregs1':
250             case 'corefx_jitstressregs2':
251             case 'corefx_jitstressregs3':
252             case 'corefx_jitstressregs4':
253             case 'corefx_jitstressregs8':
254             case 'corefx_jitstressregs0x10':
255             case 'corefx_jitstressregs0x80':
256                 assert (os == 'Windows_NT') || (os in Constants.crossList)
257                 Utilities.addPeriodicTrigger(job, '@daily')
258                 break
259             default:
260                 println("Unknown scenario: ${scenario}");
261                 assert false
262                 break
263         }
264         return
265     }
266     // Pull request builds.  Generally these fall into two categories: default triggers and on-demand triggers
267     // We generally only have a distinct set of default triggers but a bunch of on-demand ones.
268     def osGroup = getOSGroup(os)
269     switch (architecture) {
270         case 'x64':
271             switch (os) {
272                 case 'OpenSUSE13.2':
273                     assert !isFlowJob
274                     assert scenario == 'default'
275                     Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build", '(?i).*test\\W+suse.*')
276                     break
277                 case 'Debian8.2':
278                     assert !isFlowJob
279                     assert scenario == 'default'
280                     Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build", '(?i).*test\\W+debian.*')
281                     break
282                 case 'Ubuntu15.10':
283                     assert !isFlowJob
284                     assert scenario == 'default'
285                     Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build", '(?i).*test\\W+Ubuntu15\\.10.*')
286                     break
287                 case 'RHEL7.2':
288                     assert !isFlowJob
289                     assert scenario == 'default'
290                     Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build", '(?i).*test\\W+RHEL7\\.2.*')
291                     break
292                 case 'Ubuntu':
293                 case 'OSX':
294                     // Triggers on the non-flow jobs aren't necessary here
295                     // Corefx testing uses non-flow jobs.
296                     if (!isFlowJob && !isCorefxTesting(scenario)) {
297                         break
298                     }
299                     switch (scenario) {
300                         case 'default':
301                             // Ubuntu uses checked for default PR tests
302                             if (configuration == 'Checked') {
303                                 // Default trigger
304                                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test")
305                             }
306                             break
307                         case 'pri1':
308                             if (configuration == 'Release') {
309                                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Priority 1 Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
310                             }
311                             break
312                         case 'ilrt':
313                             if (configuration == 'Release') {
314                                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
315                             }
316                             break
317                         case 'minopts':
318                             assert (os == 'Windows_NT') || (os in Constants.crossList)
319                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - MinOpts)",
320                                "(?i).*test\\W+${os}\\W+${scenario}.*")
321                             break
322                         case 'jitstress1':
323                             assert (os == 'Windows_NT') || (os in Constants.crossList)
324                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStress=1)",
325                                "(?i).*test\\W+${os}\\W+${scenario}.*")
326                             break
327                         case 'jitstress2':
328                             assert (os == 'Windows_NT') || (os in Constants.crossList)
329                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStress=2)",
330                                "(?i).*test\\W+${os}\\W+${scenario}.*")
331                             break                           
332                         case 'forcerelocs':
333                             assert (os == 'Windows_NT') || (os in Constants.crossList)
334                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - ForceRelocs)",
335                                "(?i).*test\\W+${os}\\W+${scenario}.*")
336                         case 'jitstressregs1':
337                             assert (os == 'Windows_NT') || (os in Constants.crossList)
338                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=1)",
339                                "(?i).*test\\W+${os}\\W+${scenario}.*")
340                             break                           
341                         case 'jitstressregs2':
342                             assert (os == 'Windows_NT') || (os in Constants.crossList)
343                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=2)",
344                                "(?i).*test\\W+${os}\\W+${scenario}.*")
345                             break                                                   
346                         case 'jitstressregs3':
347                             assert (os == 'Windows_NT') || (os in Constants.crossList)
348                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=3)",
349                                "(?i).*test\\W+${os}\\W+${scenario}.*")
350                             break                                                   
351                         case 'jitstressregs4':      
352                             assert (os == 'Windows_NT') || (os in Constants.crossList)
353                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=4)",
354                                "(?i).*test\\W+${os}\\W+${scenario}.*")
355                             break                                                   
356                         case 'jitstressregs8':
357                             assert (os == 'Windows_NT') || (os in Constants.crossList)
358                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=8)",
359                                "(?i).*test\\W+${os}\\W+${scenario}.*")
360                             break
361                         case 'jitstressregs0x10':
362                             assert (os == 'Windows_NT') || (os in Constants.crossList)
363                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=0x10)",
364                                "(?i).*test\\W+${os}\\W+${scenario}.*")
365                             break
366                         case 'jitstressregs0x80':
367                             assert (os == 'Windows_NT') || (os in Constants.crossList)
368                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=0x80)",
369                                "(?i).*test\\W+${os}\\W+${scenario}.*")
370                             break
371                         case 'jitstress2_jitstressregs1':
372                         case 'jitstress2_jitstressregs2':
373                         case 'jitstress2_jitstressregs3':
374                         case 'jitstress2_jitstressregs4':
375                         case 'jitstress2_jitstressregs8':
376                         case 'jitstress2_jitstressregs0x10':
377                         case 'jitstress2_jitstressregs0x80':
378                             def displayStr = getStressModeDisplayName(scenario)  
379                             assert (os == 'Windows_NT') || (os in Constants.crossList)
380                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayStr})",
381                                "(?i).*test\\W+${os}\\W+${scenario}.*")
382                             break
383                         case 'corefx_baseline':
384                         case 'corefx_minopts':
385                         case 'corefx_jitstress1':
386                         case 'corefx_jitstress2':
387                         case 'corefx_jitstressregs1':
388                         case 'corefx_jitstressregs2':
389                         case 'corefx_jitstressregs3':
390                         case 'corefx_jitstressregs4':
391                         case 'corefx_jitstressregs8':
392                         case 'corefx_jitstressregs0x10':
393                         case 'corefx_jitstressregs0x80':
394                             def displayName = 'CoreFx' + getStressModeDisplayName(scenario)                                                    
395                             assert (os == 'Windows_NT') || (os in Constants.crossList)
396                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayName})",
397                                "(?i).*test\\W+${os}\\W+${scenario}.*")
398                             break                          
399                         default:
400                             println("Unknown scenario: ${scenario}");
401                             assert false
402                             break
403                     }
404                     break
405                 case 'CentOS7.1':
406                 case 'OpenSUSE13.2':
407                     assert !isFlowJob
408                     assert scenario == 'default'
409                     if (configuration == 'Checked') {
410                         Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build")
411                     }
412                     break
413                 case 'Windows_NT':
414                     switch (scenario) {
415                         case 'default':
416                             // Default trigger
417                             if (configuration != 'Checked') {
418                                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test")
419                             }
420                             break
421                         case 'pri1':
422                             if (configuration == 'Release') {
423                                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Priority 1 Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
424                             }
425                             break
426                         case 'ilrt':
427                             if (configuration == 'Release') {
428                                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
429                             }
430                             break
431                         case 'minopts':
432                             assert (os == 'Windows_NT') || (os in Constants.crossList)
433                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - MinOpts)",
434                                "(?i).*test\\W+${os}\\W+${scenario}.*")
435                             break
436                         case 'forcerelocs':                         
437                             assert (os == 'Windows_NT') || (os in Constants.crossList)
438                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - ForceRelocs)",
439                                "(?i).*test\\W+${os}\\W+${scenario}.*")
440                             break                           
441                         case 'jitstress1':
442                             assert (os == 'Windows_NT') || (os in Constants.crossList)
443                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStress=1)",
444                                "(?i).*test\\W+${os}\\W+${scenario}.*")
445                             break
446                         case 'jitstress2':
447                             assert (os == 'Windows_NT') || (os in Constants.crossList)
448                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStress=2)",
449                                "(?i).*test\\W+${os}\\W+${scenario}.*")
450                             break
451                         case 'jitstressregs1':
452                             assert (os == 'Windows_NT') || (os in Constants.crossList)
453                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=1)",
454                                "(?i).*test\\W+${os}\\W+${scenario}.*")
455                             break                       
456                         case 'jitstressregs2':
457                             assert (os == 'Windows_NT') || (os in Constants.crossList)
458                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=2)",
459                                "(?i).*test\\W+${os}\\W+${scenario}.*")
460                             break                       
461                         case 'jitstressregs3':
462                             assert (os == 'Windows_NT') || (os in Constants.crossList)
463                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=3)",
464                                "(?i).*test\\W+${os}\\W+${scenario}.*")
465                             break                       
466                         case 'jitstressregs4':      
467                             assert (os == 'Windows_NT') || (os in Constants.crossList)
468                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=4)",
469                                "(?i).*test\\W+${os}\\W+${scenario}.*")
470                             break                       
471                         case 'jitstressregs8':
472                             assert (os == 'Windows_NT') || (os in Constants.crossList)
473                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=8)",
474                                "(?i).*test\\W+${os}\\W+${scenario}.*")
475                             break                       
476                         case 'jitstressregs0x10':
477                             assert (os == 'Windows_NT') || (os in Constants.crossList)
478                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=0x10)",
479                                "(?i).*test\\W+${os}\\W+${scenario}.*")
480                             break                       
481                         case 'jitstressregs0x80':
482                             assert (os == 'Windows_NT') || (os in Constants.crossList)
483                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=0x80)",
484                                "(?i).*test\\W+${os}\\W+${scenario}.*")
485                             break       
486                         case 'jitstress2_jitstressregs1':
487                         case 'jitstress2_jitstressregs2':
488                         case 'jitstress2_jitstressregs3':
489                         case 'jitstress2_jitstressregs4':
490                         case 'jitstress2_jitstressregs8':
491                         case 'jitstress2_jitstressregs0x10':
492                         case 'jitstress2_jitstressregs0x80':
493                             def displayStr = getStressModeDisplayName(scenario)
494                             assert (os == 'Windows_NT') || (os in Constants.crossList)
495                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayStr})",
496                                "(?i).*test\\W+${os}\\W+${scenario}.*")
497                             break                                   
498                         case 'corefx_baseline':
499                         case 'corefx_minopts':
500                         case 'corefx_jitstress1':
501                         case 'corefx_jitstress2':
502                         case 'corefx_jitstressregs1':
503                         case 'corefx_jitstressregs2':
504                         case 'corefx_jitstressregs3':
505                         case 'corefx_jitstressregs4':
506                         case 'corefx_jitstressregs8':
507                         case 'corefx_jitstressregs0x10':
508                         case 'corefx_jitstressregs0x80':
509                             def displayName = 'CoreFx ' + getStressModeDisplayName(scenario)
510                             assert (os == 'Windows_NT') || (os in Constants.crossList)
511                             Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayName})",
512                                "(?i).*test\\W+${os}\\W+${scenario}.*")
513                             break                       
514                         default:
515                             println("Unknown scenario: ${scenario}");
516                             assert false
517                             break
518                     }
519                     break
520                 case 'FreeBSD':
521                     assert scenario == 'default'
522                     if (configuration == 'Checked') {
523                         Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build")
524                     }
525                     break
526                 default:
527                     println("Unknown os: ${os}");
528                     assert false
529                     break
530             }
531             break
532         case 'arm64':
533         case 'arm':
534             assert scenario == 'default'
535             switch (os) {
536                 case 'Ubuntu':
537                     Utilities.addGithubPRTrigger(job, "${os} ${architecture} Cross ${configuration} Build", "(?i).*test\\W+${os}\\W+${architecture}.*")
538                     break
539                 case 'Windows_NT':
540                     // Set up a private trigger
541                     Utilities.addPrivateGithubPRTrigger(job, "${os} ${architecture} Cross ${configuration} Build",
542                         "(?i).*test\\W+${os}\\W+${architecture}.*", null, ['jashook', 'RussKeldorph', 'gkhanna79', 'briansul', 'cmckinsey', 'jkotas', 'ramarag', 'markwilkie', 'rahku', 'tzwlai', 'weshaggard', 'LLITCHEV'])
543                     break
544             }
545             break
546         case 'x86':
547             assert scenario == 'default'
548             // For windows, x86 runs by default
549             if (os == 'Windows_NT') {
550                 if (configuration != 'Checked') {
551                     Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build")
552                 }
553             }
554             else {
555                 // default trigger
556                 Utilities.addGithubPRTrigger(job, "${os} ${architecture} ${configuration} Build", "(?i).*test\\W+${architecture}\\W+${osGroup}.*")
557             }
558             break
559         default:
560             println("Unknown architecture: ${architecture}");
561             assert false
562             break
563     }
564 }
565
566 // Additional scenario which can alter behavior
567
568 def combinedScenarios = Constants.basicScenarios + Constants.jitStressModeScenarios.keySet()
569 combinedScenarios.each { scenario ->
570     Constants.branchList.each { branchName ->
571         Constants.architectureList.each { architecture ->
572             Constants.configurationList.each { configuration ->
573                 Constants.osList.each { os ->
574                     // If the OS is Windows_NT_BuildOnly, set the isBuildOnly flag to true
575                     // and reset the os to Windows_NT
576                     def isBuildOnly = false
577                     if (os == 'Windows_NT_BuildOnly') {
578                         isBuildOnly = true
579                         os = 'Windows_NT'
580                     }
581                     def isPR = (branchName == 'pr');
582                     
583                     // Skip totally unimplemented (in CI) configurations.
584                     switch (architecture) {
585                         case 'arm64':
586                             // Windows or cross compiled Ubuntu
587                             if (os != 'Windows_NT' && os != 'Ubuntu') {
588                                 return
589                             }
590                             break
591                         case 'arm':
592                             // Only Ubuntu cross implemented
593                             if (os != 'Ubuntu') {
594                                 return
595                             }
596                             break
597                         case 'x86':
598                             // Skip non-windows
599                             if (os != 'Windows_NT') {
600                                 return
601                             }
602                             break
603                         case 'x64':
604                             // Everything implemented
605                             break
606                         default:
607                             println("Unknown architecture: ${architecture}")
608                             assert false
609                             break
610                     }
611
612                     // Skip scenarios (blanket skipping for jit stress modes, which are good most everywhere
613                     // with checked builds
614                     def enableCorefxTesting = false
615                     if (Constants.jitStressModeScenarios.containsKey(scenario)) {
616                         if (configuration != 'Checked') {
617                             return
618                         }
619                         
620                         // Since these are just execution time differences,
621                         // skip platforms that don't execute the tests here (Windows_NT only)
622                         def isEnabledOS = os == 'Windows_NT' || os == 'Ubuntu'
623                         if (!isEnabledOS || isBuildOnly) {
624                             return
625                         }
626                         
627                         // No stress modes except on x64 right now (mainly because of bad test state on x86)
628                         if (architecture != 'x64') {
629                             return
630                         }
631                         
632                         enableCorefxTesting = isCorefxTesting(scenario)
633                     }
634                     else {
635                         // Skip scenarios
636                         switch (scenario) {
637                             case 'pri1':
638                                 // The pri1 build isn't necessary except for os's in the cross list or Windows_NT (native OS runs)
639                                 if (os != 'Windows_NT' && !(os in Constants.crossList)) {
640                                     return
641                                 }
642                                 // Only x64 for now
643                                 if (architecture != 'x64') {
644                                     return
645                                 }
646                                 break
647                             case 'ilrt':
648                                 // The ilrt build isn't necessary except for os's in the cross list or Windows_NT (native OS runs)
649                                 if (os != 'Windows_NT' && !(os in Constants.crossList)) {
650                                     return
651                                 }
652                                 // Only x64 for now
653                                 if (architecture != 'x64') {
654                                     return
655                                 }
656                                 break
657                             case 'default':
658                                 // Nothing skipped
659                                 break
660                             default:
661                                 println("Unknown scenario: ${scenario}")
662                                 assert false
663                                 break
664                         }
665                     }
666                 
667                     // Calculate names
668                     def lowerConfiguration = configuration.toLowerCase()
669                     def jobName = getJobName(configuration, architecture, os, scenario, isBuildOnly, branchName)
670                     
671                     // Create the new job
672                     def newJob = job(Utilities.getFullJobName(project, jobName, isPR)) {}
673
674                     setMachineAffinity(newJob, os, architecture)
675
676                     // Add all the standard options
677                     Utilities.standardJobSetup(newJob, project, isPR, getFullBranchName(branchName))
678                     addTriggers(newJob, isPR, architecture, os, configuration, scenario, false)
679                 
680                     def buildCommands = [];
681                     def osGroup = getOSGroup(os)
682                 
683                     // Calculate the build steps, archival, and xunit results
684                     switch (os) {
685                         case 'Windows_NT':
686                             switch (architecture) {
687                                 case 'x64':
688                                 case 'x86':
689                                     
690                                     if (scenario == 'default' || Constants.jitStressModeScenarios.containsKey(scenario)) {
691                                         buildOpts = enableCorefxTesting ? 'skiptests' : ''
692                                         buildCommands += "build.cmd ${lowerConfiguration} ${architecture} ${buildOpts}"
693                                     }
694
695                                     // For Pri 1 tests, we must shorten the output test binary path names.
696                                     // if __TestIntermediateDir is already set, buildtest.cmd will
697                                     // output test binaries to that directory. If it is not set, the 
698                                     // binaries are sent to a default directory whose name is about
699                                     // 35 characters long.
700
701                                     else if (scenario == 'pri1') {
702                                         buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} Priority 1"
703                                     }
704                                     else if (scenario == 'ilrt') {
705                                         // First do the build with skiptestbuild and then build the tests with ilasm roundtrip
706                                         buildCommands += "build.cmd ${lowerConfiguration} ${architecture} skiptestbuild"
707                                         buildCommands += "tests\\buildtest.cmd ${lowerConfiguration} ${architecture} ilasmroundtrip"
708                                     }
709                                     else {
710                                         println("Unknown scenario: ${scenario}")
711                                         assert false
712                                     }
713                                     
714                                     // If we are running a stress mode, we should write out the set of key
715                                     // value env pairs to a file at this point and then we'll pass that to runtest.cmd
716
717                                     if (!isBuildOnly) {
718                                         if (Constants.jitStressModeScenarios.containsKey(scenario)) {
719                                             if (enableCorefxTesting) {
720                                                 // Sync to corefx repo
721                                                 // Move coreclr files to a subdirectory, %workspace%/clr. Otherwise, corefx build 
722                                                 // thinks that %workspace% is the project base directory.
723                                                 buildCommands += "powershell new-item clr -type directory -force"
724                                                 buildCommands += 'powershell foreach ($x in get-childitem -force) { if (\$x.name -ne \'clr\') { move-item $x clr }}'
725                                                 buildCommands += "git clone https://github.com/dotnet/corefx fx"
726                                                 
727                                                 def setEnvVar = ''
728                                                 def envVars = Constants.jitStressModeScenarios[scenario]
729                                                 envVars.each{ VarName, Value   ->
730                                                     if (VarName != '') {
731                                                         setEnvVar += "&& set ${VarName}=${Value} "
732                                                     }
733                                                 }
734                                                 
735                                                 // Run corefx build and testing
736                                                 buildCommands += "cd fx && call \"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat\" x86 ${setEnvVar} && Build.cmd /p:ConfigurationGroup=Release  /p:BUILDTOOLS_OVERRIDE_RUNTIME=%WORKSPACE%\\clr\\bin\\Product\\Windows_NT.x64.Checked "                                                                                              
737                                             }
738                                             else {
739                                                 def stepScriptLocation = "%WORKSPACE%\\bin\\tests\\SetStressModes.bat"
740                                                 buildCommands += genStressModeScriptStep(os, scenario, Constants.jitStressModeScenarios[scenario], stepScriptLocation)
741                                                 
742                                                 // Run tests with the 
743                                                 
744                                                 buildCommands += "tests\\runtest.cmd ${lowerConfiguration} ${architecture} TestEnv ${stepScriptLocation}"
745                                             }                                            
746                                         }
747                                         else if (architecture == 'x64' || !isPR) {
748                                             buildCommands += "tests\\runtest.cmd ${lowerConfiguration} ${architecture}"
749                                         }
750                                     }
751
752                                     if (!enableCorefxTesting) {
753                                         // Run the rest of the build    
754                                         // Build the mscorlib for the other OS's
755                                         buildCommands += "build.cmd ${lowerConfiguration} ${architecture} linuxmscorlib"
756                                         buildCommands += "build.cmd ${lowerConfiguration} ${architecture} freebsdmscorlib"
757                                         buildCommands += "build.cmd ${lowerConfiguration} ${architecture} osxmscorlib"
758                                     
759                                         // Zip up the tests directory so that we don't use so much space/time copying
760                                         // 10s of thousands of files around.
761                                         buildCommands += "powershell -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${architecture}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
762                                         
763                                         // For windows, pull full test results and test drops for x86/x64
764                                         Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip")
765                                         
766                                         if (!isBuildOnly) {
767                                             if (architecture == 'x64' || !isPR) {
768                                                 Utilities.addXUnitDotNETResults(newJob, 'bin/**/TestRun*.xml')
769                                             }
770                                         }
771                                     }
772                                     else {
773                                         // Archive only result xml files since corefx/bin/tests is very large around 10 GB.                                        
774                                         // For windows, pull full test results and test drops for x86/x64
775                                         Utilities.addArchival(newJob, "fx/bin/tests/**/testResults.xml")
776                                         
777                                         // Set timeout to 240
778                                         Utilities.setJobTimeout(newJob, 240)
779                                         
780                                         if (architecture == 'x64' || !isPR) {
781                                             Utilities.addXUnitDotNETResults(newJob, 'fx/bin/tests/**/testResults.xml')
782                                         }
783                                     }
784                                     
785                                     break
786                                 case 'arm64':
787                                     assert scenario == 'default'
788                                     buildCommands += "build.cmd ${lowerConfiguration} ${architecture} skiptestbuild /toolset_dir C:\\ats"
789                                     // Add archival.  No xunit results for x64 windows
790                                     Utilities.addArchival(newJob, "bin/Product/**")
791                                     break
792                                 default:
793                                     println("Unknown architecture: ${architecture}");
794                                     assert false
795                                     break
796                             }
797                             break
798                         case 'Ubuntu':
799                         case 'Ubuntu15.10':
800                         case 'Debian8.2':
801                         case 'OSX':
802                         case 'FreeBSD':
803                         case 'CentOS7.1':
804                         case 'RHEL7.2':
805                         case 'OpenSUSE13.2':
806                             switch (architecture) {
807                                 case 'x64':
808                                 case 'x86':
809                                     if (!enableCorefxTesting) {
810                                         // On other OS's we skipmscorlib but run the pal tests
811                                         if ((architecture == 'x64') && ((os == 'Ubuntu') || (os == 'OSX')))
812                                         {
813                                             buildCommands += "./build.sh verbose ${lowerConfiguration} ${architecture}"
814                                         }
815                                         else
816                                         {
817                                             buildCommands += "./build.sh skipmscorlib verbose ${lowerConfiguration} ${architecture}"
818                                         }
819                                         buildCommands += "src/pal/tests/palsuite/runpaltests.sh \${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration} \${WORKSPACE}/bin/paltestout"
820                                     
821                                         // Basic archiving of the build
822                                         Utilities.addArchival(newJob, "bin/Product/**,bin/obj/*/tests/**")
823                                         // And pal tests
824                                         Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
825                                     }
826                                     else {
827                                         // Corefx stress testing                                        
828                                         assert os == 'Ubuntu'
829                                         assert architecture == 'x64'
830                                         assert lowerConfiguration == 'checked'
831                                         
832                                         // Build coreclr and move it to clr directory
833                                         buildCommands += "./build.sh verbose ${lowerConfiguration} ${architecture}"
834                                         buildCommands += "rm -rf .clr; mkdir .clr; mv * .clr; mv .git .clr; mv .clr clr"
835                                         
836                                         // Get corefx
837                                         buildCommands += "git clone https://github.com/dotnet/corefx fx"
838                                         
839                                         // Set environment variable
840                                         def setEnvVar = ''
841                                         def envVars = Constants.jitStressModeScenarios[scenario]
842                                         envVars.each{ VarName, Value   ->
843                                             if (VarName != '') {
844                                                 setEnvVar += " ${VarName}=${Value}"
845                                             }
846                                         }
847                                                 
848                                         // Build and text corefx
849                                         buildCommands += "rm -rf \$WORKSPACE/fx_home; mkdir \$WORKSPACE/fx_home"
850                                         buildCommands += "cd fx; HOME=\$WORKSPACE/fx_home ${setEnvVar} ./build.sh /p:ConfigurationGroup=Release /p:BUILDTOOLS_OVERRIDE_RUNTIME=\$WORKSPACE/clr/bin/Product/Linux.x64.Checked"  
851
852                                         // Archive and process test result
853                                         Utilities.addArchival(newJob, "fx/bin/tests/**/testResults.xml")
854                                         Utilities.setJobTimeout(newJob, 360)
855                                         Utilities.addXUnitDotNETResults(newJob, 'fx/bin/tests/**/testResults.xml')
856                                     }
857                                     break
858                                 case 'arm64':
859                                     // We don't run the cross build except on Ubuntu
860                                     assert os == 'Ubuntu'
861                                     
862                                     buildCommands += """echo \"Using rootfs in /opt/aarch64-linux-gnu-root\"
863                                         ROOTFS_DIR=/opt/aarch64-linux-gnu-root ./build.sh skipmscorlib arm64 cross verbose ${lowerConfiguration}"""
864                                     
865                                     // Basic archiving of the build, no pal tests
866                                     Utilities.addArchival(newJob, "bin/Product/**")
867                                     break
868                                 case 'arm':
869                                     // We don't run the cross build except on Ubuntu
870                                     assert os == 'Ubuntu'
871                                     buildCommands += """echo \"Using rootfs in /opt/arm-liux-genueabihf-root\"
872                                         ROOTFS_DIR=/opt/arm-linux-genueabihf-root ./build.sh skipmscorlib arm cross verbose ${lowerConfiguration}"""
873                                         
874                                     // Basic archiving of the build, no pal tests
875                                     Utilities.addArchival(newJob, "bin/Product/**")
876                                     break
877                                 default:
878                                     println("Unknown architecture: ${architecture}");
879                                     assert false
880                                     break
881                             }
882                             break
883                         default:
884                             println("Unknown os: ${os}");
885                             assert false
886                             break
887                     }
888                 
889                     newJob.with {
890                         steps {
891                             if (os == 'Windows_NT') {
892                                 buildCommands.each { buildCommand ->
893                                     batchFile(buildCommand)
894                                 }
895                             }
896                             else {
897                                 buildCommands.each { buildCommand ->
898                                     shell(buildCommand)
899                                }
900                             }
901                         }
902                     }
903                 } // os
904             } // configuration
905         } // architecture
906     } // isPR
907 } // scenario
908
909 // Create the Linux/OSX coreclr test leg for debug and release and each scenario
910 combinedScenarios.each { scenario ->
911     Constants.branchList.each { branchName ->
912         // Architectures.  x64 only at this point
913         ['x64'].each { architecture ->
914             // Put the OS's supported for coreclr cross testing here
915             Constants.crossList.each { os ->
916                 Constants.configurationList.each { configuration ->
917
918                     def isPR = (branchName == 'pr');
919
920                     if (Constants.jitStressModeScenarios.containsKey(scenario)) {
921                         if (configuration != 'Checked') {
922                             return
923                         }
924                         if (isCorefxTesting(scenario)) {
925                             return
926                         }
927                     }
928                     else {
929                         // Skip scenarios
930                         switch (scenario) {
931                             case 'pri1':
932                                 // Nothing skipped
933                                 break
934                             case 'ilrt':
935                                 // Nothing skipped
936                                 break
937                             case 'default':
938                                 // Nothing skipped
939                                 break
940                             default:
941                                 println("Unknown scenario: ${scenario}")
942                                 assert false
943                                 break
944                         }
945                     }
946                     
947                     def lowerConfiguration = configuration.toLowerCase()
948                     def osGroup = getOSGroup(os)
949                     def jobName = getJobName(configuration, architecture, os, scenario, false, branchName) + "_tst"
950                     def inputCoreCLRBuildName = Utilities.getFolderName(project) + '/' + 
951                         Utilities.getFullJobName(project, getJobName(configuration, architecture, os, 'default', false, branchName), isPR)
952                     // If this is a stress scenario, there isn't any difference in the build job
953                     // so we didn't create a build only job for windows_nt specific to that stress mode.  Just copy
954                     // from the default scenario
955                     def inputWindowTestsBuildName = ''
956                     if (Constants.jitStressModeScenarios.containsKey(scenario)) {
957                         inputWindowTestsBuildName = Utilities.getFolderName(project) + '/' + 
958                             Utilities.getFullJobName(project, getJobName(configuration, architecture, 'windows_nt', 'default', true, branchName), isPR)
959                     }
960                     else {
961                         inputWindowTestsBuildName = Utilities.getFolderName(project) + '/' + 
962                             Utilities.getFullJobName(project, getJobName(configuration, architecture, 'windows_nt', scenario, true, branchName), isPR)
963                     }
964                     // Enable Server GC for Ubuntu PR builds
965                     def serverGCString = ''
966                      
967                     if (os == 'Ubuntu' && isPR){
968                         serverGCString = '--useServerGC'
969                     }
970                     
971
972                     def newJob = job(Utilities.getFullJobName(project, jobName, isPR)) {
973                         // Add parameters for the inputs
974                     
975                         parameters {
976                             stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR windows test binaries from')
977                             stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
978                         }
979                     
980                         steps {
981                             // Set up the copies
982                             
983                             // Coreclr build we are trying to test
984                             
985                             copyArtifacts(inputCoreCLRBuildName) {
986                                 excludePatterns('**/testResults.xml', '**/*.ni.dll')
987                                 buildSelector {
988                                     buildNumber('${CORECLR_BUILD}')
989                                 }
990                             }
991                         
992                             // Coreclr build containing the tests and mscorlib
993                         
994                             copyArtifacts(inputWindowTestsBuildName) {
995                                 excludePatterns('**/testResults.xml', '**/*.ni.dll')
996                                 buildSelector {
997                                     buildNumber('${CORECLR_WINDOWS_BUILD}')
998                                 }
999                             }
1000                         
1001                             // Corefx native components
1002                             def corefxNativeCompBinaries = 
1003                             copyArtifacts("dotnet_corefx/nativecomp_${os.toLowerCase()}_release") {
1004                                 includePatterns('bin/**')
1005                                 buildSelector {
1006                                     latestSuccessful(true)
1007                                 }
1008                             }
1009                         
1010                             // CoreFX Linux binaries
1011                             copyArtifacts("dotnet_corefx/${os.toLowerCase()}_release_bld") {
1012                                 includePatterns('bin/build.pack')
1013                                 buildSelector {
1014                                     latestSuccessful(true)
1015                                 }
1016                             }
1017                         
1018                             // Unpack the corefx binaries
1019                             shell("unpacker ./bin/build.pack ./bin")
1020                         
1021                             // Unzip the tests first.  Exit with 0
1022                             shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.${architecture}.${configuration} || exit 0")
1023                         
1024                             // Execute the tests
1025                             // If we are running a stress mode, we'll set those variables first
1026                             def stressModeString = ""
1027                             if (Constants.jitStressModeScenarios.containsKey(scenario)) {
1028                                 stressModeString = genStressModeScriptStep(os, scenario, Constants.jitStressModeScenarios[scenario], null)
1029                             }
1030                             
1031                             shell("""${stressModeString}
1032         ./tests/runtest.sh \\
1033             --testRootDir=\"\${WORKSPACE}/bin/tests/Windows_NT.${architecture}.${configuration}\" \\
1034             --testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
1035             --coreClrBinDir=\"\${WORKSPACE}/bin/Product/${osGroup}.${architecture}.${configuration}\" \\
1036             --mscorlibDir=\"\${WORKSPACE}/bin/Product/${osGroup}.${architecture}.${configuration}\" \\
1037             --coreFxBinDir=\"\${WORKSPACE}/bin/${osGroup}.AnyCPU.Release\" \\
1038             --coreFxNativeBinDir=\"\${WORKSPACE}/bin/${osGroup}.${architecture}.Release\" \\
1039             ${serverGCString}""")
1040                         }
1041                     }
1042                 
1043                     setMachineAffinity(newJob, os, architecture)
1044                     Utilities.standardJobSetup(newJob, project, isPR, getFullBranchName(branchName))
1045                     // Set timeouts to 240.
1046                     Utilities.setJobTimeout(newJob, 240)
1047                     Utilities.addXUnitDotNETResults(newJob, '**/coreclrtests.xml')
1048                 
1049                     // Create a build flow to join together the build and tests required to run this
1050                     // test.
1051                     // Windows CoreCLR build and Linux CoreCLR build (in parallel) ->
1052                     // Linux CoreCLR test
1053                     def flowJobName = getJobName(configuration, architecture, os, scenario, false, branchName) + "_flow"
1054                     def fullTestJobName = Utilities.getFolderName(project) + '/' + newJob.name
1055                     def newFlowJob = buildFlowJob(Utilities.getFullJobName(project, flowJobName, isPR)) {
1056                         buildFlow("""
1057 // Build the input jobs in parallel
1058 parallel (
1059     { coreclrBuildJob = build(params, '${inputCoreCLRBuildName}') },
1060     { windowsBuildJob = build(params, '${inputWindowTestsBuildName}') }
1061 )
1062     
1063 // And then build the test build
1064 build(params + [CORECLR_BUILD: coreclrBuildJob.build.number, 
1065                 CORECLR_WINDOWS_BUILD: windowsBuildJob.build.number], '${fullTestJobName}')    
1066 """)
1067                         // Needs a workspace
1068                         configure {
1069                             def buildNeedsWorkspace = it / 'buildNeedsWorkspace'
1070                             buildNeedsWorkspace.setValue('true')
1071                         }
1072                     }
1073
1074                     Utilities.standardJobSetup(newFlowJob, project, isPR, getFullBranchName(branchName))
1075                     addTriggers(newFlowJob, isPR, architecture, os, configuration, scenario, true)
1076                 } // configuration
1077             } // os
1078         } // architecture
1079     } // isPR
1080 } // scenario