Files
IOT_SIM/server/test/backup.test.ts
T
xuyueandClaude Opus 5.5 982b1297aa
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
试用前准备:全班模拟压测、评分并发 6→16、手动备份与恢复
- test/classroom.ts:45 个虚拟学生走一遍登录、运行、自测、提交,统计每个环节等多久
- 评分并发可配置(SIM_GRADE_CONCURRENCY,默认 16),提交队列同时评的份数跟着走;
  2 核实测项目 8 任务 3 全班自测从约 4 分钟降到约 1.5 分钟
- 检查的默认等待 2 秒→5 秒,机器忙时不再误判正确的程序
- 删除学生时删除他的数据库(编号会重新用给新学生)
- deploy/backup.sh、deploy/restore.sh:手动备份到宿主机 backups/,恢复前先备份

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 20:08:31 +08:00

47 lines
2.2 KiB
TypeScript

// 手动备份:平台数据库和学生数据库都导出完整(正在使用、数据还在 -wal 文件里时也一样)。
import { afterAll, beforeAll, expect, test } from 'bun:test'
import { Database } from 'bun:sqlite'
import { mkdir, rm } from 'node:fs/promises'
import { join } from 'node:path'
import { backupTo } from '../src/backup'
import { config } from '../src/config'
import { openDatabase } from '../src/db'
const saved = config.dataDir
const target = `${config.runsDir}/test-backup-copy`
beforeAll(async () => {
config.dataDir = `${config.runsDir}/test-backup-data`
await rm(config.dataDir, { recursive: true, force: true })
await rm(target, { recursive: true, force: true })
})
afterAll(async () => {
await rm(config.dataDir, { recursive: true, force: true })
await rm(target, { recursive: true, force: true })
config.dataDir = saved
})
test('导出平台数据库和每个学生的数据库,不覆盖已有的备份', async () => {
// 平台和学生程序都开着库(WAL 模式,刚写入的数据还在 -wal 文件里)
const db = openDatabase()
db.query(`INSERT INTO users (username, name, password, role, created_at) VALUES ('s1', '学生', '123456', 'student', 0)`).run()
await mkdir(join(config.dataDir, 'databases', '7'), { recursive: true })
const student = new Database(join(config.dataDir, 'databases', '7', 'WisdomCampus.db'), { create: true })
student.run('PRAGMA journal_mode = WAL')
student.run('CREATE TABLE EnvironmentData (id INTEGER PRIMARY KEY, temperature REAL) STRICT')
student.run('INSERT INTO EnvironmentData (temperature) VALUES (25.5), (26)')
await backupTo(target)
await expect(backupTo(target)).rejects.toThrow('已经有备份')
student.close()
db.close()
const mainCopy = new Database(join(target, 'iot-sim.db'), { readonly: true })
expect(mainCopy.query(`SELECT name FROM users WHERE username = 's1'`).get()).toEqual({ name: '学生' })
mainCopy.close()
const studentCopy = new Database(join(target, 'databases', '7', 'WisdomCampus.db'), { readonly: true })
expect(studentCopy.query('SELECT temperature FROM EnvironmentData ORDER BY id').all()).toEqual([{ temperature: 25.5 }, { temperature: 26 }])
studentCopy.close()
})