mirror of https://github.com/allinssl/allinssl
134 lines
3.8 KiB
JavaScript
134 lines
3.8 KiB
JavaScript
import { jest } from '@jest/globals'
|
|
import { promises as fs } from 'fs'
|
|
import path from 'path'
|
|
import { LogManager } from '../src/logManagement/index.js'
|
|
|
|
jest.mock('fs', () => ({
|
|
promises: {
|
|
mkdir: jest.fn(),
|
|
appendFile: jest.fn(),
|
|
readFile: jest.fn(),
|
|
readdir: jest.fn(),
|
|
stat: jest.fn(),
|
|
unlink: jest.fn(),
|
|
},
|
|
}))
|
|
|
|
describe('LogManager', () => {
|
|
const options = {
|
|
logPath: './test-logs',
|
|
errorLogFile: 'error.log',
|
|
infoLogFile: 'info.log',
|
|
}
|
|
let logManager
|
|
|
|
beforeEach(() => {
|
|
logManager = new LogManager(options)
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
describe('init', () => {
|
|
it('应该创建日志目录', async () => {
|
|
await logManager.init()
|
|
expect(fs.mkdir).toHaveBeenCalledWith(options.logPath, { recursive: true })
|
|
})
|
|
|
|
it('处理创建目录失败的情况', async () => {
|
|
const consoleError = jest.spyOn(console, 'error').mockImplementation()
|
|
fs.mkdir.mockRejectedValueOnce(new Error('创建目录失败'))
|
|
|
|
await logManager.init()
|
|
expect(consoleError).toHaveBeenCalled()
|
|
consoleError.mockRestore()
|
|
})
|
|
})
|
|
|
|
describe('logError', () => {
|
|
it('应该写入错误日志', async () => {
|
|
const error = new Error('测试错误')
|
|
await logManager.logError(error)
|
|
|
|
expect(fs.appendFile).toHaveBeenCalledWith(
|
|
expect.stringContaining('error.log'),
|
|
expect.stringContaining('测试错误'),
|
|
)
|
|
})
|
|
|
|
it('处理写入错误日志失败的情况', async () => {
|
|
const consoleError = jest.spyOn(console, 'error').mockImplementation()
|
|
fs.appendFile.mockRejectedValueOnce(new Error('写入失败'))
|
|
|
|
await logManager.logError(new Error('测试错误'))
|
|
expect(consoleError).toHaveBeenCalled()
|
|
consoleError.mockRestore()
|
|
})
|
|
})
|
|
|
|
describe('logInfo', () => {
|
|
it('应该写入信息日志', async () => {
|
|
const message = '测试信息'
|
|
await logManager.logInfo(message)
|
|
|
|
expect(fs.appendFile).toHaveBeenCalledWith(expect.stringContaining('info.log'), expect.stringContaining(message))
|
|
})
|
|
|
|
it('处理写入信息日志失败的情况', async () => {
|
|
const consoleError = jest.spyOn(console, 'error').mockImplementation()
|
|
fs.appendFile.mockRejectedValueOnce(new Error('写入失败'))
|
|
|
|
await logManager.logInfo('测试信息')
|
|
expect(consoleError).toHaveBeenCalled()
|
|
consoleError.mockRestore()
|
|
})
|
|
})
|
|
|
|
describe('cleanLogs', () => {
|
|
it('应该删除过期的日志文件', async () => {
|
|
const now = Date.now()
|
|
const oldDate = now - 7 * 24 * 60 * 60 * 1000 - 1000 // 7天+1秒前
|
|
|
|
fs.readdir.mockResolvedValueOnce(['old.log', 'new.log'])
|
|
fs.stat.mockImplementation((path) => {
|
|
return Promise.resolve({
|
|
mtimeMs: path.includes('old') ? oldDate : now,
|
|
})
|
|
})
|
|
|
|
await logManager.cleanLogs(7)
|
|
|
|
expect(fs.unlink).toHaveBeenCalledWith(expect.stringContaining('old.log'))
|
|
expect(fs.unlink).not.toHaveBeenCalledWith(expect.stringContaining('new.log'))
|
|
})
|
|
|
|
it('处理清理日志失败的情况', async () => {
|
|
const consoleError = jest.spyOn(console, 'error').mockImplementation()
|
|
fs.readdir.mockRejectedValueOnce(new Error('读取目录失败'))
|
|
|
|
await logManager.cleanLogs(7)
|
|
expect(consoleError).toHaveBeenCalled()
|
|
consoleError.mockRestore()
|
|
})
|
|
})
|
|
|
|
describe('getLogs', () => {
|
|
it('应该返回指定数量的日志行', async () => {
|
|
const logContent = '行1\n行2\n行3\n行4\n行5'
|
|
fs.readFile.mockResolvedValueOnce(logContent)
|
|
|
|
const lines = await logManager.getLogs('info', 3)
|
|
expect(lines).toHaveLength(3)
|
|
expect(lines[2]).toBe('行5')
|
|
})
|
|
|
|
it('处理读取日志失败的情况', async () => {
|
|
const consoleError = jest.spyOn(console, 'error').mockImplementation()
|
|
fs.readFile.mockRejectedValueOnce(new Error('读取文件失败'))
|
|
|
|
const lines = await logManager.getLogs('error', 5)
|
|
expect(lines).toHaveLength(0)
|
|
expect(consoleError).toHaveBeenCalled()
|
|
consoleError.mockRestore()
|
|
})
|
|
})
|
|
})
|