Skip to content

Commit eeac0bb

Browse files
authored
perf: 2차 api성능테스트 - ticket도메인
* refactor: activeSession추가에 따른 로그인 통과로직 개선 * refactor: 좌석변경 응답구조 변경
1 parent 8e44b23 commit eeac0bb

3 files changed

Lines changed: 69 additions & 2 deletions

File tree

backend/src/main/java/com/back/global/init/perf/PerfUserDataInitializer.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.springframework.security.crypto.password.PasswordEncoder;
99
import org.springframework.stereotype.Component;
1010

11+
import com.back.domain.auth.entity.ActiveSession;
12+
import com.back.domain.auth.repository.ActiveSessionRepository;
1113
import com.back.domain.user.entity.User;
1214
import com.back.domain.user.entity.UserActiveStatus;
1315
import com.back.domain.user.entity.UserRole;
@@ -24,6 +26,7 @@ public class PerfUserDataInitializer {
2426

2527
private final UserRepository userRepository;
2628
private final PasswordEncoder passwordEncoder;
29+
private final ActiveSessionRepository activeSessionRepository;
2730

2831
public void init(int userCount) {
2932
if (userRepository.count() > 0) {
@@ -47,7 +50,21 @@ public void init(int userCount) {
4750

4851
userRepository.save(admin);
4952

53+
// ActiveSession 생성 (k6 테스트용)
54+
createActiveSessions(users);
55+
56+
// admin용 고정 sessionId
57+
String adminSessionId = String.format("00000000-0000-0000-0000-%012d", admin.getId());
58+
ActiveSession adminSession = ActiveSession.builder()
59+
.user(admin)
60+
.sessionId(adminSessionId)
61+
.tokenVersion(1L)
62+
.lastLoginAt(java.time.LocalDateTime.now())
63+
.build();
64+
activeSessionRepository.save(adminSession);
65+
5066
log.info("✅ User 데이터 생성 완료: 일반 사용자 {}명 + 관리자 1명", users.size());
67+
log.info("✅ ActiveSession 생성 완료: {}개", users.size() + 1);
5168
}
5269

5370
private List<User> createTestUsers(int count) {
@@ -68,4 +85,20 @@ private List<User> createTestUsers(int count) {
6885

6986
return userRepository.saveAll(users);
7087
}
88+
89+
private void createActiveSessions(List<User> users) {
90+
List<ActiveSession> sessions = users.stream()
91+
.map(user -> {
92+
// k6 테스트용 고정 sessionId (userId 기반)
93+
String fixedSessionId = String.format("00000000-0000-0000-0000-%012d", user.getId());
94+
return ActiveSession.builder()
95+
.user(user)
96+
.sessionId(fixedSessionId)
97+
.tokenVersion(1L)
98+
.lastLoginAt(java.time.LocalDateTime.now())
99+
.build();
100+
})
101+
.toList();
102+
activeSessionRepository.saveAll(sessions);
103+
}
71104
}

perf/k6-scripts/scenarios/getMyTickets.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export function getMyTickets(baseUrl, jwt, testId) {
4545
"status 200": (r) => r.status === 200,
4646
"data exists": () => data !== null,
4747
"data is array": () => Array.isArray(data),
48-
"tickets length ≥ 0": () => data.length >= 0,
48+
"tickets length ≥ 0": () => Array.isArray(data) && data.length >= 0,
4949
});
5050

5151
// 티켓이 있을 경우 첫 번째 티켓 구조 검증

perf/k6-scripts/util/jwt.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ function sign(data, secretBase64) {
99
.replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
1010
}
1111

12+
function generateUUID() {
13+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
14+
const r = Math.random() * 16 | 0;
15+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
16+
return v.toString(16);
17+
});
18+
}
19+
20+
function generateFixedSessionId(userId) {
21+
// userId 기반 고정 sessionId (PerfUserDataInitializer와 동일한 패턴)
22+
return `00000000-0000-0000-0000-${userId.toString().padStart(12, '0')}`;
23+
}
24+
1225
export function generateJWT(payload, secretBase64) {
1326
if (!secretBase64) {
1427
throw new Error("JWT_SECRET is missing: pass it to generateJWT(payload, secret)");
@@ -17,8 +30,29 @@ export function generateJWT(payload, secretBase64) {
1730
const iat = Math.floor(Date.now() / 1000);
1831
const exp = iat + 3600;
1932

33+
// ActiveSession 필드 추가
34+
const userId = payload.id;
35+
const sessionId = generateFixedSessionId(userId);
36+
const tokenVersion = 1;
37+
const role = payload.role || "NORMAL";
38+
const tokenType = "access";
39+
const jti = generateUUID();
40+
41+
const fullPayload = {
42+
id: userId,
43+
nickname: payload.nickname,
44+
email: payload.email,
45+
role: role,
46+
tokenType: tokenType,
47+
jti: jti,
48+
sid: sessionId,
49+
tokenVersion: tokenVersion,
50+
iat: iat,
51+
exp: exp
52+
};
53+
2054
const encodedHeader = encoding.b64encode(JSON.stringify(header), "rawurl");
21-
const encodedPayload = encoding.b64encode(JSON.stringify({ ...payload, iat, exp }), "rawurl");
55+
const encodedPayload = encoding.b64encode(JSON.stringify(fullPayload), "rawurl");
2256
const signature = sign(`${encodedHeader}.${encodedPayload}`, secretBase64);
2357
const token = `${encodedHeader}.${encodedPayload}.${signature}`;
2458

0 commit comments

Comments
 (0)