Skip to content

Commit 6a82ac7

Browse files
committed
migrate termination watcher to vitest
1 parent 3778b3a commit 6a82ac7

File tree

8 files changed

+85
-43
lines changed

8 files changed

+85
-43
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import 'aws-sdk-client-mock-jest/vitest';

lambdas/functions/termination-watcher/src/ConfigResolver.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Config } from './ConfigResolver';
2+
import { describe, it, expect, beforeEach, beforeAll, afterEach, afterAll, vi } from 'vitest';
3+
24

35
process.env.ENABLE_METRICS_SPOT_WARNING = 'true';
46

lambdas/functions/termination-watcher/src/ec2.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { EC2Client, DescribeInstancesCommand, DescribeInstancesResult } from '@aws-sdk/client-ec2';
22
import { mockClient } from 'aws-sdk-client-mock';
33
import { getInstances, tagFilter } from './ec2';
4+
import { describe, it, expect, beforeEach, beforeAll, afterEach, afterAll, vi } from 'vitest';
5+
46

57
const ec2Mock = mockClient(EC2Client);
68

lambdas/functions/termination-watcher/src/lambda.test.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { logger } from '@aws-github-runner/aws-powertools-util';
22
import { Context } from 'aws-lambda';
3-
import { mocked } from 'jest-mock';
3+
44

55
import { handle as interruptionWarningHandlerImpl } from './termination-warning';
66
import { handle as terminationHandlerImpl } from './termination';
77
import { interruptionWarning, termination } from './lambda';
88
import { BidEvictedDetail, BidEvictedEvent, SpotInterruptionWarning, SpotTerminationDetail } from './types';
9+
import { describe, it, expect, beforeEach, beforeAll, afterEach, afterAll, vi } from 'vitest';
10+
911

10-
jest.mock('./termination-warning');
11-
jest.mock('./termination');
12+
vi.mock('./termination-warning');
13+
vi.mock('./termination');
1214

