Skip to content

Commit 17f09c8

Browse files
Update heart.test.ts
1 parent 93c4bd4 commit 17f09c8

File tree

1 file changed

+40
-20
lines changed

1 file changed

+40
-20
lines changed

test/unit/node/heart.test.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { logger } from "@coder/logger"
22
import { readFile, writeFile, stat, utimes } from "fs/promises"
3-
import { Heart, heartbeatTimer } from "../../../src/node/heart"
4-
import { wrapper } from "../../../src/node/wrapper"
3+
import { Heart } from "../../../src/node/heart"
54
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
65

76
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
@@ -27,7 +26,7 @@ describe("Heart", () => {
2726
testDir = await tmpdir(testName)
2827
})
2928
beforeEach(() => {
30-
heart = new Heart(`${testDir}/shutdown.txt`, undefined, mockIsActive(true))
29+
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
3130
})
3231
afterAll(() => {
3332
jest.restoreAllMocks()
@@ -53,7 +52,7 @@ describe("Heart", () => {
5352

5453
expect(fileContents).toBe(text)
5554

56-
heart = new Heart(pathToFile, undefined, mockIsActive(true))
55+
heart = new Heart(pathToFile, mockIsActive(true))
5756
await heart.beat()
5857
// Check that the heart wrote to the heartbeatFilePath and overwrote our text
5958
const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" })
@@ -63,7 +62,7 @@ describe("Heart", () => {
6362
expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(0)
6463
})
6564
it("should log a warning when given an invalid file path", async () => {
66-
heart = new Heart(`fakeDir/fake.txt`, undefined, mockIsActive(false))
65+
heart = new Heart(`fakeDir/fake.txt`, mockIsActive(false))
6766
await heart.beat()
6867
expect(logger.warn).toHaveBeenCalled()
6968
})
@@ -82,7 +81,7 @@ describe("Heart", () => {
8281
it("should beat twice without warnings", async () => {
8382
// Use fake timers so we can speed up setTimeout
8483
jest.useFakeTimers()
85-
heart = new Heart(`${testDir}/hello.txt`, undefined, mockIsActive(true))
84+
heart = new Heart(`${testDir}/hello.txt`, mockIsActive(true))
8685
await heart.beat()
8786
// we need to speed up clocks, timeouts
8887
// call heartbeat again (and it won't be alive I think)
@@ -93,37 +92,47 @@ describe("Heart", () => {
9392
})
9493

9594
describe("heartbeatTimer", () => {
96-
beforeAll(() => {
95+
const testName = "heartbeatTimer"
96+
let testDir = ""
97+
beforeAll(async () => {
98+
await clean(testName)
99+
testDir = await tmpdir(testName)
97100
mockLogger()
98101
})
99102
afterAll(() => {
100103
jest.restoreAllMocks()
101104
})
105+
beforeEach(() => {
106+
jest.useFakeTimers()
107+
})
102108
afterEach(() => {
103109
jest.resetAllMocks()
110+
jest.clearAllTimers()
111+
jest.useRealTimers()
104112
})
105-
it("should call beat when isActive resolves to true", async () => {
113+
it("should call isActive when timeout expires", async () => {
106114
const isActive = true
107115
const mockIsActive = jest.fn().mockResolvedValue(isActive)
108-
const mockBeatFn = jest.fn()
109-
await heartbeatTimer(mockIsActive, mockBeatFn)
116+
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
117+
await heart.beat()
118+
jest.advanceTimersByTime(60 * 1000)
110119
expect(mockIsActive).toHaveBeenCalled()
111-
expect(mockBeatFn).toHaveBeenCalled()
112120
})
113121
it("should log a warning when isActive rejects", async () => {
114122
const errorMsg = "oh no"
115123
const error = new Error(errorMsg)
116124
const mockIsActive = jest.fn().mockRejectedValue(error)
117-
const mockBeatFn = jest.fn()
118-
await heartbeatTimer(mockIsActive, mockBeatFn)
125+
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
126+
await heart.beat()
127+
jest.advanceTimersByTime(60 * 1000)
128+
119129
expect(mockIsActive).toHaveBeenCalled()
120-
expect(mockBeatFn).not.toHaveBeenCalled()
121130
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
122131
})
123132
})
124133

125-
describe("idleTimeout", () => {
126-
const testName = "idleHeartTests"
134+
describe("stateChange", () => {
135+
const testName = "stateChange"
127136
let testDir = ""
128137
let heart: Heart
129138
beforeAll(async () => {
@@ -140,12 +149,23 @@ describe("idleTimeout", () => {
140149
heart.dispose()
141150
}
142151
})
143-
it("should call beat when isActive resolves to true", async () => {
152+
it("should change to alive after a beat", async () => {
153+
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
154+
const mockOnChange = jest.fn()
155+
heart.onChange(mockOnChange)
156+
await heart.beat()
157+
158+
expect(mockOnChange.mock.calls[0][0]).toBe("alive")
159+
})
160+
it.only("should change to idle when not active", async () => {
144161
jest.useFakeTimers()
145-
heart = new Heart(`${testDir}/shutdown.txt`, 60, mockIsActive(true))
162+
heart = new Heart(`${testDir}/shutdown.txt`, () => new Promise((resolve) => resolve(false)))
163+
const mockOnChange = jest.fn()
164+
heart.onChange(mockOnChange)
165+
await heart.beat()
146166

147-
jest.advanceTimersByTime(60 * 1000)
148-
expect(wrapper.exit).toHaveBeenCalled()
167+
await jest.advanceTimersByTime(60 * 1000)
168+
expect(mockOnChange.mock.calls[1][0]).toBe("idle")
149169
jest.clearAllTimers()
150170
jest.useRealTimers()
151171
})

0 commit comments

Comments
 (0)