如何在Mocha中执行许多过程测试?

时间:2018-05-27 23:27:23

标签: javascript mocha

我有一个带有~70个可执行文件测试的回购。在mochajest下运行时,它通常会在前几个承诺上出现错误,或者是因为超时,或者是因为stdout从未将其返回到父进程。

我对此问题的最小复制涉及100个线程,每个线程调用一个睡眠时间为10秒的命令行:

let child_process = require('child_process');
let AllTests = [];

/* start processes */
for (let i = 0; i < 100; ++i) {
  AllTests.push({
    i: i,
    start: new Date(),
    exec: new Promise((resolve, reject) => {
      let program = child_process.spawn(
        'node', ['-e', 'setTimeout(() => { process.exit(0); }, 9999)'])
        // 'node', ['-e', 'for (let i = 0; i < 2**28; ++i) ;'])
      program.on('exit', exitCode => { resolve({exitCode:exitCode}) })
      program.on('error', err => { reject(err) })
    })
  })
}

/* test results */
describe('churn', () => {
  AllTests.forEach(test => {
    it('should execute test ' + test.i + '.',
       done => {
         test.exec.then(exec => {
           test.end = new Date()
           done()
         })
       })
  })
})

在我的笔记本电脑上,我通常会得到:

  93 passing (19s)
  7 failing

  1) churn
       should execute test 0.:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/home/eric/errz/flood.js)
  ...

之后添加一些会计:

after(() => {
  console.log()
  AllTests.forEach(test => {
    console.log(test.i, (test.end - test.start)/1000.0)
  })
})

表明每个过程需要大约19秒。

鉴于这种情况发生在Mocha和Jest中,我猜这个问题与100个同步进程有关。建议?

1 个答案:

答案 0 :(得分:0)

我几乎可以分别解决超时和stdio流问题。 当我将进程终止的退出处理程序推送到下一个事件周期时,流问题大多已清除:

program.on("exit", function(exitCode) {
  setTimeout(
    () => resolve({stdout:stdout, stderr:stderr, exitCode:exitCode}), 0
  )
});
program.on("error", function(err) { reject(err); });

超时是因为我淹没了进程表。 我使用timeout-promise-queue而不是与内核的调度程序过于亲密,它使整个并发进程受到限制,并根据每个排队进程的开始时间提供超时。

使用timeout-promise-queue也清除了恶意流问题,这些问题仅在进程表变得过大时出现。 经过数千次测试后,我在退出处理程序上确定了一个25的进程队列和一个0长度的超时。

resulting diffs非常简单且不言自明,我不再需要在Travis tests上点击[LinkedInRestart作业]。