Files
SnowLuma/packages/bridge/tests/hook-runtime-dir.test.ts
DrSmoothl 8526d0c2c5 fix(bridge): restore active sessions after delayed startup
Allow SnowLuma to discover and restore accounts that were already active before startup.

Avoid reporting sessions ready before they can serve requests, preserve account changes, and keep discovery failures observable.

Add regression coverage for delayed startup, recovery, and process isolation.

Refs #305

Refs #307
2026-08-03 10:49:47 +08:00

68 lines
2.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { resolveHookRuntimeDir } from '../src/hook-runtime-dir';
function procReader(files: Record<string, string>) {
return (file: string): string => {
const value = files[file];
if (value === undefined) throw new Error(`missing fixture: ${file}`);
return value;
};
}
describe('resolveHookRuntimeDir — Linux target process ownership', () => {
it('uses the QQ process runtime directory instead of the supervisor user directory', () => {
expect(resolveHookRuntimeDir(46301, {
platform: 'linux',
env: { XDG_RUNTIME_DIR: '/run/user/0' },
ownUid: 0,
readText: procReader({
'/proc/46301/environ': 'HOME=/home/rikka\0XDG_RUNTIME_DIR=/run/user/1000\0',
'/proc/46301/status': 'Name:\tqq\nUid:\t1000\t1000\t1000\t1000\n',
}),
})).toBe('/run/user/1000');
});
it('falls back to the QQ process uid when its environment has no runtime directory', () => {
expect(resolveHookRuntimeDir(46301, {
platform: 'linux',
env: { XDG_RUNTIME_DIR: '/run/user/0' },
ownUid: 0,
readText: procReader({
'/proc/46301/environ': 'HOME=/home/rikka\0',
'/proc/46301/status': 'Name:\tqq\nUid:\t1000\t1000\t1000\t1000\n',
}),
})).toBe('/tmp/snowluma-1000');
});
it('fails visibly when target ownership cannot be determined', () => {
expect(() => resolveHookRuntimeDir(46301, {
platform: 'linux',
env: { XDG_RUNTIME_DIR: '/run/user/0' },
ownUid: 0,
readText: () => { throw new Error('permission denied'); },
})).toThrow(/cannot resolve hook runtime directory.*permission denied/);
});
it('uses the current convention when the target disappears during discovery', () => {
const gone = Object.assign(new Error('process disappeared'), { code: 'ENOENT' });
expect(resolveHookRuntimeDir(46301, {
platform: 'linux',
env: { XDG_RUNTIME_DIR: '/run/user/0' },
ownUid: 0,
readText: () => { throw gone; },
})).toBe('/run/user/0');
});
it('honours an explicit runtime directory inherited by the QQ process', () => {
expect(resolveHookRuntimeDir(46301, {
platform: 'linux',
env: {},
ownUid: 0,
readText: procReader({
'/proc/46301/environ': 'SNOWLUMA_HOOK_RUNTIME_DIR=/srv/snowluma-hook\0',
'/proc/46301/status': 'Uid:\t1000\t1000\t1000\t1000\n',
}),
})).toBe('/srv/snowluma-hook');
});
});