feat:实现管理员系统核心功能
- 添加管理员数据库管理控制器和服务 - 实现管理员操作日志记录系统 - 添加数据库异常处理过滤器 - 完善管理员权限验证和响应格式 - 添加全面的属性测试覆盖
This commit is contained in:
541
src/business/admin/performance_monitoring.property.spec.ts
Normal file
541
src/business/admin/performance_monitoring.property.spec.ts
Normal file
@@ -0,0 +1,541 @@
|
||||
/**
|
||||
* 性能监控属性测试
|
||||
*
|
||||
* Property 13: 性能监控准确性
|
||||
*
|
||||
* Validates: Requirements 8.1, 8.2
|
||||
*
|
||||
* 测试目标:
|
||||
* - 验证性能监控数据的准确性
|
||||
* - 确保性能指标收集的完整性
|
||||
* - 验证性能警告机制的有效性
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-08: 注释规范优化 - 修正@author字段,更新版本号和修改记录 (修改者: moyin)
|
||||
* - 2026-01-08: 功能新增 - 创建性能监控属性测试 (修改者: assistant)
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.1
|
||||
* @since 2026-01-08
|
||||
* @lastModified 2026-01-08
|
||||
*/
|
||||
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { AdminDatabaseController } from '../../controllers/admin_database.controller';
|
||||
import { DatabaseManagementService } from '../../services/database_management.service';
|
||||
import { AdminOperationLogService } from '../../services/admin_operation_log.service';
|
||||
import { AdminOperationLogInterceptor } from '../../admin_operation_log.interceptor';
|
||||
import { AdminDatabaseExceptionFilter } from '../../admin_database_exception.filter';
|
||||
import { AdminGuard } from '../../admin.guard';
|
||||
import { UserStatus } from '../../../../core/db/users/user_status.enum';
|
||||
import {
|
||||
PropertyTestRunner,
|
||||
PropertyTestGenerators,
|
||||
PropertyTestAssertions,
|
||||
DEFAULT_PROPERTY_CONFIG
|
||||
} from './admin_property_test.base';
|
||||
|
||||
describe('Property Test: 性能监控功能', () => {
|
||||
let app: INestApplication;
|
||||
let module: TestingModule;
|
||||
let controller: AdminDatabaseController;
|
||||
let performanceMetrics: any[] = [];
|
||||
let mockUsersService: any;
|
||||
let mockUserProfilesService: any;
|
||||
let mockZulipAccountsService: any;
|
||||
|
||||
beforeAll(async () => {
|
||||
performanceMetrics = [];
|
||||
|
||||
// 创建性能监控mock
|
||||
const createPerformanceAwareMock = (serviceName: string, methodName: string, baseDelay: number = 50) => {
|
||||
return jest.fn().mockImplementation(async (...args) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
// 模拟不同的执行时间
|
||||
const randomDelay = baseDelay + Math.random() * 100;
|
||||
await new Promise(resolve => setTimeout(resolve, randomDelay));
|
||||
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - startTime;
|
||||
|
||||
// 记录性能指标
|
||||
performanceMetrics.push({
|
||||
service: serviceName,
|
||||
method: methodName,
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
args: args.length
|
||||
});
|
||||
|
||||
// 根据方法返回适当的mock数据
|
||||
if (methodName === 'findAll') {
|
||||
return [];
|
||||
} else if (methodName === 'count') {
|
||||
return 0;
|
||||
} else if (methodName === 'findOne' || methodName === 'findById') {
|
||||
if (serviceName === 'UsersService') {
|
||||
return { ...PropertyTestGenerators.generateUser(), id: BigInt(1) };
|
||||
} else if (serviceName === 'UserProfilesService') {
|
||||
return { ...PropertyTestGenerators.generateUserProfile(), id: BigInt(1) };
|
||||
} else {
|
||||
return { ...PropertyTestGenerators.generateZulipAccount(), id: '1' };
|
||||
}
|
||||
} else if (methodName === 'create') {
|
||||
if (serviceName === 'UsersService') {
|
||||
return { ...args[0], id: BigInt(1) };
|
||||
} else if (serviceName === 'UserProfilesService') {
|
||||
return { ...args[0], id: BigInt(1) };
|
||||
} else {
|
||||
return { ...args[0], id: '1' };
|
||||
}
|
||||
} else if (methodName === 'update') {
|
||||
if (serviceName === 'UsersService') {
|
||||
return { ...PropertyTestGenerators.generateUser(), ...args[1], id: args[0] };
|
||||
} else if (serviceName === 'UserProfilesService') {
|
||||
return { ...PropertyTestGenerators.generateUserProfile(), ...args[1], id: args[0] };
|
||||
} else {
|
||||
return { ...PropertyTestGenerators.generateZulipAccount(), ...args[1], id: args[0] };
|
||||
}
|
||||
} else if (methodName === 'findMany') {
|
||||
return { accounts: [], total: 0 };
|
||||
} else if (methodName === 'getStatusStatistics') {
|
||||
return { active: 0, inactive: 0, suspended: 0, error: 0, total: 0 };
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
};
|
||||
|
||||
mockUsersService = {
|
||||
findAll: createPerformanceAwareMock('UsersService', 'findAll', 30),
|
||||
findOne: createPerformanceAwareMock('UsersService', 'findOne', 20),
|
||||
create: createPerformanceAwareMock('UsersService', 'create', 80),
|
||||
update: createPerformanceAwareMock('UsersService', 'update', 60),
|
||||
remove: createPerformanceAwareMock('UsersService', 'remove', 40),
|
||||
search: createPerformanceAwareMock('UsersService', 'search', 100),
|
||||
count: createPerformanceAwareMock('UsersService', 'count', 25)
|
||||
};
|
||||
|
||||
mockUserProfilesService = {
|
||||
findAll: createPerformanceAwareMock('UserProfilesService', 'findAll', 35),
|
||||
findOne: createPerformanceAwareMock('UserProfilesService', 'findOne', 25),
|
||||
create: createPerformanceAwareMock('UserProfilesService', 'create', 90),
|
||||
update: createPerformanceAwareMock('UserProfilesService', 'update', 70),
|
||||
remove: createPerformanceAwareMock('UserProfilesService', 'remove', 45),
|
||||
findByMap: createPerformanceAwareMock('UserProfilesService', 'findByMap', 120),
|
||||
count: createPerformanceAwareMock('UserProfilesService', 'count', 30)
|
||||
};
|
||||
|
||||
mockZulipAccountsService = {
|
||||
findMany: createPerformanceAwareMock('ZulipAccountsService', 'findMany', 40),
|
||||
findById: createPerformanceAwareMock('ZulipAccountsService', 'findById', 30),
|
||||
create: createPerformanceAwareMock('ZulipAccountsService', 'create', 100),
|
||||
update: createPerformanceAwareMock('ZulipAccountsService', 'update', 80),
|
||||
delete: createPerformanceAwareMock('ZulipAccountsService', 'delete', 50),
|
||||
getStatusStatistics: createPerformanceAwareMock('ZulipAccountsService', 'getStatusStatistics', 60)
|
||||
};
|
||||
|
||||
module = await Test.createTestingModule({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
envFilePath: ['.env.test', '.env']
|
||||
})
|
||||
],
|
||||
controllers: [AdminDatabaseController],
|
||||
providers: [
|
||||
DatabaseManagementService,
|
||||
{
|
||||
provide: AdminOperationLogService,
|
||||
useValue: {
|
||||
createLog: jest.fn().mockResolvedValue({}),
|
||||
queryLogs: jest.fn().mockResolvedValue({ logs: [], total: 0 }),
|
||||
getLogById: jest.fn().mockResolvedValue(null),
|
||||
getStatistics: jest.fn().mockResolvedValue({}),
|
||||
cleanupExpiredLogs: jest.fn().mockResolvedValue(0),
|
||||
getAdminOperationHistory: jest.fn().mockResolvedValue([]),
|
||||
getSensitiveOperations: jest.fn().mockResolvedValue({ logs: [], total: 0 })
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: AdminOperationLogInterceptor,
|
||||
useValue: {
|
||||
intercept: jest.fn().mockImplementation((context, next) => next.handle())
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: 'UsersService',
|
||||
useValue: mockUsersService
|
||||
},
|
||||
{
|
||||
provide: 'IUserProfilesService',
|
||||
useValue: mockUserProfilesService
|
||||
},
|
||||
{
|
||||
provide: 'ZulipAccountsService',
|
||||
useValue: mockZulipAccountsService
|
||||
}
|
||||
]
|
||||
})
|
||||
.overrideGuard(AdminGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.compile();
|
||||
|
||||
app = module.createNestApplication();
|
||||
app.useGlobalFilters(new AdminDatabaseExceptionFilter());
|
||||
await app.init();
|
||||
|
||||
controller = module.get<AdminDatabaseController>(AdminDatabaseController);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
performanceMetrics.length = 0; // 清空性能指标
|
||||
});
|
||||
|
||||
describe('Property 13: 性能监控准确性', () => {
|
||||
it('操作执行时间应该被准确记录', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'操作执行时间记录准确性',
|
||||
() => PropertyTestGenerators.generateUser(),
|
||||
async (userData) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
// 执行操作
|
||||
await controller.createUser({
|
||||
...userData,
|
||||
status: UserStatus.ACTIVE
|
||||
});
|
||||
|
||||
const endTime = Date.now();
|
||||
const totalDuration = endTime - startTime;
|
||||
|
||||
// 验证性能指标被记录
|
||||
const createMetrics = performanceMetrics.filter(m =>
|
||||
m.service === 'UsersService' && m.method === 'create'
|
||||
);
|
||||
|
||||
expect(createMetrics.length).toBeGreaterThan(0);
|
||||
|
||||
const createMetric = createMetrics[0];
|
||||
expect(createMetric.duration).toBeGreaterThan(0);
|
||||
expect(createMetric.duration).toBeLessThan(totalDuration + 50); // 允许一些误差
|
||||
expect(createMetric.timestamp).toBeDefined();
|
||||
|
||||
// 验证时间戳格式
|
||||
const timestamp = new Date(createMetric.timestamp);
|
||||
expect(timestamp.toISOString()).toBe(createMetric.timestamp);
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 20 }
|
||||
);
|
||||
});
|
||||
|
||||
it('不同操作类型的性能指标应该被正确分类', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'操作类型性能分类',
|
||||
() => ({
|
||||
user: PropertyTestGenerators.generateUser(),
|
||||
profile: PropertyTestGenerators.generateUserProfile(),
|
||||
zulipAccount: PropertyTestGenerators.generateZulipAccount()
|
||||
}),
|
||||
async ({ user, profile, zulipAccount }) => {
|
||||
// 执行不同类型的操作
|
||||
await controller.getUserList(10, 0);
|
||||
await controller.createUser({ ...user, status: UserStatus.ACTIVE });
|
||||
await controller.getUserProfileList(10, 0);
|
||||
await controller.createUserProfile(profile);
|
||||
await controller.getZulipAccountList(10, 0);
|
||||
await controller.createZulipAccount(zulipAccount);
|
||||
|
||||
// 验证不同服务的性能指标
|
||||
const userServiceMetrics = performanceMetrics.filter(m => m.service === 'UsersService');
|
||||
const profileServiceMetrics = performanceMetrics.filter(m => m.service === 'UserProfilesService');
|
||||
const zulipServiceMetrics = performanceMetrics.filter(m => m.service === 'ZulipAccountsService');
|
||||
|
||||
expect(userServiceMetrics.length).toBeGreaterThan(0);
|
||||
expect(profileServiceMetrics.length).toBeGreaterThan(0);
|
||||
expect(zulipServiceMetrics.length).toBeGreaterThan(0);
|
||||
|
||||
// 验证方法分类
|
||||
const createMethods = performanceMetrics.filter(m => m.method === 'create');
|
||||
const findAllMethods = performanceMetrics.filter(m => m.method === 'findAll');
|
||||
const countMethods = performanceMetrics.filter(m => m.method === 'count');
|
||||
|
||||
expect(createMethods.length).toBe(3); // 三个create操作
|
||||
expect(findAllMethods.length).toBe(3); // 三个findAll操作
|
||||
expect(countMethods.length).toBe(3); // 三个count操作
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
|
||||
);
|
||||
});
|
||||
|
||||
it('复杂查询的性能应该被正确监控', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'复杂查询性能监控',
|
||||
() => ({
|
||||
searchTerm: PropertyTestGenerators.generateUser().username.substring(0, 3),
|
||||
mapName: ['plaza', 'forest', 'beach'][Math.floor(Math.random() * 3)],
|
||||
limit: Math.floor(Math.random() * 50) + 10,
|
||||
offset: Math.floor(Math.random() * 100)
|
||||
}),
|
||||
async ({ searchTerm, mapName, limit, offset }) => {
|
||||
// 执行复杂查询操作
|
||||
await controller.searchUsers(searchTerm, limit);
|
||||
await controller.getUserProfilesByMap(mapName, limit, offset);
|
||||
await controller.getZulipAccountStatistics();
|
||||
|
||||
// 验证复杂查询的性能指标
|
||||
const searchMetrics = performanceMetrics.filter(m => m.method === 'search');
|
||||
const mapQueryMetrics = performanceMetrics.filter(m => m.method === 'findByMap');
|
||||
const statsMetrics = performanceMetrics.filter(m => m.method === 'getStatusStatistics');
|
||||
|
||||
expect(searchMetrics.length).toBeGreaterThan(0);
|
||||
expect(mapQueryMetrics.length).toBeGreaterThan(0);
|
||||
expect(statsMetrics.length).toBeGreaterThan(0);
|
||||
|
||||
// 验证复杂查询通常耗时更长
|
||||
const searchDuration = searchMetrics[0].duration;
|
||||
const mapQueryDuration = mapQueryMetrics[0].duration;
|
||||
const statsDuration = statsMetrics[0].duration;
|
||||
|
||||
expect(searchDuration).toBeGreaterThan(50); // 搜索操作基础延迟100ms
|
||||
expect(mapQueryDuration).toBeGreaterThan(70); // 地图查询基础延迟120ms
|
||||
expect(statsDuration).toBeGreaterThan(30); // 统计查询基础延迟60ms
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
|
||||
);
|
||||
});
|
||||
|
||||
it('批量操作的性能应该被准确监控', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'批量操作性能监控',
|
||||
() => {
|
||||
const accountIds = Array.from({ length: Math.floor(Math.random() * 5) + 2 },
|
||||
(_, i) => `account_${i + 1}`);
|
||||
const targetStatus = ['active', 'inactive', 'suspended'][Math.floor(Math.random() * 3)];
|
||||
|
||||
return { accountIds, targetStatus };
|
||||
},
|
||||
async ({ accountIds, targetStatus }) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
// 执行批量操作
|
||||
await controller.batchUpdateZulipAccountStatus({
|
||||
ids: accountIds,
|
||||
status: targetStatus as any,
|
||||
reason: '性能测试批量更新'
|
||||
});
|
||||
|
||||
const endTime = Date.now();
|
||||
const totalDuration = endTime - startTime;
|
||||
|
||||
// 验证批量操作的性能指标
|
||||
const updateMetrics = performanceMetrics.filter(m =>
|
||||
m.service === 'ZulipAccountsService' && m.method === 'update'
|
||||
);
|
||||
|
||||
expect(updateMetrics.length).toBe(accountIds.length);
|
||||
|
||||
// 验证每个更新操作的性能
|
||||
updateMetrics.forEach(metric => {
|
||||
expect(metric.duration).toBeGreaterThan(0);
|
||||
expect(metric.duration).toBeLessThan(200); // 单个操作不应超过200ms
|
||||
});
|
||||
|
||||
// 验证总体性能合理性
|
||||
const totalServiceTime = updateMetrics.reduce((sum, m) => sum + m.duration, 0);
|
||||
expect(totalServiceTime).toBeLessThan(totalDuration + 100); // 允许一些并发优化
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it('性能异常应该被正确识别', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'性能异常识别',
|
||||
() => PropertyTestGenerators.generateUser(),
|
||||
async (userData) => {
|
||||
// 模拟慢查询(通过增加延迟)
|
||||
const originalFindOne = mockUsersService.findOne;
|
||||
mockUsersService.findOne = jest.fn().mockImplementation(async (...args) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
// 模拟异常慢的查询
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - startTime;
|
||||
|
||||
performanceMetrics.push({
|
||||
service: 'UsersService',
|
||||
method: 'findOne',
|
||||
duration,
|
||||
timestamp: new Date().toISOString(),
|
||||
args: args.length,
|
||||
slow: duration > 200 // 标记为慢查询
|
||||
});
|
||||
|
||||
return { ...PropertyTestGenerators.generateUser(), id: BigInt(1) };
|
||||
});
|
||||
|
||||
// 执行操作
|
||||
await controller.getUserById('1');
|
||||
|
||||
// 恢复原始mock
|
||||
mockUsersService.findOne = originalFindOne;
|
||||
|
||||
// 验证慢查询被识别
|
||||
const slowQueries = performanceMetrics.filter(m => m.slow === true);
|
||||
expect(slowQueries.length).toBeGreaterThan(0);
|
||||
|
||||
const slowQuery = slowQueries[0];
|
||||
expect(slowQuery.duration).toBeGreaterThan(200);
|
||||
expect(slowQuery.service).toBe('UsersService');
|
||||
expect(slowQuery.method).toBe('findOne');
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it('并发操作的性能应该被独立监控', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'并发操作性能监控',
|
||||
() => ({
|
||||
concurrentCount: Math.floor(Math.random() * 3) + 2 // 2-4个并发操作
|
||||
}),
|
||||
async ({ concurrentCount }) => {
|
||||
const promises = [];
|
||||
const startTime = Date.now();
|
||||
|
||||
// 创建并发操作
|
||||
for (let i = 0; i < concurrentCount; i++) {
|
||||
const user = PropertyTestGenerators.generateUser();
|
||||
promises.push(
|
||||
controller.createUser({
|
||||
...user,
|
||||
status: UserStatus.ACTIVE,
|
||||
username: `${user.username}_${i}` // 确保唯一性
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// 等待所有操作完成
|
||||
await Promise.all(promises);
|
||||
|
||||
const endTime = Date.now();
|
||||
const totalDuration = endTime - startTime;
|
||||
|
||||
// 验证并发操作的性能指标
|
||||
const createMetrics = performanceMetrics.filter(m =>
|
||||
m.service === 'UsersService' && m.method === 'create'
|
||||
);
|
||||
|
||||
expect(createMetrics.length).toBe(concurrentCount);
|
||||
|
||||
// 验证每个操作都有独立的性能记录
|
||||
createMetrics.forEach((metric, index) => {
|
||||
expect(metric.duration).toBeGreaterThan(0);
|
||||
expect(metric.timestamp).toBeDefined();
|
||||
|
||||
// 验证时间戳在合理范围内
|
||||
const metricTime = new Date(metric.timestamp).getTime();
|
||||
expect(metricTime).toBeGreaterThanOrEqual(startTime);
|
||||
expect(metricTime).toBeLessThanOrEqual(endTime);
|
||||
});
|
||||
|
||||
// 验证并发执行的效率
|
||||
const avgDuration = createMetrics.reduce((sum, m) => sum + m.duration, 0) / concurrentCount;
|
||||
expect(totalDuration).toBeLessThan(avgDuration * concurrentCount * 1.2); // 并发应该有一定效率提升
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
|
||||
);
|
||||
});
|
||||
|
||||
it('性能统计数据应该准确计算', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'性能统计准确性',
|
||||
() => ({
|
||||
operationCount: Math.floor(Math.random() * 8) + 3 // 3-10个操作
|
||||
}),
|
||||
async ({ operationCount }) => {
|
||||
// 执行多个操作
|
||||
for (let i = 0; i < operationCount; i++) {
|
||||
await controller.getUserList(10, i * 10);
|
||||
}
|
||||
|
||||
// 计算性能统计
|
||||
const findAllMetrics = performanceMetrics.filter(m =>
|
||||
m.service === 'UsersService' && m.method === 'findAll'
|
||||
);
|
||||
|
||||
expect(findAllMetrics.length).toBe(operationCount);
|
||||
|
||||
// 计算统计数据
|
||||
const durations = findAllMetrics.map(m => m.duration);
|
||||
const totalDuration = durations.reduce((sum, d) => sum + d, 0);
|
||||
const avgDuration = totalDuration / durations.length;
|
||||
const minDuration = Math.min(...durations);
|
||||
const maxDuration = Math.max(...durations);
|
||||
|
||||
// 验证统计数据合理性
|
||||
expect(totalDuration).toBeGreaterThan(0);
|
||||
expect(avgDuration).toBeGreaterThan(0);
|
||||
expect(avgDuration).toBeGreaterThanOrEqual(minDuration);
|
||||
expect(avgDuration).toBeLessThanOrEqual(maxDuration);
|
||||
expect(minDuration).toBeLessThanOrEqual(maxDuration);
|
||||
|
||||
// 验证平均值在合理范围内(基础延迟30ms + 随机100ms)
|
||||
expect(avgDuration).toBeGreaterThan(20);
|
||||
expect(avgDuration).toBeLessThan(200);
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 15 }
|
||||
);
|
||||
});
|
||||
|
||||
it('性能监控不应该显著影响操作性能', async () => {
|
||||
await PropertyTestRunner.runPropertyTest(
|
||||
'性能监控开销验证',
|
||||
() => PropertyTestGenerators.generateUser(),
|
||||
async (userData) => {
|
||||
const iterations = 5;
|
||||
const durations = [];
|
||||
|
||||
// 执行多次相同操作
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const startTime = Date.now();
|
||||
|
||||
await controller.createUser({
|
||||
...userData,
|
||||
status: UserStatus.ACTIVE,
|
||||
username: `${userData.username}_${i}`
|
||||
});
|
||||
|
||||
const endTime = Date.now();
|
||||
durations.push(endTime - startTime);
|
||||
}
|
||||
|
||||
// 验证性能一致性
|
||||
const avgDuration = durations.reduce((sum, d) => sum + d, 0) / durations.length;
|
||||
const maxVariation = Math.max(...durations) - Math.min(...durations);
|
||||
|
||||
// 性能变化不应该太大(监控开销应该很小)
|
||||
expect(maxVariation).toBeLessThan(avgDuration * 0.5); // 变化不超过平均值的50%
|
||||
|
||||
// 验证所有操作都被监控
|
||||
const createMetrics = performanceMetrics.filter(m =>
|
||||
m.service === 'UsersService' && m.method === 'create'
|
||||
);
|
||||
|
||||
expect(createMetrics.length).toBe(iterations);
|
||||
},
|
||||
{ ...DEFAULT_PROPERTY_CONFIG, iterations: 10 }
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user