- Added comprehensive performance tests for critical endpoints: * Health check endpoints (/health, /readyz) - threshold: 10ms * Authentication endpoints (login: 100ms, register: 200ms) * Track endpoints (list: 50ms, get: 30ms, create: 500ms) * Playlist endpoints (list: 50ms, create: 200ms) * User endpoints (list: 50ms, get: 30ms) - Includes both performance tests (measuring response times against thresholds) - Includes benchmarks using Go benchmark framework - All tests tagged with performance build tag - Tests use in-memory SQLite for fast execution
647 lines
20 KiB
Go
647 lines
20 KiB
Go
//go:build performance
|
|
// +build performance
|
|
|
|
package performance
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zaptest"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
|
|
"veza-backend-api/internal/core/auth"
|
|
"veza-backend-api/internal/core/track"
|
|
"veza-backend-api/internal/database"
|
|
"veza-backend-api/internal/handlers"
|
|
"veza-backend-api/internal/models"
|
|
"veza-backend-api/internal/repositories"
|
|
"veza-backend-api/internal/services"
|
|
"veza-backend-api/internal/validators"
|
|
)
|
|
|
|
// PerformanceThresholds définit les seuils de performance acceptables
|
|
var PerformanceThresholds = struct {
|
|
HealthCheck time.Duration // Health check should be very fast
|
|
AuthLogin time.Duration // Authentication should be fast
|
|
AuthRegister time.Duration // Registration can be slightly slower
|
|
TrackList time.Duration // List operations should be fast
|
|
TrackGet time.Duration // Get single item should be fast
|
|
TrackCreate time.Duration // Create operations can be slower
|
|
PlaylistList time.Duration // List operations should be fast
|
|
PlaylistCreate time.Duration // Create operations can be slower
|
|
UserList time.Duration // List operations should be fast
|
|
UserGet time.Duration // Get single item should be fast
|
|
}{
|
|
HealthCheck: 10 * time.Millisecond,
|
|
AuthLogin: 100 * time.Millisecond,
|
|
AuthRegister: 200 * time.Millisecond,
|
|
TrackList: 50 * time.Millisecond,
|
|
TrackGet: 30 * time.Millisecond,
|
|
TrackCreate: 500 * time.Millisecond,
|
|
PlaylistList: 50 * time.Millisecond,
|
|
PlaylistCreate: 200 * time.Millisecond,
|
|
UserList: 50 * time.Millisecond,
|
|
UserGet: 30 * time.Millisecond,
|
|
}
|
|
|
|
// setupPerformanceTestRouter crée un router de test pour les tests de performance
|
|
func setupPerformanceTestRouter(t *testing.T) (*gin.Engine, *gorm.DB, func()) {
|
|
gin.SetMode(gin.TestMode)
|
|
logger := zaptest.NewLogger(t)
|
|
|
|
// Setup in-memory SQLite database
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
db.Exec("PRAGMA foreign_keys = ON")
|
|
|
|
// Auto-migrate models
|
|
err = db.AutoMigrate(
|
|
&models.User{},
|
|
&models.Track{},
|
|
&models.Playlist{},
|
|
&models.PlaylistTrack{},
|
|
&models.RefreshToken{},
|
|
&models.Session{},
|
|
&models.Role{},
|
|
&models.UserRole{},
|
|
&models.Permission{},
|
|
)
|
|
require.NoError(t, err)
|
|
|
|
dbWrapper := &database.Database{GormDB: db}
|
|
|
|
// Setup services
|
|
emailValidator := validators.NewEmailValidator(db)
|
|
passwordValidator := validators.NewPasswordValidator()
|
|
passwordService := services.NewPasswordService(dbWrapper, logger)
|
|
jwtService, err := services.NewJWTService("test-secret-key-must-be-32-chars-long", "test-issuer", "test-audience")
|
|
require.NoError(t, err)
|
|
refreshTokenService := services.NewRefreshTokenService(db)
|
|
emailVerificationService := services.NewEmailVerificationService(dbWrapper, logger)
|
|
passwordResetService := services.NewPasswordResetService(dbWrapper, logger)
|
|
emailService := services.NewEmailService(dbWrapper, logger)
|
|
|
|
authService := auth.NewAuthService(
|
|
db, emailValidator, passwordValidator, passwordService, jwtService,
|
|
refreshTokenService, emailVerificationService, passwordResetService,
|
|
emailService, nil, logger,
|
|
)
|
|
|
|
// Setup track services
|
|
uploadDir := t.TempDir()
|
|
trackService := track.NewTrackService(db, logger, uploadDir)
|
|
trackUploadService := services.NewTrackUploadService(db, logger)
|
|
likeService := services.NewTrackLikeService(db, logger)
|
|
streamService := services.NewStreamService("http://localhost:8082", logger)
|
|
trackHandler := track.NewTrackHandler(trackService, trackUploadService, nil, likeService, streamService)
|
|
|
|
// Setup playlist services
|
|
playlistRepo := repositories.NewPlaylistRepository(db)
|
|
playlistTrackRepo := repositories.NewPlaylistTrackRepository(db)
|
|
playlistCollaboratorRepo := repositories.NewPlaylistCollaboratorRepository(db)
|
|
userRepo := repositories.NewGormUserRepository(db)
|
|
playlistService := services.NewPlaylistService(playlistRepo, playlistTrackRepo, playlistCollaboratorRepo, userRepo, logger)
|
|
playlistHandler := handlers.NewPlaylistHandler(playlistService, db, logger)
|
|
|
|
// Setup user services
|
|
userService := services.NewUserServiceWithDB(userRepo, db)
|
|
profileHandler := handlers.NewProfileHandler(userService, logger)
|
|
|
|
// Create router
|
|
router := gin.New()
|
|
|
|
// Health check endpoint
|
|
router.GET("/health", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
|
})
|
|
|
|
router.GET("/readyz", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"status": "ready"})
|
|
})
|
|
|
|
// Auth routes
|
|
authGroup := router.Group("/api/v1/auth")
|
|
{
|
|
authGroup.POST("/login", handlers.Login(authService, services.NewSessionService(dbWrapper, logger), services.NewTwoFactorService(dbWrapper, logger), logger))
|
|
authGroup.POST("/register", handlers.Register(authService, logger))
|
|
}
|
|
|
|
// Track routes
|
|
tracksGroup := router.Group("/api/v1/tracks")
|
|
{
|
|
tracksGroup.GET("", trackHandler.ListTracks)
|
|
tracksGroup.GET("/:id", trackHandler.GetTrack)
|
|
tracksGroup.POST("", func(c *gin.Context) {
|
|
// Mock upload for performance testing
|
|
c.JSON(http.StatusCreated, gin.H{"id": uuid.New().String()})
|
|
})
|
|
}
|
|
|
|
// Playlist routes
|
|
playlistsGroup := router.Group("/api/v1/playlists")
|
|
{
|
|
playlistsGroup.GET("", playlistHandler.GetPlaylists)
|
|
playlistsGroup.POST("", func(c *gin.Context) {
|
|
// Mock create for performance testing
|
|
c.JSON(http.StatusCreated, gin.H{"id": uuid.New().String()})
|
|
})
|
|
}
|
|
|
|
// User routes
|
|
usersGroup := router.Group("/api/v1/users")
|
|
{
|
|
usersGroup.GET("", profileHandler.ListUsers)
|
|
usersGroup.GET("/:id", profileHandler.GetProfile)
|
|
}
|
|
|
|
cleanup := func() {
|
|
// Cleanup handled by t.TempDir()
|
|
}
|
|
|
|
return router, db, cleanup
|
|
}
|
|
|
|
// measureResponseTime mesure le temps de réponse d'une requête HTTP
|
|
func measureResponseTime(router *gin.Engine, method, path string, body []byte, headers map[string]string) time.Duration {
|
|
req := httptest.NewRequest(method, path, bytes.NewBuffer(body))
|
|
for k, v := range headers {
|
|
req.Header.Set(k, v)
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
start := time.Now()
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
duration := time.Since(start)
|
|
|
|
return duration
|
|
}
|
|
|
|
// TestPerformance_HealthCheck teste les performances de l'endpoint health check
|
|
func TestPerformance_HealthCheck(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, _, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Run multiple requests to get average
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", "/health", nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Health check average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.HealthCheck)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.HealthCheck,
|
|
"Health check should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_ReadinessCheck teste les performances de l'endpoint readiness check
|
|
func TestPerformance_ReadinessCheck(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, _, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", "/readyz", nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Readiness check average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.HealthCheck)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.HealthCheck,
|
|
"Readiness check should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_AuthLogin teste les performances de l'endpoint de login
|
|
func TestPerformance_AuthLogin(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, db, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Create test user
|
|
userID := uuid.New()
|
|
user := &models.User{
|
|
ID: userID,
|
|
Email: "test@example.com",
|
|
Username: "testuser",
|
|
PasswordHash: "$2a$10$abcdefghijklmnopqrstuvwxyz1234567890", // Mock hashed password
|
|
IsVerified: true,
|
|
}
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
loginReq := map[string]interface{}{
|
|
"email": "test@example.com",
|
|
"password": "password123",
|
|
}
|
|
loginBody, _ := json.Marshal(loginReq)
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 50
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "POST", "/api/v1/auth/login", loginBody, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Auth login average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.AuthLogin)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.AuthLogin,
|
|
"Auth login should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_AuthRegister teste les performances de l'endpoint d'inscription
|
|
func TestPerformance_AuthRegister(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, _, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
registerReq := map[string]interface{}{
|
|
"email": fmt.Sprintf("test%d@example.com", time.Now().UnixNano()),
|
|
"username": fmt.Sprintf("testuser%d", time.Now().UnixNano()),
|
|
"password": "SecurePassword123!",
|
|
"password_confirm": "SecurePassword123!",
|
|
}
|
|
registerBody, _ := json.Marshal(registerReq)
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 20
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
// Use unique email for each iteration
|
|
registerReq["email"] = fmt.Sprintf("test%d@example.com", time.Now().UnixNano()+int64(i))
|
|
registerReq["username"] = fmt.Sprintf("testuser%d", time.Now().UnixNano()+int64(i))
|
|
registerBody, _ = json.Marshal(registerReq)
|
|
|
|
duration := measureResponseTime(router, "POST", "/api/v1/auth/register", registerBody, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Auth register average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.AuthRegister)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.AuthRegister,
|
|
"Auth register should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_TrackList teste les performances de l'endpoint de liste de tracks
|
|
func TestPerformance_TrackList(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, db, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Create test tracks
|
|
userID := uuid.New()
|
|
for i := 0; i < 10; i++ {
|
|
track := &models.Track{
|
|
ID: uuid.New(),
|
|
UserID: userID,
|
|
Title: fmt.Sprintf("Test Track %d", i),
|
|
}
|
|
db.Create(track)
|
|
}
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", "/api/v1/tracks", nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Track list average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.TrackList)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.TrackList,
|
|
"Track list should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_TrackGet teste les performances de l'endpoint de récupération d'un track
|
|
func TestPerformance_TrackGet(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, db, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Create test track
|
|
userID := uuid.New()
|
|
trackID := uuid.New()
|
|
track := &models.Track{
|
|
ID: trackID,
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
}
|
|
err := db.Create(track).Error
|
|
require.NoError(t, err)
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", fmt.Sprintf("/api/v1/tracks/%s", trackID), nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Track get average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.TrackGet)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.TrackGet,
|
|
"Track get should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_TrackCreate teste les performances de l'endpoint de création de track
|
|
func TestPerformance_TrackCreate(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, _, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
createReq := map[string]interface{}{
|
|
"title": "Test Track",
|
|
}
|
|
createBody, _ := json.Marshal(createReq)
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 50
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "POST", "/api/v1/tracks", createBody, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Track create average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.TrackCreate)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.TrackCreate,
|
|
"Track create should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_PlaylistList teste les performances de l'endpoint de liste de playlists
|
|
func TestPerformance_PlaylistList(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, db, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Create test playlists
|
|
userID := uuid.New()
|
|
for i := 0; i < 10; i++ {
|
|
playlist := &models.Playlist{
|
|
ID: uuid.New(),
|
|
UserID: userID,
|
|
Title: fmt.Sprintf("Test Playlist %d", i),
|
|
}
|
|
db.Create(playlist)
|
|
}
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", "/api/v1/playlists", nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Playlist list average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.PlaylistList)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.PlaylistList,
|
|
"Playlist list should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_PlaylistCreate teste les performances de l'endpoint de création de playlist
|
|
func TestPerformance_PlaylistCreate(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, _, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
createReq := map[string]interface{}{
|
|
"name": "Test Playlist",
|
|
}
|
|
createBody, _ := json.Marshal(createReq)
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 50
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "POST", "/api/v1/playlists", createBody, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("Playlist create average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.PlaylistCreate)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.PlaylistCreate,
|
|
"Playlist create should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_UserList teste les performances de l'endpoint de liste d'utilisateurs
|
|
func TestPerformance_UserList(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, db, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Create test users
|
|
for i := 0; i < 10; i++ {
|
|
user := &models.User{
|
|
ID: uuid.New(),
|
|
Email: fmt.Sprintf("user%d@example.com", i),
|
|
Username: fmt.Sprintf("user%d", i),
|
|
IsVerified: true,
|
|
}
|
|
db.Create(user)
|
|
}
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", "/api/v1/users", nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("User list average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.UserList)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.UserList,
|
|
"User list should respond within threshold")
|
|
}
|
|
|
|
// TestPerformance_UserGet teste les performances de l'endpoint de récupération d'un utilisateur
|
|
func TestPerformance_UserGet(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping performance test in short mode")
|
|
}
|
|
|
|
router, db, cleanup := setupPerformanceTestRouter(t)
|
|
defer cleanup()
|
|
|
|
// Create test user
|
|
userID := uuid.New()
|
|
user := &models.User{
|
|
ID: userID,
|
|
Email: "test@example.com",
|
|
Username: "testuser",
|
|
IsVerified: true,
|
|
}
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
var totalDuration time.Duration
|
|
iterations := 100
|
|
|
|
for i := 0; i < iterations; i++ {
|
|
duration := measureResponseTime(router, "GET", fmt.Sprintf("/api/v1/users/%s", userID), nil, nil)
|
|
totalDuration += duration
|
|
}
|
|
|
|
avgDuration := totalDuration / time.Duration(iterations)
|
|
t.Logf("User get average response time: %v (threshold: %v)", avgDuration, PerformanceThresholds.UserGet)
|
|
|
|
assert.Less(t, avgDuration, PerformanceThresholds.UserGet,
|
|
"User get should respond within threshold")
|
|
}
|
|
|
|
// BenchmarkHealthCheck benchmark pour l'endpoint health check
|
|
func BenchmarkHealthCheck(b *testing.B) {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.GET("/health", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
|
})
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
req := httptest.NewRequest("GET", "/health", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
}
|
|
}
|
|
|
|
// BenchmarkTrackList benchmark pour l'endpoint de liste de tracks
|
|
func BenchmarkTrackList(b *testing.B) {
|
|
gin.SetMode(gin.TestMode)
|
|
logger := zap.NewNop()
|
|
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
if err != nil {
|
|
b.Fatalf("Failed to open database: %v", err)
|
|
}
|
|
db.AutoMigrate(&models.Track{})
|
|
|
|
// Create test tracks
|
|
userID := uuid.New()
|
|
for i := 0; i < 100; i++ {
|
|
track := &models.Track{
|
|
ID: uuid.New(),
|
|
UserID: userID,
|
|
Title: fmt.Sprintf("Test Track %d", i),
|
|
}
|
|
db.Create(track)
|
|
}
|
|
|
|
uploadDir := b.TempDir()
|
|
trackService := track.NewTrackService(db, logger, uploadDir)
|
|
trackUploadService := services.NewTrackUploadService(db, logger)
|
|
likeService := services.NewTrackLikeService(db, logger)
|
|
streamService := services.NewStreamService("http://localhost:8082", logger)
|
|
trackHandler := track.NewTrackHandler(trackService, trackUploadService, nil, likeService, streamService)
|
|
|
|
router := gin.New()
|
|
router.GET("/api/v1/tracks", trackHandler.ListTracks)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
req := httptest.NewRequest("GET", "/api/v1/tracks", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
}
|
|
}
|
|
|
|
// BenchmarkTrackGet benchmark pour l'endpoint de récupération d'un track
|
|
func BenchmarkTrackGet(b *testing.B) {
|
|
gin.SetMode(gin.TestMode)
|
|
logger := zap.NewNop()
|
|
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
if err != nil {
|
|
b.Fatalf("Failed to open database: %v", err)
|
|
}
|
|
db.AutoMigrate(&models.Track{})
|
|
|
|
// Create test track
|
|
userID := uuid.New()
|
|
trackID := uuid.New()
|
|
testTrack := &models.Track{
|
|
ID: trackID,
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
}
|
|
db.Create(testTrack)
|
|
|
|
uploadDir := b.TempDir()
|
|
trackService := track.NewTrackService(db, logger, uploadDir)
|
|
trackUploadService := services.NewTrackUploadService(db, logger)
|
|
likeService := services.NewTrackLikeService(db, logger)
|
|
streamService := services.NewStreamService("http://localhost:8082", logger)
|
|
trackHandler := track.NewTrackHandler(trackService, trackUploadService, nil, likeService, streamService)
|
|
|
|
router := gin.New()
|
|
router.GET("/api/v1/tracks/:id", trackHandler.GetTrack)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
req := httptest.NewRequest("GET", fmt.Sprintf("/api/v1/tracks/%s", trackID), nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
}
|
|
}
|
|
|