You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
5.4 KiB
142 lines
5.4 KiB
import { expect } from 'chai'
|
|
import db, { DbQueryCache, checkDatabaseHealth, getDatabaseStats } from '../../src/db/index.js'
|
|
import { UserModel } from '../../src/db/models/UserModel.js'
|
|
import { logQuery, getQueryStats, getSlowQueries, resetStats } from '../../src/db/monitor.js'
|
|
|
|
describe('Database Performance', () => {
|
|
before(() => {
|
|
// 重置统计
|
|
resetStats()
|
|
})
|
|
|
|
describe('Connection Pool', () => {
|
|
it('应该保持健康的数据库连接', async () => {
|
|
const health = await checkDatabaseHealth()
|
|
expect(health.status).to.equal('healthy')
|
|
expect(health).to.have.property('responseTime')
|
|
expect(health.responseTime).to.be.a('number')
|
|
})
|
|
|
|
it('应该正确报告连接池状态', async () => {
|
|
const stats = getDatabaseStats()
|
|
expect(stats).to.have.property('connectionPool')
|
|
expect(stats.connectionPool).to.have.property('min')
|
|
expect(stats.connectionPool).to.have.property('max')
|
|
expect(stats.connectionPool).to.have.property('used')
|
|
})
|
|
})
|
|
|
|
describe('Query Performance', () => {
|
|
beforeEach(async () => {
|
|
// 清空用户表
|
|
await db('users').del()
|
|
})
|
|
|
|
it('应该正确记录查询统计', async () => {
|
|
const initialStats = getQueryStats()
|
|
|
|
// 执行一些查询
|
|
await UserModel.create({
|
|
username: 'perf_test',
|
|
email: 'perf_test@example.com',
|
|
password: 'password123'
|
|
})
|
|
|
|
await UserModel.findByUsername('perf_test')
|
|
await UserModel.findAll()
|
|
|
|
const finalStats = getQueryStats()
|
|
expect(finalStats.totalQueries).to.be.greaterThan(initialStats.totalQueries)
|
|
})
|
|
|
|
it('应该正确处理缓存查询', async () => {
|
|
// 清空缓存
|
|
DbQueryCache.clear()
|
|
|
|
const cacheStatsBefore = DbQueryCache.stats()
|
|
|
|
// 执行带缓存的查询
|
|
const query = db('users').select('*').cache(1000) // 1秒缓存
|
|
await query
|
|
|
|
const cacheStatsAfter = DbQueryCache.stats()
|
|
expect(cacheStatsAfter.valid).to.be.greaterThan(cacheStatsBefore.valid)
|
|
})
|
|
|
|
it('应该正确识别慢查询', async function() {
|
|
this.timeout(5000) // 增加超时时间
|
|
|
|
// 清空慢查询记录
|
|
resetStats()
|
|
|
|
// 执行一个可能较慢的查询(通过复杂连接)
|
|
try {
|
|
const result = await db.raw(`
|
|
SELECT u1.*, u2.username as related_user
|
|
FROM users u1
|
|
LEFT JOIN users u2 ON u1.id != u2.id
|
|
WHERE u1.id IN (
|
|
SELECT id FROM users
|
|
WHERE username LIKE '%test%'
|
|
ORDER BY id
|
|
)
|
|
ORDER BY u1.id, u2.id
|
|
LIMIT 100
|
|
`)
|
|
} catch (error) {
|
|
// 忽略查询错误
|
|
}
|
|
|
|
// 检查是否有慢查询记录
|
|
const slowQueries = getSlowQueries()
|
|
// 注意:由于测试环境可能很快,不一定能触发慢查询
|
|
})
|
|
})
|
|
|
|
describe('Cache Performance', () => {
|
|
it('应该正确管理缓存统计', async () => {
|
|
const cacheStats = DbQueryCache.stats()
|
|
expect(cacheStats).to.have.property('size')
|
|
expect(cacheStats).to.have.property('valid')
|
|
expect(cacheStats).to.have.property('expired')
|
|
})
|
|
|
|
it('应该正确清理过期缓存', async () => {
|
|
// 添加一些带短生命周期的缓存项
|
|
DbQueryCache.set('test_key_1', 'test_value_1', 10) // 10ms过期
|
|
DbQueryCache.set('test_key_2', 'test_value_2', 5000) // 5秒过期
|
|
|
|
// 等待第一个缓存项过期
|
|
await new Promise(resolve => setTimeout(resolve, 20))
|
|
|
|
const cleaned = DbQueryCache.cleanup()
|
|
expect(cleaned).to.be.greaterThanOrEqual(0)
|
|
})
|
|
|
|
it('应该按前缀清理缓存', async () => {
|
|
DbQueryCache.set('user:123', 'user_data')
|
|
DbQueryCache.set('user:456', 'user_data')
|
|
DbQueryCache.set('post:123', 'post_data')
|
|
|
|
const before = DbQueryCache.stats()
|
|
DbQueryCache.clearByPrefix('user:')
|
|
const after = DbQueryCache.stats()
|
|
|
|
expect(after.valid).to.be.lessThan(before.valid)
|
|
})
|
|
})
|
|
|
|
describe('Memory Usage', () => {
|
|
it('应该报告缓存内存使用情况', async () => {
|
|
// 添加一些测试数据到缓存
|
|
DbQueryCache.set('memory_test_1', { data: 'test data 1', timestamp: Date.now() })
|
|
DbQueryCache.set('memory_test_2', { data: 'test data 2 with more content', timestamp: Date.now() })
|
|
|
|
const memoryUsage = DbQueryCache.getMemoryUsage()
|
|
expect(memoryUsage).to.have.property('entryCount')
|
|
expect(memoryUsage).to.have.property('totalMemoryBytes')
|
|
expect(memoryUsage).to.have.property('averageEntrySize')
|
|
expect(memoryUsage).to.have.property('estimatedMemoryMB')
|
|
})
|
|
})
|
|
})
|