Repository Public
1import { execFileSync, spawn, type ChildProcess } from 'node:child_process';2import { randomBytes } from 'node:crypto';3import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';4import { homedir } from 'node:os';5import { join } from 'node:path';67const ROOT = '/tmp/sp-drive-test';8const CLAM_DB = process.env.SPD_TEST_CLAMAV_DB ?? join(homedir(), '.cache/sp-drive-clamav');9let clamd: ChildProcess | undefined;1011export async function setup(): Promise<void> {12 rmSync(ROOT, { recursive: true, force: true });13 mkdirSync(join(ROOT, 'data'), { recursive: true });14 writeFileSync(join(ROOT, 'master.key'), `${randomBytes(32).toString('hex')}\n`, { mode: 0o600 });15 const pg = (bin: string, ...args: string[]) => execFileSync(existsSync(`/opt/homebrew/opt/postgresql@17/bin/${bin}`) ? `/opt/homebrew/opt/postgresql@17/bin/${bin}` : bin, ['-h', '127.0.0.1', ...args], { stdio: 'pipe' });16 pg('dropdb', '--if-exists', 'sp_drive_test');17 pg('createdb', 'sp_drive_test');18 // a real antivirus daemon when its signatures are available (brew install clamav + freshclam); otherwise the AV tests fail loudly19 if (existsSync(join(CLAM_DB, 'main.cvd')) || existsSync(join(CLAM_DB, 'main.cld'))) {20 const conf = join(ROOT, 'clamd.conf');21 writeFileSync(conf, `LocalSocket ${ROOT}/clamd.sock\nDatabaseDirectory ${CLAM_DB}\nForeground yes\nStreamMaxLength 4000M\nMaxFileSize 2000M\nMaxScanSize 4000M\nLogFile ${ROOT}/clamd.log\n`);22 clamd = spawn('/opt/homebrew/sbin/clamd', ['-c', conf], { stdio: 'ignore' });23 const t0 = Date.now();24 while (!existsSync(`${ROOT}/clamd.sock`)) { if (Date.now() - t0 > 150_000) throw new Error('clamd did not start'); await new Promise((r) => setTimeout(r, 500)); }25 }26}27export async function teardown(): Promise<void> { clamd?.kill('SIGTERM'); }28