UNPKG

1.78 kBPlain TextView Raw
1import { DryRunStatus, DryRunResult, DryRunOptions, MutantRunOptions, MutantRunResult, MutantRunStatus } from '@stryker-mutator/api/test-runner';
2import log4js from 'log4js';
3import { ExpirableTask } from '@stryker-mutator/util';
4
5import { TestRunnerDecorator } from './test-runner-decorator.js';
6
7/**
8 * Wraps a test runner and implements the timeout functionality.
9 */
10export class TimeoutDecorator extends TestRunnerDecorator {
11 private readonly log = log4js.getLogger(TimeoutDecorator.name);
12
13 public async dryRun(options: DryRunOptions): Promise<DryRunResult> {
14 const result = await this.run(options, () => super.dryRun(options));
15 if (result === ExpirableTask.TimeoutExpired) {
16 return {
17 status: DryRunStatus.Timeout,
18 };
19 } else {
20 return result;
21 }
22 }
23
24 public async mutantRun(options: MutantRunOptions): Promise<MutantRunResult> {
25 const result = await this.run(options, () => super.mutantRun(options));
26 if (result === ExpirableTask.TimeoutExpired) {
27 return {
28 status: MutantRunStatus.Timeout,
29 };
30 } else {
31 return result;
32 }
33 }
34
35 private async run<TOptions extends { timeout: number }, TResult>(
36 options: TOptions,
37 actRun: () => Promise<TResult>
38 ): Promise<TResult | typeof ExpirableTask.TimeoutExpired> {
39 this.log.debug('Starting timeout timer (%s ms) for a test run', options.timeout);
40 const result = await ExpirableTask.timeout(actRun(), options.timeout);
41 if (result === ExpirableTask.TimeoutExpired) {
42 await this.handleTimeout();
43 return result;
44 } else {
45 return result;
46 }
47 }
48
49 private async handleTimeout(): Promise<void> {
50 this.log.debug('Timeout expired, restarting the process and reporting timeout');
51 await this.recover();
52 }
53}