103 lines
3.6 KiB
JavaScript
103 lines
3.6 KiB
JavaScript
// Usage:
|
|
//
|
|
// Run all services:
|
|
// npm run test:services
|
|
//
|
|
// Run some services:
|
|
// npm run test:services -- --only=service1,service2,service3
|
|
//
|
|
// Alternatively, pass a newline-separated list of services to stdin.
|
|
// echo "service1\nservice2\nservice3" | npm run test:services -- --stdin
|
|
//
|
|
// Service tests are run in CI in two cases: scheduled builds and pull
|
|
// requests. The scheduled builds run _all_ the service tests, whereas the
|
|
// pull requests run service tests designated in the PR title. In this way,
|
|
// affected services can be proven working during code review without needing
|
|
// to run all the slow (and likely flaky) service tests.
|
|
//
|
|
// Example pull request titles:
|
|
//
|
|
// - [Travis] Fix timeout issues
|
|
// - [Travis Sonar] Support user token authentication
|
|
// - [CRAN CPAN CTAN] Add test coverage
|
|
//
|
|
// The pull request script test:services:pr is split into two parts. First the
|
|
// :prepare script infers the pull request context, fetches the PR title, and
|
|
// writes the list of affected services to a file. Then the :run script reads
|
|
// the list of affected services and runs the appropriate tests.
|
|
//
|
|
// There are three reasons to separate these two steps into separate processes
|
|
// and build stages:
|
|
//
|
|
// 1. Generating the list of services to test is necessarily asynchronous, and
|
|
// in Mocha, exclusive tests (`it.only` and `describe.only`) can only be
|
|
// applied synchronously. In other words, if you try to add exclusive tests
|
|
// in an asynchronous callback, all the tests will run. This is true even
|
|
// when using `_mocha --delay`, as we are. Undoubtedly this could be fixed,
|
|
// though it's not worth it. The problem is obscure and therefore low
|
|
// for Mocha, which is quite backlogged. There is an easy workaround, which
|
|
// is to generate the list of services to test in a separate process.
|
|
// 2. Executing these two steps of the test runner separately makes the process
|
|
// easier to reason about and much easier to debug on a dev machine.
|
|
// 3. Getting "pipefail" to work cross platform with an npm script seems tricky.
|
|
// Relying on npm scripts is safer. Using "pre" makes it impossible to run
|
|
// the second step without the first.
|
|
|
|
'use strict'
|
|
|
|
const minimist = require('minimist')
|
|
const readAllStdinSync = require('read-all-stdin-sync')
|
|
const Runner = require('./runner')
|
|
const serverHelpers = require('../../lib/in-process-server-test-helpers')
|
|
|
|
require('../../lib/unhandled-rejection.spec')
|
|
|
|
let server
|
|
before('Start running the server', function() {
|
|
this.timeout(5000)
|
|
server = serverHelpers.start()
|
|
})
|
|
after('Shut down the server', async function() {
|
|
await serverHelpers.stop(server)
|
|
})
|
|
|
|
const runner = new Runner()
|
|
runner.prepare()
|
|
// The server's request cache causes side effects between tests.
|
|
runner.beforeEach = () => {
|
|
serverHelpers.reset(server)
|
|
}
|
|
|
|
const args = minimist(process.argv.slice(3))
|
|
const stdinOption = args.stdin
|
|
const onlyOption = args.only
|
|
|
|
let onlyServices
|
|
|
|
if (stdinOption && onlyOption) {
|
|
console.error('Do not use --only with --stdin')
|
|
} else if (stdinOption) {
|
|
const allStdin = readAllStdinSync().trim()
|
|
onlyServices = allStdin ? allStdin.split('\n') : []
|
|
} else if (onlyOption) {
|
|
onlyServices = onlyOption.split(',')
|
|
}
|
|
|
|
if (typeof onlyServices === 'undefined') {
|
|
console.info('Running all service tests.')
|
|
} else if (onlyServices.length === 0) {
|
|
console.info('No service tests to run. Exiting.')
|
|
process.exit(0)
|
|
} else {
|
|
console.info(
|
|
`Running tests for ${onlyServices.length} services: ${onlyServices.join(
|
|
', '
|
|
)}.\n`
|
|
)
|
|
runner.only(onlyServices)
|
|
}
|
|
|
|
runner.toss()
|
|
// Invoke run() asynchronously, because Mocha will not start otherwise.
|
|
process.nextTick(run)
|