1 | import { DryRunStatus, DryRunResult, DryRunOptions, MutantRunOptions, MutantRunResult, MutantRunStatus } from '@stryker-mutator/api/test-runner';
|
2 | import log4js from 'log4js';
|
3 | import { ExpirableTask } from '@stryker-mutator/util';
|
4 |
|
5 | import { TestRunnerDecorator } from './test-runner-decorator.js';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | export 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 | }
|