Skip to content

Commit

Permalink
feat: ✨ graceful-shutdown unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
louiscavalcante committed Jan 18, 2024
1 parent 4a37d00 commit 56e5479
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 4 deletions.
7 changes: 3 additions & 4 deletions jest/setup-files-after-env.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const env = process.env

beforeAll(async () => {
jest.useFakeTimers({ advanceTimers: true })
jest.setSystemTime(new Date('2024-01-20T13:00:00.000Z'))
})
beforeAll(async () => {})

afterAll(async () => {})

beforeEach(async () => {
jest.useFakeTimers({ advanceTimers: true })
jest.setSystemTime(new Date('2024-01-20T13:00:00.000Z'))
jest.resetModules()
process.env = { ...env }
})
Expand Down
83 changes: 83 additions & 0 deletions src/__tests__/unit/helpers/graceful-shutdown.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Server } from 'node:http'
import { Logger } from 'traceability'

import { gracefulShutdown } from '@helpers/graceful-shutdown.helper'
import { EExitReason } from '@helpers/interfaces/graceful-shutdown.helper.interface'

jest.mock('traceability', () => ({
Logger: {
error: jest.fn(),
warn: jest.fn(),
},
}))

describe('Gracefulshutdown helper', () => {
let server: Server
let exitSpy: jest.SpyInstance
const error = new Error('Test error')
const signalCode = 0

beforeEach(() => {
server = new Server()
server.close = jest.fn(callback => callback()) as jest.Mock
exitSpy = jest.spyOn(process, 'exit').mockImplementation()
})

afterEach(() => {
exitSpy.mockRestore()
})

it('should log error if error is instance of Error', () => {
const handler = gracefulShutdown(server, { coredump: false, timeout: 500 })
handler(signalCode, EExitReason.SIGTERM)(error, null)

expect(Logger.error).toHaveBeenCalledWith({
exitReason: EExitReason.SIGTERM,
signalCode: signalCode,
message: error.message,
stack: error.stack,
})
})

it('should call process.exit with signal code', async () => {
const handler = gracefulShutdown(server, { coredump: false, timeout: 500 })
handler(signalCode, EExitReason.SIGTERM)(error, null)

expect(process.exit).toHaveBeenCalledWith(signalCode)
})

it('should call process.abort if coredump is true', async () => {
const abortSpy = jest.spyOn(process, 'abort').mockImplementation()
const handler = gracefulShutdown(server, { coredump: true, timeout: 500 })
handler(signalCode, EExitReason.SIGTERM)(error, null)

expect(process.abort).toHaveBeenCalled()
abortSpy.mockRestore()
})

it('should log warning if server stopped receiving connections', async () => {
const handler = gracefulShutdown(server, { coredump: false, timeout: 500 })
handler(signalCode, EExitReason.SIGTERM)(error, null)

expect(Logger.warn).toHaveBeenCalledWith('Graceful shutdown - Server stopped receiving connections')
expect(server.close).toHaveBeenCalledTimes(1)
})

it('should log warning if timeout reached', async () => {
const handler = gracefulShutdown(server, { coredump: false, timeout: 500 })
handler(signalCode, EExitReason.SIGTERM)(error, null)
jest.advanceTimersByTime(500)

expect(Logger.warn).toHaveBeenCalledWith('Graceful shutdown - Timeout reached: 500ms')
})

it('should log warning on process exit', async () => {
const handler = gracefulShutdown(server, { coredump: false, timeout: 500 })
handler(signalCode, EExitReason.SIGTERM)(error, null)
process.emit('exit', signalCode)

expect(Logger.warn).toHaveBeenCalledWith(
`Graceful shutdown - Completed with signal code: ${signalCode}`
)
})
})

0 comments on commit 56e5479

Please sign in to comment.