mirror of
https://github.com/whyour/qinglong.git
synced 2026-10-16 22:35:32 +08:00
Synchronize scheduler concurrency across API and gRPC processes and restore persisted limits during recovery. Serialize subscription mutations and preserve shared storage while cleaning Shell and CLI namespaces, historical references, and filesystem-specific naming candidates. Handle CLI text responses correctly and include script history in backups. Add regression coverage for concurrency, cleanup ownership, long URLs, Unicode paths, and history exports.
128 lines
3.8 KiB
JavaScript
128 lines
3.8 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');
|
|
|
|
test('clearing a dependency cache marks installed entries for reinstall', async (t) => {
|
|
const directory = await fs.mkdtemp(path.join(os.tmpdir(), 'ql-dependence-'));
|
|
const nodeCache = path.join(directory, 'node');
|
|
await fs.mkdir(nodeCache);
|
|
await fs.writeFile(path.join(nodeCache, 'package'), 'cached');
|
|
t.after(() => fs.rm(directory, { recursive: true, force: true }));
|
|
|
|
const moduleStubs = new Map();
|
|
const stubModule = (modulePath, exports) => {
|
|
const resolved = require.resolve(modulePath);
|
|
moduleStubs.set(resolved, require.cache[resolved]);
|
|
require.cache[resolved] = {
|
|
id: resolved,
|
|
filename: resolved,
|
|
loaded: true,
|
|
exports,
|
|
children: [],
|
|
paths: [],
|
|
};
|
|
};
|
|
const updates = [];
|
|
const DependenceStatus = { installed: 1, installFailed: 2 };
|
|
const DependenceTypes = { nodejs: 0, python3: 1 };
|
|
|
|
stubModule('../../back/config', {
|
|
__esModule: true,
|
|
default: { dependenceCachePath: directory },
|
|
});
|
|
stubModule('../../back/config/const', {
|
|
NotificationModeStringMap: {},
|
|
TASK_COMMAND: 'task',
|
|
});
|
|
stubModule('../../back/config/util', {
|
|
getPid: async () => 0,
|
|
killTask: async () => {},
|
|
parseContentVersion: () => '',
|
|
parseVersion: () => '',
|
|
promiseExec: async () => '',
|
|
readDirs: async () => [],
|
|
rmPath: async () => {},
|
|
setSystemTimezone: async () => true,
|
|
updateLinuxMirrorFile: async () => {},
|
|
});
|
|
stubModule('../../back/data/dependence', {
|
|
DependenceModel: {
|
|
update: async (values, options) => updates.push({ values, options }),
|
|
},
|
|
DependenceStatus,
|
|
DependenceTypes,
|
|
});
|
|
stubModule('../../back/data/notify', {});
|
|
stubModule('../../back/data/system', {
|
|
AuthDataType: {},
|
|
SystemModel: {},
|
|
});
|
|
stubModule('../../back/schedule/client', { __esModule: true, default: {} });
|
|
stubModule('../../back/shared/pLimit', {
|
|
__esModule: true,
|
|
default: {},
|
|
});
|
|
stubModule('../../back/shared/i18n', {
|
|
setLang: () => {},
|
|
t: (message) => message,
|
|
});
|
|
stubModule('../../back/services/notify', {
|
|
__esModule: true,
|
|
default: class NotificationService {},
|
|
});
|
|
stubModule('../../back/services/schedule', {
|
|
__esModule: true,
|
|
default: class ScheduleService {},
|
|
});
|
|
stubModule('../../back/services/sock', {
|
|
__esModule: true,
|
|
default: class SockService {},
|
|
});
|
|
|
|
const servicePath = require.resolve('../../back/services/system');
|
|
const originalService = require.cache[servicePath];
|
|
delete require.cache[servicePath];
|
|
t.after(() => {
|
|
if (originalService) {
|
|
require.cache[servicePath] = originalService;
|
|
} else {
|
|
delete require.cache[servicePath];
|
|
}
|
|
for (const [resolved, original] of moduleStubs) {
|
|
if (original) {
|
|
require.cache[resolved] = original;
|
|
} else {
|
|
delete require.cache[resolved];
|
|
}
|
|
}
|
|
});
|
|
|
|
const SystemService = require('../../back/services/system').default;
|
|
const service = new SystemService({}, {}, {});
|
|
assert.deepEqual(await service.cleanDependence('node'), { code: 200 });
|
|
assert.deepEqual(await service.cleanDependence('python3'), { code: 200 });
|
|
await assert.rejects(fs.stat(nodeCache), { code: 'ENOENT' });
|
|
assert.deepEqual(updates, [
|
|
{
|
|
values: { status: DependenceStatus.installFailed },
|
|
options: {
|
|
where: {
|
|
type: DependenceTypes.nodejs,
|
|
status: DependenceStatus.installed,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
values: { status: DependenceStatus.installFailed },
|
|
options: {
|
|
where: {
|
|
type: DependenceTypes.python3,
|
|
status: DependenceStatus.installed,
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
});
|