1315
process.env.POWERTOOLS_METRICS_NAMESPACE = 'test';
1416
process.env.POWERTOOLS_TRACE_ENABLED = 'true';
@@ -87,11 +89,11 @@ const context: Context = {
8789
// Docs for testing async with jest: https://jestjs.io/docs/tutorial-async
8890
describe('Handle sport termination interruption warning', () => {
8991
beforeEach(() => {
90-
jest.clearAllMocks();
92+
vi.clearAllMocks();
9193
});
9294

9395
it('should not throw or log in error.', async () => {
94-
const mock = mocked(interruptionWarningHandlerImpl);
96+
const mock = vi.mocked(interruptionWarningHandlerImpl);
9597
mock.mockImplementation(() => {
9698
return new Promise((resolve) => {
9799
resolve();
@@ -101,9 +103,9 @@ describe('Handle sport termination interruption warning', () => {
101103
});
102104

103105
it('should not throw only log in error in case of an exception.', async () => {
104-
const logSpy = jest.spyOn(logger, 'error');
106+
const logSpy = vi.spyOn(logger, 'error');
105107
const error = new Error('An error.');
106-
const mock = mocked(interruptionWarningHandlerImpl);
108+
const mock = vi.mocked(interruptionWarningHandlerImpl);
107109
mock.mockRejectedValue(error);
108110
await expect(interruptionWarning(spotInstanceInterruptionEvent, context)).resolves.toBeUndefined();
109111

@@ -113,11 +115,11 @@ describe('Handle sport termination interruption warning', () => {
113115

114116
describe('Handle sport termination (BidEvictEvent', () => {
115117
beforeEach(() => {
116-
jest.clearAllMocks();
118+
vi.clearAllMocks();
117119
});
118120

119121
it('should not throw or log in error.', async () => {
120-
const mock = mocked(terminationHandlerImpl);
122+
const mock = vi.mocked(terminationHandlerImpl);
121123
mock.mockImplementation(() => {
122124
return new Promise((resolve) => {
123125
resolve();
@@ -127,9 +129,9 @@ describe('Handle sport termination (BidEvictEvent', () => {
127129
});
128130

129131
it('should not throw only log in error in case of an exception.', async () => {
130-
const logSpy = jest.spyOn(logger, 'error');
132+
const logSpy = vi.spyOn(logger, 'error');
131133
const error = new Error('An error.');
132-
const mock = mocked(terminationHandlerImpl);
134+
const mock = vi.mocked(terminationHandlerImpl);
133135
mock.mockRejectedValue(error);
134136
await expect(termination(bidEvictedEvent, context)).resolves.toBeUndefined();
135137

lambdas/functions/termination-watcher/src/metric-event.test.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,23 @@ import { SpotInterruptionWarning, SpotTerminationDetail } from './types';
44
import { createSingleMetric } from '@aws-github-runner/aws-powertools-util';
55
import { MetricUnit } from '@aws-lambda-powertools/metrics';
66
import { metricEvent } from './metric-event';
7+
import { describe, it, expect, beforeEach, beforeAll, afterEach, afterAll, vi } from 'vitest';
78

8-
jest.mock('@aws-github-runner/aws-powertools-util', () => ({
9-
...jest.requireActual('@aws-github-runner/aws-powertools-util'),
10-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
11-
createSingleMetric: jest.fn((name: string, unit: string, value: number, dimensions?: Record<string, string>) => {
12-
return {
13-
addMetadata: jest.fn(),
14-
};
15-
}),
16-
}));
9+
10+
// Mock the module before imports
11+
vi.mock('@aws-github-runner/aws-powertools-util', async (importOriginal) => {
12+
// Use importOriginal instead of requireActual in Vitest
13+
const actual = await importOriginal();
14+
return {
15+
...actual,
16+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
17+
createSingleMetric: vi.fn((name: string, unit: string, value: number, dimensions?: Record<string, string>) => {
18+
return {
19+
addMetadata: vi.fn(),
20+
};
21+
}),
22+
};
23+
});
1724

1825
const event: SpotInterruptionWarning<SpotTerminationDetail> = {
1926
version: '0',
@@ -44,7 +51,7 @@ const instance: Instance = {
4451

4552
describe('create metric and metric logs', () => {
4653
beforeEach(() => {
47-
jest.clearAllMocks();
54+
vi.clearAllMocks();
4855
});
4956

5057
it('should log and create a metric', async () => {

lambdas/functions/termination-watcher/src/termination-warning.test.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@ import 'aws-sdk-client-mock-jest';
44
import { handle } from './termination-warning';
55
import { SpotInterruptionWarning, SpotTerminationDetail } from './types';
66
import { metricEvent } from './metric-event';
7-
import { mocked } from 'jest-mock';
7+
88
import { getInstances } from './ec2';
9+
import { describe, it, expect, beforeEach, beforeAll, afterEach, afterAll, vi } from 'vitest';
910

10-
jest.mock('./metric-event', () => ({
11-
metricEvent: jest.fn(),
12-
}));
1311

14-
jest.mock('./ec2', () => ({
15-
...jest.requireActual('./ec2'),
16-
getInstances: jest.fn(),
12+
vi.mock('./metric-event', () => ({
13+
metricEvent: vi.fn(),
1714
}));
1815

16+
vi.mock('./ec2', async (importOriginal) => {
17+
const actual = await importOriginal();
18+
return {
19+
...actual,
20+
getInstances: vi.fn(),
21+
};
22+
});
23+
1924
mockClient(EC2Client);
2025

2126
const config = {
@@ -54,26 +59,26 @@ const instance: Instance = {
5459

5560
describe('handle termination warning', () => {
5661
beforeEach(() => {
57-
jest.clearAllMocks();
62+
vi.clearAllMocks();
5863
});
5964

6065
it('should log and create an metric', async () => {
61-
mocked(getInstances).mockResolvedValue([instance]);
66+
vi.mocked(getInstances).mockResolvedValue([instance]);
6267
await handle(event, config);
6368

6469
expect(metricEvent).toHaveBeenCalled();
6570
expect(metricEvent).toHaveBeenCalledWith(instance, event, 'SpotInterruptionWarning', expect.anything());
6671
});
6772

6873
it('should log details and not create a metric', async () => {
69-
mocked(getInstances).mockResolvedValue([instance]);
74+
vi.mocked(getInstances).mockResolvedValue([instance]);
7075

7176
await handle(event, { ...config, createSpotWarningMetric: false });
7277
expect(metricEvent).toHaveBeenCalledWith(instance, event, undefined, expect.anything());
7378
});
7479

7580
it('should not create a metric if filter not matched.', async () => {
76-
mocked(getInstances).mockResolvedValue([instance]);
81+
vi.mocked(getInstances).mockResolvedValue([instance]);
7782

7883
await handle(event, {
7984
createSpotWarningMetric: true,

lambdas/functions/termination-watcher/src/termination.test.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,23 @@ import 'aws-sdk-client-mock-jest';
44
import { handle } from './termination';
55
import { BidEvictedDetail, BidEvictedEvent } from './types';
66
import { metricEvent } from './metric-event';
7-
import { mocked } from 'jest-mock';
7+
88
import { getInstances } from './ec2';
9+
import { describe, it, expect, beforeEach, beforeAll, afterEach, afterAll, vi } from 'vitest';
910

10-
jest.mock('./metric-event', () => ({
11-
metricEvent: jest.fn(),
12-
}));
1311

14-
jest.mock('./ec2', () => ({
15-
...jest.requireActual('./ec2'),
16-
getInstances: jest.fn(),
12+
vi.mock('./metric-event', () => ({
13+
metricEvent: vi.fn(),
1714
}));
1815

16+
vi.mock('./ec2', async (importOriginal) => {
17+
const actual = await importOriginal();
18+
return {
19+
...actual,
20+
getInstances: vi.fn(),
21+
};
22+
});
23+
1924
mockClient(EC2Client);
2025

2126
const config = {
@@ -75,26 +80,26 @@ const instance: Instance = {
7580

7681
describe('handle termination warning', () => {
7782
beforeEach(() => {
78-
jest.clearAllMocks();
83+
vi.clearAllMocks();
7984
});
8085

8186
it('should log and create an metric', async () => {
82-
mocked(getInstances).mockResolvedValue([instance]);
87+
vi.mocked(getInstances).mockResolvedValue([instance]);
8388
await handle(event, config);
8489

8590
expect(metricEvent).toHaveBeenCalled();
8691
expect(metricEvent).toHaveBeenCalledWith(instance, event, 'SpotTermination', expect.anything());
8792
});
8893

8994
it('should log details and not create a metric', async () => {
90-
mocked(getInstances).mockResolvedValue([instance]);
95+
vi.mocked(getInstances).mockResolvedValue([instance]);
9196

9297
await handle(event, { ...config, createSpotTerminationMetric: false });
9398
expect(metricEvent).toHaveBeenCalledWith(instance, event, undefined, expect.anything());
9499
});
95100

96101
it('should not create a metric if filter not matched.', async () => {
97-
mocked(getInstances).mockResolvedValue([instance]);
102+
vi.mocked(getInstances).mockResolvedValue([instance]);
98103

99104
await handle(event, {
100105
createSpotWarningMetric: false,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { mergeConfig } from 'vitest/config';
2+
import defaultConfig from '../../vitest.base.config';
3+
4+
export default mergeConfig(defaultConfig, {
5+
test: {
6+
setupFiles: ['./aws-vitest-setup.ts'],
7+
coverage: {
8+
include: ['src/**/*.ts'],
9+
exclude: ['src/**/*.test.ts', 'src/**/*.d.ts'],
10+
thresholds: {
11+
statements: 100,
12+
branches: 100,
13+
functions: 100,
14+
lines: 100,
15+
}
16+
},
17+
},
18+
});

0 commit comments

Comments
 (0)