Files
qinglong/test/back/retention.test.cjs
T

132 lines
4.3 KiB
JavaScript

const assert = require('node:assert/strict');
const fs = require('node:fs/promises');
const os = require('node:os');
const path = require('node:path');
const test = require('node:test');
const { Op } = require('sequelize');
const {
getDirectorySize,
normalizeRetentionPolicy,
} = require('../../back/shared/retention');
test('retention policy defaults to disabled and clamps invalid values', () => {
assert.deepEqual(normalizeRetentionPolicy({}), {
runningInstanceRetentionDays: 0,
cronStatRetentionDays: 0,
});
assert.deepEqual(
normalizeRetentionPolicy({
runningInstanceRetentionDays: -10,
cronStatRetentionDays: 99999,
}),
{
runningInstanceRetentionDays: 0,
cronStatRetentionDays: 3650,
},
);
});
test('directory preview counts files recursively and ignores symlinks', async (t) => {
const directory = await fs.mkdtemp(path.join(os.tmpdir(), 'ql-retention-'));
const nested = path.join(directory, 'nested');
t.after(() => fs.rm(directory, { recursive: true, force: true }));
await fs.mkdir(nested);
await fs.writeFile(path.join(directory, 'one'), Buffer.alloc(7));
await fs.writeFile(path.join(nested, 'two'), Buffer.alloc(11));
await fs.symlink(path.join(nested, 'two'), path.join(directory, 'link'));
assert.equal(await getDirectorySize(directory), 18);
assert.equal(await getDirectorySize(path.join(directory, 'missing')), 0);
});
test('cleanup previews first, protects running instances, and uses explicit options', async (t) => {
const directory = await fs.mkdtemp(path.join(os.tmpdir(), 'ql-retention-'));
const nodeCache = path.join(directory, 'node');
await fs.mkdir(nodeCache);
await fs.writeFile(path.join(nodeCache, 'cache'), Buffer.alloc(13));
const config = require('../../back/config').default;
const originalCachePath = config.dependenceCachePath;
const RunningInstanceModel = {};
const CrontabStatModel = {};
const InstanceStatus = { running: 0 };
const sequelize = {};
const stubModule = (modulePath, exports) => {
require.cache[require.resolve(modulePath)] = {
id: require.resolve(modulePath),
filename: require.resolve(modulePath),
loaded: true,
exports,
children: [],
paths: [],
};
};
stubModule('../../back/data', { sequelize });
stubModule('../../back/data/cronStats', { CrontabStatModel });
stubModule('../../back/data/runningInstance', {
InstanceStatus,
RunningInstanceModel,
});
stubModule('../../back/data/system', {
AuthDataType: { systemConfig: 'systemConfig' },
SystemModel: {},
});
delete require.cache[require.resolve('../../back/services/retention')];
const RetentionService = require('../../back/services/retention').default;
t.after(async () => {
config.dependenceCachePath = originalCachePath;
await fs.rm(directory, { recursive: true, force: true });
});
let instanceWhere;
let vacuumed = false;
let instanceCountCalls = 0;
let statCountCalls = 0;
config.dependenceCachePath = directory;
RunningInstanceModel.count = async ({ where }) => {
instanceCountCalls++;
instanceWhere = where;
return 2;
};
RunningInstanceModel.destroy = async ({ where }) => {
instanceWhere = where;
return 2;
};
CrontabStatModel.count = async () => {
statCountCalls++;
return 3;
};
CrontabStatModel.destroy = async () => 3;
sequelize.transaction = async (callback) => callback({});
sequelize.query = async (query) => {
vacuumed = query === 'VACUUM';
return [];
};
const service = new RetentionService();
const disabledPreview = await service.preview({
runningInstanceRetentionDays: 0,
cronStatRetentionDays: 0,
});
assert.equal(disabledPreview.runningInstances, 0);
assert.equal(disabledPreview.cronStats, 0);
assert.equal(instanceCountCalls, 0);
assert.equal(statCountCalls, 0);
const result = await service.cleanup({
runningInstanceRetentionDays: 30,
cronStatRetentionDays: 90,
dependenceCacheTypes: ['node'],
compactDatabase: true,
});
assert.equal(instanceWhere.status[Op.ne], InstanceStatus.running);
assert.equal(result.deleted.runningInstances, 2);
assert.equal(result.deleted.cronStats, 3);
assert.equal(result.deleted.dependenceCacheBytes, 13);
assert.equal(vacuumed, true);
await assert.rejects(fs.stat(nodeCache), { code: 'ENOENT' });
});