mirror of
https://github.com/cdr/code-server.git
synced 2025-12-07 17:02:27 +01:00
Update unit tests
This commit is contained in:
parent
ea538ed79e
commit
cecb83018f
2 changed files with 44 additions and 33 deletions
|
|
@ -1,21 +1,10 @@
|
||||||
import { logger } from "@coder/logger"
|
import { logger } from "@coder/logger"
|
||||||
import { readFile, writeFile, stat, utimes } from "fs/promises"
|
import { readFile, writeFile, stat, utimes } from "fs/promises"
|
||||||
import { Heart, heartbeatTimer } from "../../../src/node/heart"
|
import { Heart } from "../../../src/node/heart"
|
||||||
import { wrapper } from "../../../src/node/wrapper"
|
|
||||||
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
|
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
|
||||||
|
|
||||||
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
|
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
|
||||||
|
|
||||||
jest.mock("../../../src/node/wrapper", () => {
|
|
||||||
const original = jest.requireActual("../../../src/node/wrapper")
|
|
||||||
return {
|
|
||||||
...original,
|
|
||||||
wrapper: {
|
|
||||||
exit: jest.fn(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
describe("Heart", () => {
|
describe("Heart", () => {
|
||||||
const testName = "heartTests"
|
const testName = "heartTests"
|
||||||
let testDir = ""
|
let testDir = ""
|
||||||
|
|
@ -27,7 +16,7 @@ describe("Heart", () => {
|
||||||
testDir = await tmpdir(testName)
|
testDir = await tmpdir(testName)
|
||||||
})
|
})
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
heart = new Heart(`${testDir}/shutdown.txt`, undefined, mockIsActive(true))
|
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
|
||||||
})
|
})
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
jest.restoreAllMocks()
|
jest.restoreAllMocks()
|
||||||
|
|
@ -53,7 +42,7 @@ describe("Heart", () => {
|
||||||
|
|
||||||
expect(fileContents).toBe(text)
|
expect(fileContents).toBe(text)
|
||||||
|
|
||||||
heart = new Heart(pathToFile, undefined, mockIsActive(true))
|
heart = new Heart(pathToFile, mockIsActive(true))
|
||||||
await heart.beat()
|
await heart.beat()
|
||||||
// Check that the heart wrote to the heartbeatFilePath and overwrote our text
|
// Check that the heart wrote to the heartbeatFilePath and overwrote our text
|
||||||
const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" })
|
const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" })
|
||||||
|
|
@ -63,7 +52,7 @@ describe("Heart", () => {
|
||||||
expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(0)
|
expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(0)
|
||||||
})
|
})
|
||||||
it("should log a warning when given an invalid file path", async () => {
|
it("should log a warning when given an invalid file path", async () => {
|
||||||
heart = new Heart(`fakeDir/fake.txt`, undefined, mockIsActive(false))
|
heart = new Heart(`fakeDir/fake.txt`, mockIsActive(false))
|
||||||
await heart.beat()
|
await heart.beat()
|
||||||
expect(logger.warn).toHaveBeenCalled()
|
expect(logger.warn).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
@ -82,7 +71,7 @@ describe("Heart", () => {
|
||||||
it("should beat twice without warnings", async () => {
|
it("should beat twice without warnings", async () => {
|
||||||
// Use fake timers so we can speed up setTimeout
|
// Use fake timers so we can speed up setTimeout
|
||||||
jest.useFakeTimers()
|
jest.useFakeTimers()
|
||||||
heart = new Heart(`${testDir}/hello.txt`, undefined, mockIsActive(true))
|
heart = new Heart(`${testDir}/hello.txt`, mockIsActive(true))
|
||||||
await heart.beat()
|
await heart.beat()
|
||||||
// we need to speed up clocks, timeouts
|
// we need to speed up clocks, timeouts
|
||||||
// call heartbeat again (and it won't be alive I think)
|
// call heartbeat again (and it won't be alive I think)
|
||||||
|
|
@ -93,37 +82,47 @@ describe("Heart", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("heartbeatTimer", () => {
|
describe("heartbeatTimer", () => {
|
||||||
beforeAll(() => {
|
const testName = "heartbeatTimer"
|
||||||
|
let testDir = ""
|
||||||
|
beforeAll(async () => {
|
||||||
|
await clean(testName)
|
||||||
|
testDir = await tmpdir(testName)
|
||||||
mockLogger()
|
mockLogger()
|
||||||
})
|
})
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
jest.restoreAllMocks()
|
jest.restoreAllMocks()
|
||||||
})
|
})
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers()
|
||||||
|
})
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks()
|
jest.resetAllMocks()
|
||||||
|
jest.clearAllTimers()
|
||||||
|
jest.useRealTimers()
|
||||||
})
|
})
|
||||||
it("should call beat when isActive resolves to true", async () => {
|
it("should call isActive when timeout expires", async () => {
|
||||||
const isActive = true
|
const isActive = true
|
||||||
const mockIsActive = jest.fn().mockResolvedValue(isActive)
|
const mockIsActive = jest.fn().mockResolvedValue(isActive)
|
||||||
const mockBeatFn = jest.fn()
|
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
|
||||||
await heartbeatTimer(mockIsActive, mockBeatFn)
|
await heart.beat()
|
||||||
|
jest.advanceTimersByTime(60 * 1000)
|
||||||
expect(mockIsActive).toHaveBeenCalled()
|
expect(mockIsActive).toHaveBeenCalled()
|
||||||
expect(mockBeatFn).toHaveBeenCalled()
|
|
||||||
})
|
})
|
||||||
it("should log a warning when isActive rejects", async () => {
|
it("should log a warning when isActive rejects", async () => {
|
||||||
const errorMsg = "oh no"
|
const errorMsg = "oh no"
|
||||||
const error = new Error(errorMsg)
|
const error = new Error(errorMsg)
|
||||||
const mockIsActive = jest.fn().mockRejectedValue(error)
|
const mockIsActive = jest.fn().mockRejectedValue(error)
|
||||||
const mockBeatFn = jest.fn()
|
const heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive)
|
||||||
await heartbeatTimer(mockIsActive, mockBeatFn)
|
await heart.beat()
|
||||||
|
jest.advanceTimersByTime(60 * 1000)
|
||||||
|
|
||||||
expect(mockIsActive).toHaveBeenCalled()
|
expect(mockIsActive).toHaveBeenCalled()
|
||||||
expect(mockBeatFn).not.toHaveBeenCalled()
|
|
||||||
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
|
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("idleTimeout", () => {
|
describe("stateChange", () => {
|
||||||
const testName = "idleHeartTests"
|
const testName = "stateChange"
|
||||||
let testDir = ""
|
let testDir = ""
|
||||||
let heart: Heart
|
let heart: Heart
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
|
@ -140,12 +139,23 @@ describe("idleTimeout", () => {
|
||||||
heart.dispose()
|
heart.dispose()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it("should call beat when isActive resolves to true", async () => {
|
it("should change to alive after a beat", async () => {
|
||||||
jest.useFakeTimers()
|
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
|
||||||
heart = new Heart(`${testDir}/shutdown.txt`, 60, mockIsActive(true))
|
const mockOnChange = jest.fn()
|
||||||
|
heart.onChange(mockOnChange)
|
||||||
|
await heart.beat()
|
||||||
|
|
||||||
jest.advanceTimersByTime(60 * 1000)
|
expect(mockOnChange.mock.calls[0][0]).toBe("alive")
|
||||||
expect(wrapper.exit).toHaveBeenCalled()
|
})
|
||||||
|
it.only("should change to idle when not active", async () => {
|
||||||
|
jest.useFakeTimers()
|
||||||
|
heart = new Heart(`${testDir}/shutdown.txt`, () => new Promise((resolve) => resolve(false)))
|
||||||
|
const mockOnChange = jest.fn()
|
||||||
|
heart.onChange(mockOnChange)
|
||||||
|
await heart.beat()
|
||||||
|
|
||||||
|
await jest.advanceTimersByTime(60 * 1000)
|
||||||
|
expect(mockOnChange.mock.calls[1][0]).toBe("idle")
|
||||||
jest.clearAllTimers()
|
jest.clearAllTimers()
|
||||||
jest.useRealTimers()
|
jest.useRealTimers()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ jest.mock("@coder/logger", () => ({
|
||||||
debug: jest.fn(),
|
debug: jest.fn(),
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
error: jest.fn(),
|
error: jest.fn(),
|
||||||
|
named: jest.fn(),
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
field: jest.fn(),
|
field: jest.fn(),
|
||||||
|
|
@ -94,7 +95,7 @@ describe("main", () => {
|
||||||
|
|
||||||
// Mock routes module
|
// Mock routes module
|
||||||
jest.doMock("../../../src/node/routes", () => ({
|
jest.doMock("../../../src/node/routes", () => ({
|
||||||
register: jest.fn().mockResolvedValue(jest.fn()),
|
register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Mock loadCustomStrings to succeed
|
// Mock loadCustomStrings to succeed
|
||||||
|
|
@ -131,7 +132,7 @@ describe("main", () => {
|
||||||
|
|
||||||
// Mock routes module
|
// Mock routes module
|
||||||
jest.doMock("../../../src/node/routes", () => ({
|
jest.doMock("../../../src/node/routes", () => ({
|
||||||
register: jest.fn().mockResolvedValue(jest.fn()),
|
register: jest.fn().mockResolvedValue({ disposeRoutes: jest.fn() }),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Import runCodeServer after mocking
|
// Import runCodeServer after mocking
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue