mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-08-06 22:24:13 +08:00
72 lines
3.1 KiB
JavaScript
72 lines
3.1 KiB
JavaScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
let createBackgroundJobQueue
|
|
try {
|
|
({ createBackgroundJobQueue } = await import('../scripts/media-background-queue.js'))
|
|
} catch {}
|
|
|
|
const rustSource = readFileSync(new URL('../src-tauri/src/commands/media.rs', import.meta.url), 'utf8')
|
|
const webSource = readFileSync(new URL('../scripts/dev-api.js', import.meta.url), 'utf8')
|
|
const pageSource = readFileSync(new URL('../src/pages/media.js', import.meta.url), 'utf8')
|
|
|
|
async function waitFor(predicate, timeoutMs = 500) {
|
|
const deadline = Date.now() + timeoutMs
|
|
while (!predicate()) {
|
|
if (Date.now() >= deadline) throw new Error('等待后台队列状态超时')
|
|
await new Promise(resolve => setTimeout(resolve, 5))
|
|
}
|
|
}
|
|
|
|
test('后台队列限制并发并拒绝重复入队', async () => {
|
|
assert.equal(typeof createBackgroundJobQueue, 'function', '应提供可复用的后台任务队列')
|
|
|
|
const releases = []
|
|
const started = []
|
|
let active = 0
|
|
let maxActive = 0
|
|
const queue = createBackgroundJobQueue({
|
|
concurrency: 2,
|
|
worker: async jobId => {
|
|
started.push(jobId)
|
|
active += 1
|
|
maxActive = Math.max(maxActive, active)
|
|
await new Promise(resolve => releases.push(resolve))
|
|
active -= 1
|
|
},
|
|
})
|
|
|
|
assert.equal(queue.enqueue('job-1'), true)
|
|
assert.equal(queue.enqueue('job-1'), false, '同一任务不能重复消费')
|
|
assert.equal(queue.enqueue('job-2'), true)
|
|
assert.equal(queue.enqueue('job-3'), true)
|
|
await waitFor(() => started.length === 2)
|
|
assert.equal(maxActive, 2)
|
|
assert.deepEqual(started, ['job-1', 'job-2'])
|
|
|
|
releases.shift()()
|
|
await waitFor(() => started.length === 3)
|
|
assert.equal(started[2], 'job-3')
|
|
while (releases.length) releases.shift()()
|
|
await queue.whenIdle()
|
|
assert.deepEqual(queue.stats(), { active: 0, pending: 0 })
|
|
})
|
|
|
|
test('Tauri 和 Web 提交立即持久化 queued 并由后台恢复消费', () => {
|
|
for (const [label, source] of [['Tauri', rustSource], ['Web', webSource]]) {
|
|
assert.match(source, /MEDIA_QUEUE_CONCURRENCY/, `${label} 应限制媒体生成并发`)
|
|
assert.match(source, /status["']?\s*[:=]\s*["']queued["']|["']status["']\s*:\s*["']queued["']/, `${label} 应持久化 queued 状态`)
|
|
assert.match(source, /schedule_media_job|queueMediaJob/, `${label} 应在后台调度任务`)
|
|
assert.match(source, /recover_media_queue|recoverMediaQueue/, `${label} 应恢复持久化的未完成任务`)
|
|
}
|
|
})
|
|
|
|
test('创作中心提供生成队列、自动刷新并在提交后解锁当前表单', () => {
|
|
assert.match(pageSource, /['"]queue['"][\s\S]*media\.tabQueue/, '页面应提供生成队列页签')
|
|
assert.match(pageSource, /setInterval\([\s\S]*refresh/, '页面应自动刷新任务状态')
|
|
assert.match(pageSource, /export function cleanup\(/, '离开页面时应停止自动刷新')
|
|
assert.match(pageSource, /querySelector\(['"]#media-image-form button\[type="submit"\]/, '图片提交后应解锁当前表单按钮')
|
|
assert.match(pageSource, /querySelector\(['"]#media-video-form button\[type="submit"\]/, '视频提交后应解锁当前表单按钮')
|
|
})
|