11import { logger } from "@coder/logger"
22import { readFile , writeFile , stat , utimes } from "fs/promises"
33import { Heart , heartbeatTimer } from "../../../src/node/heart"
4+ import { wrapper } from "../../../src/node/wrapper"
45import { clean , mockLogger , tmpdir } from "../../utils/helpers"
56
67const mockIsActive = ( resolveTo : boolean ) => jest . fn ( ) . mockResolvedValue ( resolveTo )
78
9+ jest . mock ( "../../../src/node/wrapper" , ( ) => {
10+ const original = jest . requireActual ( "../../../src/node/wrapper" )
11+ return {
12+ ...original ,
13+ wrapper : {
14+ exit : jest . fn ( ) ,
15+ } ,
16+ }
17+ } )
18+
819describe ( "Heart" , ( ) => {
920 const testName = "heartTests"
1021 let testDir = ""
@@ -16,7 +27,7 @@ describe("Heart", () => {
1627 testDir = await tmpdir ( testName )
1728 } )
1829 beforeEach ( ( ) => {
19- heart = new Heart ( `${ testDir } /shutdown.txt` , mockIsActive ( true ) )
30+ heart = new Heart ( `${ testDir } /shutdown.txt` , undefined , mockIsActive ( true ) )
2031 } )
2132 afterAll ( ( ) => {
2233 jest . restoreAllMocks ( )
@@ -42,7 +53,7 @@ describe("Heart", () => {
4253
4354 expect ( fileContents ) . toBe ( text )
4455
45- heart = new Heart ( pathToFile , mockIsActive ( true ) )
56+ heart = new Heart ( pathToFile , undefined , mockIsActive ( true ) )
4657 await heart . beat ( )
4758 // Check that the heart wrote to the heartbeatFilePath and overwrote our text
4859 const fileContentsAfterBeat = await readFile ( pathToFile , { encoding : "utf8" } )
@@ -52,7 +63,7 @@ describe("Heart", () => {
5263 expect ( fileStatusAfterEdit . mtimeMs ) . toBeGreaterThan ( 0 )
5364 } )
5465 it ( "should log a warning when given an invalid file path" , async ( ) => {
55- heart = new Heart ( `fakeDir/fake.txt` , mockIsActive ( false ) )
66+ heart = new Heart ( `fakeDir/fake.txt` , undefined , mockIsActive ( false ) )
5667 await heart . beat ( )
5768 expect ( logger . warn ) . toHaveBeenCalled ( )
5869 } )
@@ -71,7 +82,7 @@ describe("Heart", () => {
7182 it ( "should beat twice without warnings" , async ( ) => {
7283 // Use fake timers so we can speed up setTimeout
7384 jest . useFakeTimers ( )
74- heart = new Heart ( `${ testDir } /hello.txt` , mockIsActive ( true ) )
85+ heart = new Heart ( `${ testDir } /hello.txt` , undefined , mockIsActive ( true ) )
7586 await heart . beat ( )
7687 // we need to speed up clocks, timeouts
7788 // call heartbeat again (and it won't be alive I think)
@@ -110,3 +121,32 @@ describe("heartbeatTimer", () => {
110121 expect ( logger . warn ) . toHaveBeenCalledWith ( errorMsg )
111122 } )
112123} )
124+
125+ describe ( "idleTimeout" , ( ) => {
126+ const testName = "idleHeartTests"
127+ let testDir = ""
128+ let heart : Heart
129+ beforeAll ( async ( ) => {
130+ await clean ( testName )
131+ testDir = await tmpdir ( testName )
132+ mockLogger ( )
133+ } )
134+ afterAll ( ( ) => {
135+ jest . restoreAllMocks ( )
136+ } )
137+ afterEach ( ( ) => {
138+ jest . resetAllMocks ( )
139+ if ( heart ) {
140+ heart . dispose ( )
141+ }
142+ } )
143+ it ( "should call beat when isActive resolves to true" , async ( ) => {
144+ jest . useFakeTimers ( )
145+ heart = new Heart ( `${ testDir } /shutdown.txt` , 60 , mockIsActive ( true ) )
146+
147+ jest . advanceTimersByTime ( 60 * 1000 )
148+ expect ( wrapper . exit ) . toHaveBeenCalled ( )
149+ jest . clearAllTimers ( )
150+ jest . useRealTimers ( )
151+ } )
152+ } )
0 commit comments