/** * @module tests/unit/utils/osLimits * @description OS-limit detection for pool-scale use. Laws: * (1) the /proc/self/limits parser reads soft/hard NOFILE exactly, including * 'unlimited'; (2) assessment warns ONLY below the pool floors and NEVER * on an unreadable (null) limit — no measurement, no claim; (3) the full * check composes both sources and survives unreadable /proc silently. */ import { describe, it, expect } from 'vitest' import { parseProcLimits, assessOsLimits, checkOsLimits, NOFILE_POOL_FLOOR, MAX_MAP_COUNT_POOL_FLOOR } from '../../../src/utils/osLimits.js' const SAMPLE_LIMITS = [ 'Limit Soft Limit Hard Limit Units', 'Max cpu time unlimited unlimited seconds', 'Max open files 1024 1048576 files', 'Max locked memory 8388608 8388608 bytes' ].join('\n') describe('osLimits — detect + warn at pool scale', () => { it('parses soft/hard NOFILE from /proc/self/limits, including unlimited', () => { expect(parseProcLimits(SAMPLE_LIMITS)).toEqual({ soft: 1024, hard: 1048576 }) expect( parseProcLimits('Max open files unlimited unlimited files') ).toEqual({ soft: Infinity, hard: Infinity }) expect(parseProcLimits('no such row here')).toEqual({ soft: null, hard: null }) }) it('warns below the floors, stays quiet at or above them', () => { const low = assessOsLimits({ nofileSoft: 1024, nofileHard: 1048576, maxMapCount: 65530 }) expect(low).toHaveLength(2) expect(low[0]).toContain('RLIMIT_NOFILE soft limit is 1024') expect(low[0]).toContain(`ulimit -n ${NOFILE_POOL_FLOOR}`) expect(low[0]).toContain('raise the soft limit only') // hard already allows it expect(low[1]).toContain('vm.max_map_count is 65530') expect(low[1]).toContain(`vm.max_map_count=${MAX_MAP_COUNT_POOL_FLOOR}`) expect( assessOsLimits({ nofileSoft: NOFILE_POOL_FLOOR, nofileHard: Infinity, maxMapCount: MAX_MAP_COUNT_POOL_FLOOR }) ).toEqual([]) }) it('an unreadable limit makes NO claim — nulls never warn', () => { expect(assessOsLimits({ nofileSoft: null, nofileHard: null, maxMapCount: null })).toEqual([]) }) it('checkOsLimits composes both sources and survives unreadable /proc silently', async () => { const report = await checkOsLimits(async (p) => { if (p === '/proc/self/limits') return SAMPLE_LIMITS if (p === '/proc/sys/vm/max_map_count') return '65530\n' throw new Error('unexpected path') }) expect(report.nofileSoft).toBe(1024) expect(report.maxMapCount).toBe(65530) expect(report.warnings).toHaveLength(2) const offLinux = await checkOsLimits(async () => { throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' }) }) expect(offLinux).toEqual({ nofileSoft: null, nofileHard: null, maxMapCount: null, warnings: [] }) }) })