Files
hermes-agent/apps/desktop/electron/linux-crash-diagnostics.test.ts
hermes-seaeye[bot] bc655bfb40 fmt(js): npm run fix on merge (#118250)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-21 14:41:52 +00:00

86 lines
3.2 KiB
TypeScript

import assert from 'node:assert/strict'
import path from 'node:path'
import { test } from 'vitest'
import { CHROMIUM_LOG_FILENAME, enableLinuxCrashDiagnostics, linuxCrashDiagnostics } from './linux-crash-diagnostics'
// Regression for #100573: the Linux shell died with SIGTRAP at Chromium's
// shared fatal-handler address and no launcher kept the FATAL message. The
// fix is not a guess at the cause; it is making the next crash legible.
test('on linux, fatal Chromium output lands in a file under the Hermes logs dir', () => {
const plan = linuxCrashDiagnostics('/home/u/.hermes/logs', 'linux')
assert.ok(plan)
const switches = new Map(plan.switches)
assert.equal(switches.get('enable-logging'), 'file')
const logFile = switches.get('log-file')
assert.ok(logFile)
assert.equal(path.dirname(logFile), '/home/u/.hermes/logs')
// FATAL (3) must survive the level filter; anything stricter would drop it.
assert.ok(Number(switches.get('log-level')) <= 3)
assert.equal(plan.crashReporter.uploadToServer, false)
})
test('other platforms get no Chromium logging switches and no crash reporter', () => {
assert.equal(linuxCrashDiagnostics('/Users/u/.hermes/logs', 'darwin'), null)
assert.equal(linuxCrashDiagnostics('C:\\Users\\u\\.hermes\\logs', 'win32'), null)
})
test('a logs dir that cannot be created degrades to no logging, never a dead shell', () => {
const switches: string[] = []
let reporterStarted = false
// Read-only or invalid HERMES_HOME/logs: mkdir throws before app readiness.
enableLinuxCrashDiagnostics(linuxCrashDiagnostics('/read-only/logs', 'linux'), '/read-only/logs', {
ensureLogsDir: () => {
throw new Error('EROFS: read-only file system')
},
reclaimChromiumLog: () => assert.fail('must not touch a log dir that does not exist'),
appendSwitch: name => switches.push(name),
startCrashReporter: () => {
reporterStarted = true
}
})
// No log-file switch (Chromium could not have opened it anyway), and the
// crash reporter — which writes elsewhere — still runs.
assert.deepEqual(switches, [])
assert.equal(reporterStarted, true)
})
test('a crash reporter that refuses to start is not fatal either', () => {
const switches: string[] = []
enableLinuxCrashDiagnostics(linuxCrashDiagnostics('/home/u/.hermes/logs', 'linux'), '/home/u/.hermes/logs', {
ensureLogsDir: () => {},
reclaimChromiumLog: () => {},
appendSwitch: name => switches.push(name),
startCrashReporter: () => {
throw new Error('crashpad handler missing')
}
})
assert.ok(switches.includes('log-file'))
})
test('the Chromium log is bounded before Chromium appends to it', () => {
const reclaimed: string[] = []
enableLinuxCrashDiagnostics(linuxCrashDiagnostics('/home/u/.hermes/logs', 'linux'), '/home/u/.hermes/logs', {
ensureLogsDir: () => {},
reclaimChromiumLog: file => reclaimed.push(file),
appendSwitch: () => {},
startCrashReporter: () => {}
})
// Electron opens an explicit --log-file with APPEND_TO_OLD_LOG_FILE, so the
// file it is about to append to is exactly the one that must be reclaimed.
assert.deepEqual(reclaimed, [path.join('/home/u/.hermes/logs', CHROMIUM_LOG_FILENAME)])
})