import test from 'node:test'; import assert from 'node:assert/strict'; import { validateComposeModel } from '../runtime/validate-compose-model.mjs'; const safeRuntime = { environment: { CORE_SOURCE_MODE: 'clone', NODE_OPTIONS: '--max-old-space-size=1536', RAYON_NUM_THREADS: '2', }, restart: 'unless-stopped', mem_limit: String(4 * 1024 * 1024 * 1024), memswap_limit: String(4 * 1024 * 1024 * 1024), cpus: 4, pids_limit: 256, }; test('accepts a bounded production runtime', () => { assert.deepEqual(validateComposeModel({ services: { runtime: safeRuntime } }, 'production'), []); }); test('accepts a literal, non-restarting development model', () => { const services = Object.fromEntries(['postgres', 'redis', 'caddy'].map((name) => [name, { restart: 'no' }])); services.runtime = { ...safeRuntime, restart: 'no', environment: { CORE_SOURCE_MODE: 'bind', RUNTIME_MODE: 'development', NODE_OPTIONS: '--max-old-space-size=1536', RAYON_NUM_THREADS: '2', }, }; assert.deepEqual(validateComposeModel({ services }, 'development'), []); }); test('accepts a bounded, non-restarting production smoke model', () => { const services = Object.fromEntries(['postgres', 'redis', 'caddy'].map((name) => [name, { restart: 'no' }])); services.runtime = { ...safeRuntime, restart: 'no' }; assert.deepEqual(validateComposeModel({ services }, 'smoke'), []); }); test('rejects an unbounded or production-mode development runtime', () => { const services = Object.fromEntries(['postgres', 'redis', 'caddy'].map((name) => [name, { restart: 'unless-stopped' }])); services.runtime = { environment: { CORE_SOURCE_MODE: 'bind', RUNTIME_MODE: 'production' }, restart: 'unless-stopped', mem_limit: 0, memswap_limit: 0, cpus: 0, pids_limit: 0, }; const errors = validateComposeModel({ services }, 'development'); assert.ok(errors.some((error) => error.includes('memory limit must be positive'))); assert.ok(errors.some((error) => error.includes('literal development'))); assert.ok(errors.some((error) => error.includes('restart policy must be no'))); }); test('rejects missing or excessive build memory and parallelism limits', () => { const runtime = { ...safeRuntime, environment: { CORE_SOURCE_MODE: 'clone', NODE_OPTIONS: '--max-old-space-size=4096', RAYON_NUM_THREADS: '8', }, }; const errors = validateComposeModel({ services: { runtime } }, 'production'); assert.ok(errors.some((error) => error.includes('Node heap limit'))); assert.ok(errors.some((error) => error.includes('Rayon thread count'))); });