test(infrastructure): Configure pgxpool with max_conns=1
Fix database connection exhaustion in tests by setting max_conns=1 when creating pgxpool via pgxpool.ParseConfig(). - Update setupTestServer() in test_helpers.go - Update setupSyncTestDB() in sync_integration_test.go This reduces per-test connection usage from 4 to 1, keeping total connections well under PostgreSQL's default max_connections=100. 78 tests × 1 connection = 78 connections (down from 312 potential) Fixes test failures: "FATAL: sorry, too many clients already" See PROJECT_GUIDELINES.md Testing section for details.
This commit is contained in:
@@ -11,13 +11,14 @@ import (
|
||||
|
||||
// TestOPDSEndpoints tests OPDS (Open Publication Distribution System) endpoints
|
||||
func TestOPDSEndpoints(t *testing.T) {
|
||||
t.Run("GetDeviceCatalog_WithoutDeviceAuth", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
setup := setupTestServer(t)
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
client := &http.Client{}
|
||||
|
||||
t.Run("GetDeviceCatalog_WithoutDeviceAuth", func(t *testing.T) {
|
||||
deviceID := uuid.New()
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -28,11 +29,8 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetDeviceCatalog_InvalidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/catalog", nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -42,17 +40,11 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetDeviceCatalog_ValidDevice", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
|
||||
// Note: Device registration requires different endpoint
|
||||
// For now, test with a valid UUID format
|
||||
deviceID := uuid.New()
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -62,11 +54,8 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("SearchDeviceCatalog_InvalidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/search?query=test", nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -75,15 +64,11 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("SearchDeviceCatalog_ValidDevice", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/search?query=test", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -93,11 +78,8 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetDeviceNavigation_InvalidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/nav", nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -106,15 +88,11 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetDeviceNavigation_ValidDevice", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/nav", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -124,12 +102,8 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("DownloadBook_InvalidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/download/"+uuid.New().String(), nil)
|
||||
|
||||
bookID := uuid.New()
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/download/"+bookID.String(), nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -138,12 +112,9 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("DownloadBook_InvalidBookID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
deviceID := uuid.New()
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/invalid-uuid", nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -152,16 +123,12 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("DownloadBook_ValidIDs", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
bookID := createTestMediaItemID(t, setup.Server, token)
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID, nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -172,12 +139,8 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetCoverImage_InvalidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/cover/"+uuid.New().String(), nil)
|
||||
|
||||
bookID := uuid.New()
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/cover/"+bookID.String(), nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -186,12 +149,8 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetCoverImage_InvalidBookID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/cover/"+uuid.New().String(), nil)
|
||||
|
||||
deviceID := uuid.New()
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/cover/invalid-uuid", nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -200,16 +159,12 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("GetCoverImage_ValidIDs", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
bookID := createTestMediaItemID(t, setup.Server, token)
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/cover/"+bookID, nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -219,12 +174,9 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("ListFormats_InvalidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
bookID := uuid.New()
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/formats/"+bookID.String(), nil)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -233,16 +185,12 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("ListFormats_ValidDeviceID", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
bookID := createTestMediaItemID(t, setup.Server, token)
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/formats/"+bookID, nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -254,10 +202,11 @@ func TestOPDSEndpoints(t *testing.T) {
|
||||
|
||||
// TestOPDSConversion tests on-the-fly conversion for downloads
|
||||
func TestOPDSConversion(t *testing.T) {
|
||||
t.Run("DownloadKEPUB_FormatParameter", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
setup := setupTestServer(t)
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
client := &http.Client{}
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
t.Run("DownloadKEPUB_FormatParameter", func(t *testing.T) {
|
||||
deviceID := uuid.New()
|
||||
bookID := createTestMediaItemID(t, setup.Server, token)
|
||||
|
||||
@@ -265,7 +214,6 @@ func TestOPDSConversion(t *testing.T) {
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID+"?format=kepub", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -276,9 +224,6 @@ func TestOPDSConversion(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("DownloadEPUB_DefaultFormat", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
bookID := createTestMediaItemID(t, setup.Server, token)
|
||||
|
||||
@@ -286,7 +231,6 @@ func TestOPDSConversion(t *testing.T) {
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID, nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -296,9 +240,6 @@ func TestOPDSConversion(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Download_UnsupportedFormat", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
bookID := createTestMediaItemID(t, setup.Server, token)
|
||||
|
||||
@@ -306,7 +247,6 @@ func TestOPDSConversion(t *testing.T) {
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID+"?format=pdf", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -318,16 +258,16 @@ func TestOPDSConversion(t *testing.T) {
|
||||
|
||||
// TestOPDSEdgeCases tests edge cases for OPDS endpoints
|
||||
func TestOPDSEdgeCases(t *testing.T) {
|
||||
t.Run("Catalog_EmptyLibrary", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
setup := setupTestServer(t)
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
client := &http.Client{}
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
t.Run("Catalog_EmptyLibrary", func(t *testing.T) {
|
||||
deviceID := uuid.New()
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -337,16 +277,12 @@ func TestOPDSEdgeCases(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Search_SpecialCharacters", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
|
||||
// Search with special characters
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/search?query=test%20%26%20more", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
@@ -356,15 +292,11 @@ func TestOPDSEdgeCases(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Search_EmptyQuery", func(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := loginTestUser(t, setup.Server, setup.DB)
|
||||
deviceID := uuid.New()
|
||||
|
||||
httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/search?query=", nil)
|
||||
httpReq.Header.Set("Authorization", "Bearer "+token)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(httpReq)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
Reference in New Issue
Block a user