feat: k6 테스트에서 setup에 사용할 테스트용 API 추가

This commit is contained in:
이상진 2025-10-10 17:35:34 +09:00
parent 5c89cd6a46
commit 9d178c764c
5 changed files with 204 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package com.sangdol.roomescape.schedule.infrastructure.persistence
import com.sangdol.roomescape.schedule.business.domain.ScheduleOverview
import com.sangdol.roomescape.test.ScheduleWithThemeId
import jakarta.persistence.LockModeType
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Lock
@ -159,4 +160,18 @@ interface ScheduleRepository : JpaRepository<ScheduleEntity, Long> {
"""
)
fun releaseHeldSchedules(@Param("scheduleIds") scheduleIds: List<Long>): Int
/**
* for test
*/
@Query("""
SELECT
s.id, s.theme_id
FROM
schedule s
WHERE
s.status = 'AVAILABLE'
AND s.date > CURRENT_DATE
""", nativeQuery = true)
fun findAllAvailableSchedules(): List<ScheduleWithThemeId>
}

View File

@ -0,0 +1,45 @@
package com.sangdol.roomescape.test
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/tests")
class TestSetupController(
private val testSetupService: TestSetupService
) {
@GetMapping("/themes")
fun findAllThemeWithTimes(): ThemeWithTimesList {
return testSetupService.findAllThemeWithTimes()
}
@GetMapping("/max-iterations")
fun maxIterations(): MaxIterations {
return testSetupService.calculateMaxIterations()
}
@GetMapping("/admin/accounts")
fun findAllStoreAdminAccounts(): AccountList {
return testSetupService.findAllStoreAdminAccounts()
}
@GetMapping("/schedules/available")
fun findAllAvailableSchedules(): ScheduleWithThemeIdList {
return testSetupService.findAllAvailableSchedule()
}
@GetMapping("/users")
fun findAllUsers(
@RequestParam("count") count: Long
): AccountList {
return testSetupService.findAllUserAccounts(count)
}
@GetMapping("/stores")
fun findAllStoreIds(): StoreIdList {
return testSetupService.findAllStores()
}
}

View File

@ -0,0 +1,47 @@
package com.sangdol.roomescape.test
import java.time.LocalTime
data class ThemeWithTimesList(
val results: List<ThemeWithTimes>
)
data class ThemeWithTimes(
val id: Long,
val times: List<ScheduleTime>
)
data class ScheduleTime(
val startFrom: LocalTime,
val endAt: LocalTime
)
data class AccountList(
val results: List<Account>
)
data class Account(
val account: String,
val password: String
)
data class ScheduleWithThemeIdList(
val results: List<ScheduleWithThemeId>
)
data class ScheduleWithThemeId(
val scheduleId: Long,
val themeId: Long
)
data class MaxIterations(
val count: Long
)
data class StoreIdList(
val results: List<StoreId>
)
data class StoreId(
val storeId: Long
)

View File

@ -0,0 +1,88 @@
package com.sangdol.roomescape.test
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminRepository
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType
import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleRepository
import com.sangdol.roomescape.store.infrastructure.persistence.StoreRepository
import com.sangdol.roomescape.theme.infrastructure.persistence.ThemeRepository
import com.sangdol.roomescape.user.infrastructure.persistence.UserRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalTime
@Service
class TestSetupService(
private val themeRepository: ThemeRepository,
private val storeRepository: StoreRepository,
private val adminRepository: AdminRepository,
private val userRepository: UserRepository,
private val scheduleRepository: ScheduleRepository,
) {
@Transactional(readOnly = true)
fun findAllThemeWithTimes(): ThemeWithTimesList {
val storeOpenTime = LocalTime.of(10, 0)
val storeCloseTime = LocalTime.of(22, 0)
val timeGapMinutes = 10L
return ThemeWithTimesList(themeRepository.findAll()
.filter { it.isActive }
.map { theme ->
val times: MutableList<ScheduleTime> = mutableListOf()
var startTime: LocalTime = storeOpenTime
while (startTime.isBefore(storeCloseTime)) {
val themeAvailableMinute = theme.availableMinutes.toLong()
val endTime: LocalTime = startTime.plusMinutes(themeAvailableMinute)
if (endTime.isAfter(storeCloseTime)) {
break
}
times.add(ScheduleTime(startTime, endTime))
startTime = endTime.plusMinutes(timeGapMinutes)
}
ThemeWithTimes(theme.id, times)
}
)
}
@Transactional(readOnly = true)
fun calculateMaxIterations(): MaxIterations {
val max = findAllThemeWithTimes().results.sumOf { it.times.size }
val stores = storeRepository.findAll().size
val days = 6
return MaxIterations((max * stores * days).toLong())
}
@Transactional(readOnly = true)
fun findAllStoreAdminAccounts(): AccountList {
return AccountList(adminRepository.findAll()
.filter { it.permissionLevel == AdminPermissionLevel.FULL_ACCESS }
.filter { it.type == AdminType.STORE }
.map { Account(it.account, it.password) }
)
}
@Transactional(readOnly = true)
fun findAllUserAccounts(count: Long): AccountList {
return AccountList(userRepository.findUsersByCount(count)
.map { Account(it.email, it.password) }
)
}
@Transactional(readOnly = true)
fun findAllAvailableSchedule(): ScheduleWithThemeIdList {
return ScheduleWithThemeIdList(scheduleRepository.findAllAvailableSchedules())
}
@Transactional(readOnly = true)
fun findAllStores(): StoreIdList {
return StoreIdList(storeRepository.findAll().map {
StoreId(it.id)
})
}
}

View File

@ -1,12 +1,21 @@
package com.sangdol.roomescape.user.infrastructure.persistence
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
interface UserRepository : JpaRepository<UserEntity, Long> {
fun existsByEmail(email: String): Boolean
fun existsByPhone(phone: String): Boolean
fun findByEmail(email: String): UserEntity?
/**
* for test
*/
@Query("""
SELECT * FROM users u LIMIT :count
""", nativeQuery = true)
fun findUsersByCount(count: Long): List<UserEntity>
}
interface UserStatusHistoryRepository : JpaRepository<UserStatusHistoryEntity, Long>