// Waiting files whose buffered copy is gone are listed; uploaded files, // files with their copy, and very recent changes are not. import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { DatabaseSync } from 'node:sqlite'; import { stuckUploads } from '../core/stuck.js'; test('stuck uploads: missing copy, still waiting, not brand new', async (t) => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'pithos-stuck-')); t.after(() => fs.rmSync(dir, { recursive: true, force: true })); fs.mkdirSync(path.join(dir, 'uploads')); const db = new DatabaseSync(path.join(dir, 's3d.db')); db.exec(`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT); CREATE TABLE buckets (id INTEGER PRIMARY KEY, name TEXT, user_id INTEGER); CREATE TABLE objects (bucket_id INTEGER, name TEXT, is_latest INTEGER, is_delete_marker INTEGER, size INTEGER, updated_at INTEGER, filename TEXT, sia_object_id BLOB); INSERT INTO users VALUES (1, 'game.x'); INSERT INTO buckets VALUES (1, 'house-music', 1);`); const old = Math.floor(Date.now() / 1000) - 3600; const now = Math.floor(Date.now() / 1000); const add = db.prepare('INSERT INTO objects VALUES (1, ?, 1, 0, ?, ?, ?, ?)'); add.run('lost.mp3', 5000, old, 'aaaa.obj', null); // stuck add.run('waiting.mp3', 4000, old, 'bbbb.obj', null); // copy present add.run('uploaded.mp3', 3000, old, null, Buffer.from([1])); // on Sia add.run('just-now.mp3', 2000, now, 'cccc.obj', null); // too recent to judge db.prepare('INSERT INTO objects VALUES (1, ?, 0, 0, ?, ?, ?, NULL)').run('old-version.mp3', 1, old, 'dddd.obj'); // not latest db.close(); fs.writeFileSync(path.join(dir, 'uploads', 'bbbb.obj'), 'x'); const items = await stuckUploads(dir, { settleMs: 10 }); assert.deepEqual(items, [{ bucket: 'house-music', user: 'game.x', key: 'lost.mp3', size: 5000, filename: 'aaaa.obj' }]); assert.deepEqual(await stuckUploads(path.join(dir, 'nope'), { settleMs: 10 }), []); });