|
2 | 2 |
|
3 | 3 | const wait = duration => new Promise(resolve => setTimeout(resolve, duration)); |
4 | 4 |
|
| 5 | +const avoidConcurrencyOnSameBrowser = (_job, _jobs, _results) => { |
| 6 | + const startedJobs = _jobs.slice(0, _results.length); |
| 7 | + const runningJobsWithSameBrowser = startedJobs.filter((startedJob) => { |
| 8 | + if (startedJob.state === "complete" || startedJob.state === "error") { |
| 9 | + return false; |
| 10 | + } |
| 11 | + |
| 12 | + return startedJob.name === _job.name; |
| 13 | + }); |
| 14 | + |
| 15 | + const index = runningJobsWithSameBrowser.indexOf(_job); |
| 16 | + if (index === 0) { |
| 17 | + return Promise.resolve(); |
| 18 | + } |
| 19 | + |
| 20 | + return wait(1_000).then(() => { |
| 21 | + return avoidConcurrencyOnSameBrowser(_job, _jobs, _results); |
| 22 | + }); |
| 23 | +} |
| 24 | + |
5 | 25 | // By default, promises fail silently if you don't attach a .catch() handler to them. |
6 | 26 | //This tool keeps track of unhandled rejections globally. If any remain unhandled at the end of your process, it logs them to STDERR and exits with code 1. |
7 | 27 | const hardRejection = require("hard-rejection"); |
@@ -225,6 +245,21 @@ async function main() { |
225 | 245 | }) |
226 | 246 | }); |
227 | 247 |
|
| 248 | + jobConfigs.sort((a, b) => { |
| 249 | + if (a.polyfillCombinations !== b.polyfillCombinations) { |
| 250 | + return Number(b.polyfillCombinations) - Number(a.polyfillCombinations); |
| 251 | + } |
| 252 | + |
| 253 | + const aShard = a.shard ? Number(a.shard) : 1; |
| 254 | + const bShard = b.shard ? Number(b.shard) : 1; |
| 255 | + |
| 256 | + if (aShard !== bShard) { |
| 257 | + return aShard - bShard; |
| 258 | + } |
| 259 | + |
| 260 | + return a.browser.localeCompare(b.browser); |
| 261 | + }); |
| 262 | + |
228 | 263 | let jobs = []; |
229 | 264 |
|
230 | 265 | for (const jobConfig of jobConfigs) { |
@@ -296,10 +331,7 @@ async function main() { |
296 | 331 | } |
297 | 332 | if (message) { |
298 | 333 | out.push( |
299 | | - ` • Browser: ${job.name.padEnd( |
300 | | - " ", |
301 | | - 20 |
302 | | - )} Test config: ${job.configForLog} ${message}` |
| 334 | + ` • Browser: ${job.name.padEnd(15, " ")} Test config: ${job.configForLog.padEnd(32, " ")} ${message}` |
303 | 335 | ); |
304 | 336 | } |
305 | 337 | } |
@@ -329,62 +361,63 @@ async function main() { |
329 | 361 | let resolvedCount = 0; |
330 | 362 | function pushJob() { |
331 | 363 | const job = jobs[results.length]; |
332 | | - results.push( |
333 | | - job |
334 | | - .run() |
335 | | - .then(job => { |
336 | | - if (job.state === "complete") { |
337 | | - const [family, version] = normalizeUserAgent(job.useragent).split("/"); |
338 | | - _.set( |
339 | | - testResults, |
340 | | - [family, version, job.mode], |
341 | | - job.getResultSummary() |
342 | | - ); |
343 | | - } |
344 | | - resolvedCount++; |
345 | | - if (results.length < jobs.length) { |
346 | | - pushJob(); |
347 | | - } else if (resolvedCount === jobs.length) { |
348 | | - resolve(); |
349 | | - } |
350 | | - return job; |
351 | | - }) |
352 | | - .catch(error => { |
353 | | - if (TestJob.isRetryableError(error)) { |
354 | | - return wait(30 * 1000).then(() => |
355 | | - job |
356 | | - .run() |
357 | | - .then(job => { |
358 | | - if (job.state === "complete") { |
359 | | - const [family, version] = job.name.split("/"); |
360 | | - _.set( |
361 | | - testResults, |
362 | | - [family, version, job.mode], |
363 | | - job.getResultSummary() |
364 | | - ); |
365 | | - } |
366 | | - resolvedCount++; |
367 | | - if (results.length < jobs.length) { |
368 | | - pushJob(); |
369 | | - } else if (resolvedCount === jobs.length) { |
370 | | - resolve(); |
371 | | - } |
372 | | - return job; |
373 | | - }) |
374 | | - .catch(error => { |
375 | | - console.log(error.stack || error); |
376 | | - process.exitCode = 1; |
377 | | - |
378 | | - process.exit(1); |
379 | | - })); |
380 | | - } else { |
381 | | - console.log(error.stack || error); |
382 | | - process.exitCode = 1; |
383 | | - |
384 | | - process.exit(1); |
385 | | - } |
386 | | - }) |
387 | | - ); |
| 364 | + |
| 365 | + const jobRun = avoidConcurrencyOnSameBrowser(job, jobs, results).then(() => { |
| 366 | + return job.run(); |
| 367 | + }).then(job => { |
| 368 | + if (job.state === "complete") { |
| 369 | + const [family, version] = normalizeUserAgent(job.useragent).split("/"); |
| 370 | + _.set( |
| 371 | + testResults, |
| 372 | + [family, version, job.mode], |
| 373 | + job.getResultSummary() |
| 374 | + ); |
| 375 | + } |
| 376 | + resolvedCount++; |
| 377 | + if (results.length < jobs.length) { |
| 378 | + pushJob(); |
| 379 | + } else if (resolvedCount === jobs.length) { |
| 380 | + resolve(); |
| 381 | + } |
| 382 | + return job; |
| 383 | + }) |
| 384 | + .catch(error => { |
| 385 | + if (TestJob.isRetryableError(error)) { |
| 386 | + return wait(30_000).then(() => |
| 387 | + job |
| 388 | + .run() |
| 389 | + .then(job => { |
| 390 | + if (job.state === "complete") { |
| 391 | + const [family, version] = job.name.split("/"); |
| 392 | + _.set( |
| 393 | + testResults, |
| 394 | + [family, version, job.mode], |
| 395 | + job.getResultSummary() |
| 396 | + ); |
| 397 | + } |
| 398 | + resolvedCount++; |
| 399 | + if (results.length < jobs.length) { |
| 400 | + pushJob(); |
| 401 | + } else if (resolvedCount === jobs.length) { |
| 402 | + resolve(); |
| 403 | + } |
| 404 | + return job; |
| 405 | + }) |
| 406 | + .catch(error => { |
| 407 | + console.log(error.stack || error); |
| 408 | + process.exitCode = 1; |
| 409 | + |
| 410 | + process.exit(1); |
| 411 | + })); |
| 412 | + } else { |
| 413 | + console.log(error.stack || error); |
| 414 | + process.exitCode = 1; |
| 415 | + |
| 416 | + process.exit(1); |
| 417 | + } |
| 418 | + }); |
| 419 | + |
| 420 | + results.push(jobRun); |
388 | 421 | } |
389 | 422 | const concurrency = 5; |
390 | 423 | for (let index = 0; index < concurrency && index < jobs.length; index++) { |
|
0 commit comments