184 lines
5.3 KiB
JavaScript
184 lines
5.3 KiB
JavaScript
|
|
/**
|
||
|
|
* 테이블 타입관리 성능 테스트 스크립트
|
||
|
|
* 최적화 전후 성능 비교용
|
||
|
|
*/
|
||
|
|
|
||
|
|
const axios = require("axios");
|
||
|
|
|
||
|
|
const BASE_URL = "http://localhost:3001/api";
|
||
|
|
const TEST_TABLE = "user_info"; // 테스트할 테이블명
|
||
|
|
|
||
|
|
// 성능 측정 함수
|
||
|
|
async function measurePerformance(name, fn) {
|
||
|
|
const start = Date.now();
|
||
|
|
try {
|
||
|
|
const result = await fn();
|
||
|
|
const end = Date.now();
|
||
|
|
const duration = end - start;
|
||
|
|
|
||
|
|
console.log(`✅ ${name}: ${duration}ms`);
|
||
|
|
return { success: true, duration, result };
|
||
|
|
} catch (error) {
|
||
|
|
const end = Date.now();
|
||
|
|
const duration = end - start;
|
||
|
|
|
||
|
|
console.log(`❌ ${name}: ${duration}ms (실패: ${error.message})`);
|
||
|
|
return { success: false, duration, error: error.message };
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 테스트 함수들
|
||
|
|
const tests = {
|
||
|
|
// 1. 테이블 목록 조회 성능
|
||
|
|
async testTableList() {
|
||
|
|
return await axios.get(`${BASE_URL}/table-management/tables`);
|
||
|
|
},
|
||
|
|
|
||
|
|
// 2. 컬럼 목록 조회 성능 (첫 페이지)
|
||
|
|
async testColumnListFirstPage() {
|
||
|
|
return await axios.get(
|
||
|
|
`${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=50`
|
||
|
|
);
|
||
|
|
},
|
||
|
|
|
||
|
|
// 3. 컬럼 목록 조회 성능 (큰 페이지)
|
||
|
|
async testColumnListLargePage() {
|
||
|
|
return await axios.get(
|
||
|
|
`${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=200`
|
||
|
|
);
|
||
|
|
},
|
||
|
|
|
||
|
|
// 4. 캐시 효과 테스트 (동일한 요청 반복)
|
||
|
|
async testCacheEffect() {
|
||
|
|
// 첫 번째 요청 (캐시 미스)
|
||
|
|
await axios.get(
|
||
|
|
`${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=50`
|
||
|
|
);
|
||
|
|
|
||
|
|
// 두 번째 요청 (캐시 히트)
|
||
|
|
return await axios.get(
|
||
|
|
`${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=1&size=50`
|
||
|
|
);
|
||
|
|
},
|
||
|
|
|
||
|
|
// 5. 동시 요청 처리 성능
|
||
|
|
async testConcurrentRequests() {
|
||
|
|
const requests = Array(10)
|
||
|
|
.fill()
|
||
|
|
.map((_, i) =>
|
||
|
|
axios.get(
|
||
|
|
`${BASE_URL}/table-management/tables/${TEST_TABLE}/columns?page=${i + 1}&size=20`
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
return await Promise.all(requests);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 메인 테스트 실행
|
||
|
|
async function runPerformanceTests() {
|
||
|
|
console.log("🚀 테이블 타입관리 성능 테스트 시작\n");
|
||
|
|
console.log(`📊 테스트 대상: ${BASE_URL}`);
|
||
|
|
console.log(`📋 테스트 테이블: ${TEST_TABLE}\n`);
|
||
|
|
|
||
|
|
const results = {};
|
||
|
|
|
||
|
|
// 각 테스트 실행
|
||
|
|
for (const [testName, testFn] of Object.entries(tests)) {
|
||
|
|
console.log(`\n--- ${testName} ---`);
|
||
|
|
|
||
|
|
// 각 테스트를 3번 실행하여 평균 계산
|
||
|
|
const runs = [];
|
||
|
|
for (let i = 0; i < 3; i++) {
|
||
|
|
const result = await measurePerformance(`실행 ${i + 1}`, testFn);
|
||
|
|
runs.push(result);
|
||
|
|
|
||
|
|
// 테스트 간 간격
|
||
|
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||
|
|
}
|
||
|
|
|
||
|
|
// 성공한 실행들의 평균 시간 계산
|
||
|
|
const successfulRuns = runs.filter((r) => r.success);
|
||
|
|
if (successfulRuns.length > 0) {
|
||
|
|
const avgDuration =
|
||
|
|
successfulRuns.reduce((sum, r) => sum + r.duration, 0) /
|
||
|
|
successfulRuns.length;
|
||
|
|
const minDuration = Math.min(...successfulRuns.map((r) => r.duration));
|
||
|
|
const maxDuration = Math.max(...successfulRuns.map((r) => r.duration));
|
||
|
|
|
||
|
|
results[testName] = {
|
||
|
|
average: Math.round(avgDuration),
|
||
|
|
min: minDuration,
|
||
|
|
max: maxDuration,
|
||
|
|
successRate: (successfulRuns.length / runs.length) * 100,
|
||
|
|
};
|
||
|
|
|
||
|
|
console.log(
|
||
|
|
`📈 평균: ${Math.round(avgDuration)}ms, 최소: ${minDuration}ms, 최대: ${maxDuration}ms`
|
||
|
|
);
|
||
|
|
} else {
|
||
|
|
results[testName] = { error: "모든 테스트 실패" };
|
||
|
|
console.log("❌ 모든 테스트 실패");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 결과 요약
|
||
|
|
console.log("\n" + "=".repeat(50));
|
||
|
|
console.log("📊 성능 테스트 결과 요약");
|
||
|
|
console.log("=".repeat(50));
|
||
|
|
|
||
|
|
for (const [testName, result] of Object.entries(results)) {
|
||
|
|
if (result.error) {
|
||
|
|
console.log(`❌ ${testName}: ${result.error}`);
|
||
|
|
} else {
|
||
|
|
console.log(
|
||
|
|
`✅ ${testName}: ${result.average}ms (${result.min}-${result.max}ms, 성공률: ${result.successRate}%)`
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 성능 기준 평가
|
||
|
|
console.log("\n" + "=".repeat(50));
|
||
|
|
console.log("🎯 성능 기준 평가");
|
||
|
|
console.log("=".repeat(50));
|
||
|
|
|
||
|
|
const benchmarks = {
|
||
|
|
testTableList: { good: 200, acceptable: 500 },
|
||
|
|
testColumnListFirstPage: { good: 300, acceptable: 800 },
|
||
|
|
testColumnListLargePage: { good: 500, acceptable: 1200 },
|
||
|
|
testCacheEffect: { good: 50, acceptable: 150 },
|
||
|
|
testConcurrentRequests: { good: 1000, acceptable: 3000 },
|
||
|
|
};
|
||
|
|
|
||
|
|
for (const [testName, result] of Object.entries(results)) {
|
||
|
|
if (result.error) continue;
|
||
|
|
|
||
|
|
const benchmark = benchmarks[testName];
|
||
|
|
if (!benchmark) continue;
|
||
|
|
|
||
|
|
let status = "🔴 느림";
|
||
|
|
if (result.average <= benchmark.good) {
|
||
|
|
status = "🟢 우수";
|
||
|
|
} else if (result.average <= benchmark.acceptable) {
|
||
|
|
status = "🟡 양호";
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(`${status} ${testName}: ${result.average}ms`);
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log("\n✨ 성능 테스트 완료!");
|
||
|
|
}
|
||
|
|
|
||
|
|
// 에러 핸들링
|
||
|
|
process.on("unhandledRejection", (error) => {
|
||
|
|
console.error("❌ 처리되지 않은 에러:", error.message);
|
||
|
|
process.exit(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
// 테스트 실행
|
||
|
|
if (require.main === module) {
|
||
|
|
runPerformanceTests().catch(console.error);
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = { runPerformanceTests, measurePerformance };
|