Skip to content

Instantly share code, notes, and snippets.

@keegancsmith
Created August 1, 2025 14:39
Show Gist options
  • Select an option

  • Save keegancsmith/9a3422ea1dc7c490ad8b4bf303a00b0b to your computer and use it in GitHub Desktop.

Select an option

Save keegancsmith/9a3422ea1dc7c490ad8b4bf303a00b0b to your computer and use it in GitHub Desktop.
Vitest Reporter which dumps what test was running on SIGTERM (useful for bazel)
import type { TestCase, TestSuite, Vitest } from 'vitest/node'
import type { Reporter } from 'vitest/reporters'
/**
* Catches SIGTERM from Bazel so we can report what tests are currently
* running. Vitest currently does not support reporting this information nor
* configuring a global timeout.
*/
class TimeoutReporter implements Reporter {
private runningTests = new Set<{ id: string; name: string; file: string; startTime: number }>()
private runningSuites = new Set<{ name: string; startTime: number }>()
public onInit(_: Vitest): void {
this.runningTests.clear()
this.runningSuites.clear()
// Vitest registers a SIGTERM listener in logger.ts which calls
// process.exit(). So we need to make sure we run before it.
process.prependOnceListener('SIGTERM', () => {
const now = Date.now()
process.stderr.write('\n\nSIGTERM received!\n')
for (const test of this.runningTests) {
const duration = now - test.startTime
process.stderr.write(`Currently running test ${test.name} (${test.file}) - running for ${duration}ms\n`)
}
for (const suite of this.runningSuites) {
const duration = now - suite.startTime
process.stderr.write(`Currently running suite ${suite.name} - running for ${duration}ms\n`)
}
process.stderr.write('Vitest was terminated by Bazel due to timeout\n')
})
}
public onTestCaseReady(testCase: TestCase): void {
this.runningTests.add({
id: testCase.id,
name: testCase.fullName,
file: testCase.module.moduleId,
startTime: Date.now(),
})
}
public onTestCaseResult(testCase: TestCase): void {
for (const test of this.runningTests) {
if (test.id === testCase.id) {
this.runningTests.delete(test)
break
}
}
}
public onTestSuiteReady(testSuite: TestSuite): void {
this.runningSuites.add({ name: testSuite.fullName, startTime: Date.now() })
}
public onTestSuiteResult(testSuite: TestSuite): void {
for (const suite of this.runningSuites) {
if (suite.name === testSuite.fullName) {
this.runningSuites.delete(suite)
break
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment