Skip to content

Commit 5e98936

Browse files
committed
crasher tests
1 parent d058742 commit 5e98936

File tree

6 files changed

+120
-4
lines changed

6 files changed

+120
-4
lines changed

test/crasher.test.js

+63-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,68 @@
11
'use strict'
22

33
const { test } = require('brittle')
4+
const path = require('bare-path')
5+
const fs = require('bare-fs')
6+
const os = require('bare-os')
47

5-
test('crasher', async function (t) {
6-
// TODO: write tests
8+
const Helper = require('./helper')
9+
10+
const dirname = __dirname
11+
12+
test('crasher uncaught exception', async function (t) {
13+
const dir = path.join(dirname, 'fixtures', 'run-crasher-uncaught-exception')
14+
15+
const teardown = Helper.rig({ runtimeArgv: [dir] })
16+
t.teardown(teardown)
17+
18+
const swap = path.join(os.tmpdir(), `${Date.now()}`)
19+
await fs.promises.mkdir(swap)
20+
const pipe = Pear.run(dir, [swap])
21+
pipe.on('error', (err) => {
22+
if (err.code === 'ENOTCONN') return // when the other side destroys the pipe
23+
throw err
24+
})
25+
26+
const pid = await Helper.untilResult(pipe)
27+
await Helper.untilExit(pid)
28+
29+
const crashlogPath = path.join(swap, 'testProcess.crash.log')
30+
await Helper.untilExists(crashlogPath)
31+
t.ok(fs.existsSync(crashlogPath), 'Crash log file should be created')
32+
33+
await Helper.untilHandler(async () => {
34+
const logContent = await fs.promises.readFile(crashlogPath, 'utf8')
35+
return logContent.includes('Test uncaught exception')
36+
})
37+
const logContent = await fs.promises.readFile(crashlogPath, 'utf8')
38+
t.ok(logContent.includes('Test uncaught exception'), 'Log should contain the error message')
39+
})
40+
41+
test('crasher unhandled rejection', async function (t) {
42+
const dir = path.join(dirname, 'fixtures', 'run-crasher-unhandled-rejection')
43+
44+
const teardown = Helper.rig({ runtimeArgv: [dir] })
45+
t.teardown(teardown)
46+
47+
const swap = path.join(os.tmpdir(), `${Date.now()}`)
48+
await fs.promises.mkdir(swap)
49+
const pipe = Pear.run(dir, [swap])
50+
pipe.on('error', (err) => {
51+
if (err.code === 'ENOTCONN') return // when the other side destroys the pipe
52+
throw err
53+
})
54+
55+
const pid = await Helper.untilResult(pipe)
56+
await Helper.untilExit(pid)
57+
58+
const crashlogPath = path.join(swap, 'testProcess.crash.log')
59+
await Helper.untilExists(crashlogPath)
60+
t.ok(fs.existsSync(crashlogPath), 'Crash log file should be created')
61+
62+
await Helper.untilHandler(async () => {
63+
const logContent = await fs.promises.readFile(crashlogPath, 'utf8')
64+
return logContent.includes('Test unhandled rejection')
65+
})
66+
const logContent = await fs.promises.readFile(crashlogPath, 'utf8')
67+
t.ok(logContent.includes('Test unhandled rejection'), 'Log should contain the error message')
768
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const Helper = require('../../helper')
2+
3+
Helper.rig({ state: { config: { args: Bare.argv.slice(4) } } })
4+
const [swap] = Pear.config.args
5+
6+
const setupCrashHandlers = require('../../../crasher')
7+
setupCrashHandlers('testProcess', swap, true)
8+
9+
const main = async () => {
10+
const pipe = Pear.pipe
11+
pipe.write(`${Bare.pid}\n`)
12+
13+
await new Promise((resolve) => setTimeout(resolve, 1000))
14+
throw new Error('Test uncaught exception')
15+
}
16+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const Helper = require('../../helper')
2+
3+
Helper.rig({ state: { config: { args: Bare.argv.slice(4) } } })
4+
const [swap] = Pear.config.args
5+
6+
const setupCrashHandlers = require('../../../crasher')
7+
setupCrashHandlers('testProcess', swap, true)
8+
9+
const main = async () => {
10+
const pipe = Pear.pipe
11+
pipe.write(`${Bare.pid}\n`)
12+
13+
await new Promise((resolve) => setTimeout(resolve, 1000))
14+
await new Promise((resolve, reject) => reject(new Error('Test unhandled rejection')))
15+
}
16+
main()

test/helper.js

+23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ global.Pear = null
33

44
const { isWindows } = require('which-runtime')
55
const IPC = require('pear-ipc')
6+
const fs = require('bare-fs')
67

78
const dirname = __dirname
89
const socketPath = isWindows ? '\\\\.\\pipe\\pear-api-test-ipc' : 'test.sock'
@@ -109,6 +110,28 @@ class Helper {
109110
}
110111
}
111112

113+
static async untilExists (path, timeout = 5000, start = Date.now()) {
114+
if (Date.now() - start > timeout) throw new Error('timed out')
115+
try {
116+
await fs.promises.stat(path)
117+
return true
118+
} catch (err) {
119+
if (err.code !== 'ENOENT') throw err
120+
}
121+
await new Promise((resolve) => setTimeout(resolve, 100))
122+
await Helper.untilExists(path, timeout, start)
123+
}
124+
125+
static async untilHandler (handler, timeout = 5000, start = Date.now()) {
126+
if (Date.now() - start > timeout) throw new Error('timed out')
127+
try {
128+
const res = await handler()
129+
if (res) return res
130+
} catch {}
131+
await new Promise((resolve) => setTimeout(resolve, 100))
132+
await Helper.untilHandler(handler, timeout, start)
133+
}
134+
112135
static async startIpcClient () {
113136
const client = new IPC.Client({
114137
socketPath

test/index.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const { test } = require('brittle')
44
const { isWindows } = require('which-runtime')
5-
const path = require('path')
5+
const path = require('bare-path')
66
const os = require('bare-os')
77
const Iambus = require('iambus')
88

test/worker.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const { test } = require('brittle')
4-
const path = require('path')
4+
const path = require('bare-path')
55

66
const dirname = __dirname
77
global.Pear = null

0 commit comments

Comments
 (0)